diff options
Diffstat (limited to 'src')
314 files changed, 42927 insertions, 22421 deletions
diff --git a/src/admin/fwd.hpp b/src/admin/fwd.hpp new file mode 100644 index 0000000..46674c8 --- /dev/null +++ b/src/admin/fwd.hpp @@ -0,0 +1,27 @@ +#pragma once +// admin/fwd.hpp - list of type names for admin client +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +// meh, add more when I feel like it +} // namespace tmwa diff --git a/src/admin/ladmin.cpp b/src/admin/ladmin.cpp index 9bbd710..9dae089 100644 --- a/src/admin/ladmin.cpp +++ b/src/admin/ladmin.cpp @@ -1,4 +1,4 @@ -#include <arpa/inet.h> +#include "ladmin.hpp" // ladmin.cpp - Local administration tool. // // Copyright © ????-2004 Athena Dev Teams @@ -26,30 +26,37 @@ #include <cassert> +#include <algorithm> + #include "../strings/mstring.hpp" #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" #include "../strings/vstring.hpp" -#include "../generic/md5.hpp" - #include "../io/cxxstdio.hpp" #include "../io/read.hpp" #include "../io/tty.hpp" #include "../io/write.hpp" +#include "../net/ip.hpp" +#include "../net/packets.hpp" + +#include "../proto2/any-user.hpp" +#include "../proto2/login-admin.hpp" + #include "../mmo/config_parse.hpp" #include "../mmo/core.hpp" #include "../mmo/human_time_diff.hpp" #include "../mmo/mmo.hpp" -#include "../mmo/socket.hpp" #include "../mmo/utils.hpp" #include "../mmo/version.hpp" #include "../poison.hpp" +namespace tmwa +{ static int eathena_interactive_session; #define Iprintf if (eathena_interactive_session) PRINTF @@ -68,9 +75,9 @@ IP4Address login_ip = IP4_LOCALHOST; // IP of login-server static int login_port = 6900; // Port of login-server static -AccountPass admin_pass = stringish<AccountPass>("admin"); // Administration password +AccountPass admin_pass = stringish<AccountPass>("admin"_s); // Administration password static -AString ladmin_log_filename = "log/ladmin.log"; +AString ladmin_log_filename = "log/ladmin.log"_s; //------------------------------------------------------------------------- // LIST of COMMANDs that you can type at the prompt: // To use these commands you can only type only the first letters. @@ -259,17 +266,19 @@ static TString parameters; // needs to be global since it's passed to the parse function // really should be added to session data static -int list_first, list_last, list_type, list_count; // parameter to display a list of accounts +AccountId list_first, list_last; +static +int list_type, list_count; // parameter to display a list of accounts static int already_exit_function = 0; // sometimes, the exit function is called twice... so, don't log twice the message -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmissing-noreturn" +DIAG_PUSH(); +DIAG_I(missing_noreturn); void SessionDeleter::operator()(SessionData *) { - assert(false && "ladmin does not have sessions"); + assert(false && "ladmin does not have sessions"_s); } -#pragma GCC diagnostic pop +DIAG_POP(); //------------------------------ // Writing function of logs file @@ -285,13 +294,14 @@ void ladmin_log(XString line) log_with_timestamp(logfp, line); } -static +static __attribute__((noreturn)) void delete_fromlogin(Session *) { + login_session = nullptr; { - PRINTF("Impossible to have a connection with the login-server [%s:%d] !\n", + PRINTF("Impossible to have a connection with the login-server [%s:%d] !\n"_fmt, login_ip, login_port); - LADMIN_LOG("Impossible to have a connection with the login-server [%s:%d] !\n", + LADMIN_LOG("Impossible to have a connection with the login-server [%s:%d] !\n"_fmt, login_ip, login_port); exit(0); } @@ -352,315 +362,315 @@ void display_help(ZString param) XString command = param.xislice_h(std::find(param.begin(), param.end(), ' ')); if (command.startswith('?')) - command = "help"; + command = "help"_s; - LADMIN_LOG("Displaying of the commands or a command.\n"); + LADMIN_LOG("Displaying of the commands or a command.\n"_fmt); - if (command == "help") + if (command == "help"_s) { - PRINTF("help/?\n"); - PRINTF(" Display the description of the commands\n"); - PRINTF("help/? [command]\n"); - PRINTF(" Display the description of the specified command\n"); + PRINTF("help/?\n"_fmt); + PRINTF(" Display the description of the commands\n"_fmt); + PRINTF("help/? [command]\n"_fmt); + PRINTF(" Display the description of the specified command\n"_fmt); } - else if (command == "add") + else if (command == "add"_s) { - PRINTF("add <account_name> <sex> <password>\n"); - PRINTF(" Create an account with the default email (a@a.com).\n"); - PRINTF(" Concerning the sex, only the first letter is used (F or M).\n"); - PRINTF(" The e-mail is set to a@a.com (default e-mail). It's like to have no e-mail.\n"); - PRINTF(" When the password is omitted,\n"); - PRINTF(" the input is done without displaying of the pressed keys.\n"); - PRINTF(" <example> add testname Male testpass\n"); + PRINTF("add <account_name> <sex> <password>\n"_fmt); + PRINTF(" Create an account with the default email (a@a.com).\n"_fmt); + PRINTF(" Concerning the sex, only the first letter is used (F or M).\n"_fmt); + PRINTF(" The e-mail is set to a@a.com (default e-mail). It's like to have no e-mail.\n"_fmt); + PRINTF(" When the password is omitted,\n"_fmt); + PRINTF(" the input is done without displaying of the pressed keys.\n"_fmt); + PRINTF(" <example> add testname Male testpass\n"_fmt); } - else if (command == "ban") + else if (command == "ban"_s) { - PRINTF("ban yyyy/mm/dd hh:mm:ss <account name>\n"); - PRINTF(" Changes the final date of a banishment of an account.\n"); - PRINTF(" Like banset, but <account name> is at end.\n"); + PRINTF("ban yyyy/mm/dd hh:mm:ss <account name>\n"_fmt); + PRINTF(" Changes the final date of a banishment of an account.\n"_fmt); + PRINTF(" Like banset, but <account name> is at end.\n"_fmt); } - else if (command == "banadd") + else if (command == "banadd"_s) { - PRINTF("banadd <account_name> <modifier>\n"); - PRINTF(" Adds or substracts time from the final date of a banishment of an account.\n"); - PRINTF(" Modifier is done as follows:\n"); - PRINTF(" Adjustment value (-1, 1, +1, etc...)\n"); - PRINTF(" Modified element:\n"); - PRINTF(" a or y: year\n"); - PRINTF(" m: month\n"); - PRINTF(" j or d: day\n"); - PRINTF(" h: hour\n"); - PRINTF(" mn: minute\n"); - PRINTF(" s: second\n"); - PRINTF(" <example> banadd testname +1m-2mn1s-6y\n"); - PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"); - PRINTF(" and 6 years at the same time.\n"); - PRINTF("NOTE: If you modify the final date of a non-banished account,\n"); - PRINTF(" you fix the final date to (actual time +- adjustments)\n"); + PRINTF("banadd <account_name> <modifier>\n"_fmt); + PRINTF(" Adds or substracts time from the final date of a banishment of an account.\n"_fmt); + PRINTF(" Modifier is done as follows:\n"_fmt); + PRINTF(" Adjustment value (-1, 1, +1, etc...)\n"_fmt); + PRINTF(" Modified element:\n"_fmt); + PRINTF(" a or y: year\n"_fmt); + PRINTF(" m: month\n"_fmt); + PRINTF(" j or d: day\n"_fmt); + PRINTF(" h: hour\n"_fmt); + PRINTF(" mn: minute\n"_fmt); + PRINTF(" s: second\n"_fmt); + PRINTF(" <example> banadd testname +1m-2mn1s-6y\n"_fmt); + PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"_fmt); + PRINTF(" and 6 years at the same time.\n"_fmt); + PRINTF("NOTE: If you modify the final date of a non-banished account,\n"_fmt); + PRINTF(" you fix the final date to (actual time +- adjustments)\n"_fmt); } - else if (command == "banset") + else if (command == "banset"_s) { - PRINTF("banset <account_name> yyyy/mm/dd [hh:mm:ss]\n"); - PRINTF(" Changes the final date of a banishment of an account.\n"); - PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"); - PRINTF("banset <account_name> 0\n"); - PRINTF(" Set a non-banished account (0 = unbanished).\n"); + PRINTF("banset <account_name> yyyy/mm/dd [hh:mm:ss]\n"_fmt); + PRINTF(" Changes the final date of a banishment of an account.\n"_fmt); + PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"_fmt); + PRINTF("banset <account_name> 0\n"_fmt); + PRINTF(" Set a non-banished account (0 = unbanished).\n"_fmt); } - else if (command == "block") + else if (command == "block"_s) { - PRINTF("block <account name>\n"); - PRINTF(" Set state 5 (You have been blocked by the GM Team) to an account.\n"); - PRINTF(" This command works like state <account_name> 5.\n"); + PRINTF("block <account name>\n"_fmt); + PRINTF(" Set state 5 (You have been blocked by the GM Team) to an account.\n"_fmt); + PRINTF(" This command works like state <account_name> 5.\n"_fmt); } - else if (command == "check") + else if (command == "check"_s) { - PRINTF("check <account_name> <password>\n"); - PRINTF(" Check the validity of a password for an account.\n"); - PRINTF(" NOTE: Server will never sends back a password.\n"); - PRINTF(" It's the only method you have to know if a password is correct.\n"); - PRINTF(" The other method is to have a ('physical') access to the accounts file.\n"); + PRINTF("check <account_name> <password>\n"_fmt); + PRINTF(" Check the validity of a password for an account.\n"_fmt); + PRINTF(" NOTE: Server will never sends back a password.\n"_fmt); + PRINTF(" It's the only method you have to know if a password is correct.\n"_fmt); + PRINTF(" The other method is to have a ('physical') access to the accounts file.\n"_fmt); } - else if (command == "create") + else if (command == "create"_s) { - PRINTF("create <account_name> <sex> <email> <password>\n"); - PRINTF(" Like the 'add' command, but with e-mail moreover.\n"); - PRINTF(" <example> create testname Male my@mail.com testpass\n"); + PRINTF("create <account_name> <sex> <email> <password>\n"_fmt); + PRINTF(" Like the 'add' command, but with e-mail moreover.\n"_fmt); + PRINTF(" <example> create testname Male my@mail.com testpass\n"_fmt); } - else if (command == "delete") + else if (command == "delete"_s) { - PRINTF("delete <account name>\n"); - PRINTF(" Remove an account.\n"); - PRINTF(" This order requires confirmation. After confirmation, the account is deleted.\n"); + PRINTF("delete <account name>\n"_fmt); + PRINTF(" Remove an account.\n"_fmt); + PRINTF(" This order requires confirmation. After confirmation, the account is deleted.\n"_fmt); } - else if (command == "email") + else if (command == "email"_s) { - PRINTF("email <account_name> <email>\n"); - PRINTF(" Modify the e-mail of an account.\n"); + PRINTF("email <account_name> <email>\n"_fmt); + PRINTF(" Modify the e-mail of an account.\n"_fmt); } - else if (command == "getcount") + else if (command == "getcount"_s) { - PRINTF("getcount\n"); - PRINTF(" Give the number of players online on all char-servers.\n"); + PRINTF("getcount\n"_fmt); + PRINTF(" Give the number of players online on all char-servers.\n"_fmt); } - else if (command == "gm") + else if (command == "gm"_s) { - PRINTF("gm <account_name> [GM_level]\n"); - PRINTF(" Modify the GM level of an account.\n"); - PRINTF(" Default value remove GM level (GM level = 0).\n"); - PRINTF(" <example> gm testname 80\n"); + PRINTF("gm <account_name> [GM_level]\n"_fmt); + PRINTF(" Modify the GM level of an account.\n"_fmt); + PRINTF(" Default value remove GM level (GM level = 0).\n"_fmt); + PRINTF(" <example> gm testname 80\n"_fmt); } - else if (command == "id") + else if (command == "id"_s) { - PRINTF("id <account name>\n"); - PRINTF(" Give the id of an account.\n"); + PRINTF("id <account name>\n"_fmt); + PRINTF(" Give the id of an account.\n"_fmt); } - else if (command == "info") + else if (command == "info"_s) { - PRINTF("info <account_id>\n"); - PRINTF(" Display complete information of an account.\n"); + PRINTF("info <account_id>\n"_fmt); + PRINTF(" Display complete information of an account.\n"_fmt); } - else if (command == "kami") + else if (command == "kami"_s) { - PRINTF("kami <message>\n"); - PRINTF(" Sends a broadcast message on all map-server (in yellow).\n"); + PRINTF("kami <message>\n"_fmt); + PRINTF(" Sends a broadcast message on all map-server (in yellow).\n"_fmt); } - else if (command == "kamib") + else if (command == "kamib"_s) { - PRINTF("kamib <message>\n"); - PRINTF(" Sends a broadcast message on all map-server (in blue).\n"); + PRINTF("kamib <message>\n"_fmt); + PRINTF(" Sends a broadcast message on all map-server (in blue).\n"_fmt); } - else if (command == "list") + else if (command == "list"_s) { - PRINTF("list/ls [start_id [end_id]]\n"); - PRINTF(" Display a list of accounts.\n"); - PRINTF(" 'start_id', 'end_id': indicate end and start identifiers.\n"); - PRINTF(" Research by name is not possible with this command.\n"); - PRINTF(" <example> list 10 9999999\n"); + PRINTF("list/ls [start_id [end_id]]\n"_fmt); + PRINTF(" Display a list of accounts.\n"_fmt); + PRINTF(" 'start_id', 'end_id': indicate end and start identifiers.\n"_fmt); + PRINTF(" Research by name is not possible with this command.\n"_fmt); + PRINTF(" <example> list 10 9999999\n"_fmt); } - else if (command == "itemfrob") + else if (command == "itemfrob"_s) { - PRINTF("itemfrob <source-id> <dest-id>\n"); - PRINTF(" Translates item IDs for all accounts.\n"); - PRINTF(" Any items matching the source item ID will be mapped to the dest-id.\n"); - PRINTF(" <example> itemfrob 500 700\n"); + PRINTF("itemfrob <source-id> <dest-id>\n"_fmt); + PRINTF(" Translates item IDs for all accounts.\n"_fmt); + PRINTF(" Any items matching the source item ID will be mapped to the dest-id.\n"_fmt); + PRINTF(" <example> itemfrob 500 700\n"_fmt); } - else if (command == "listban") + else if (command == "listban"_s) { - PRINTF("listban [start_id [end_id]]\n"); - PRINTF(" Like list/ls, but only for accounts with state or banished.\n"); + PRINTF("listban [start_id [end_id]]\n"_fmt); + PRINTF(" Like list/ls, but only for accounts with state or banished.\n"_fmt); } - else if (command == "listgm") + else if (command == "listgm"_s) { - PRINTF("listgm [start_id [end_id]]\n"); - PRINTF(" Like list/ls, but only for GM accounts.\n"); + PRINTF("listgm [start_id [end_id]]\n"_fmt); + PRINTF(" Like list/ls, but only for GM accounts.\n"_fmt); } - else if (command == "listok") + else if (command == "listok"_s) { - PRINTF("listok [start_id [end_id]]\n"); - PRINTF(" Like list/ls, but only for accounts without state and not banished.\n"); + PRINTF("listok [start_id [end_id]]\n"_fmt); + PRINTF(" Like list/ls, but only for accounts without state and not banished.\n"_fmt); } - else if (command == "memo") + else if (command == "memo"_s) { - PRINTF("memo <account_name> <memo>\n"); - PRINTF(" Modify the memo of an account.\n"); - PRINTF(" 'memo': it can have until 253 characters (with spaces or not).\n"); + PRINTF("memo <account_name> <memo>\n"_fmt); + PRINTF(" Modify the memo of an account.\n"_fmt); + PRINTF(" 'memo': it can have until 253 characters (with spaces or not).\n"_fmt); } - else if (command == "name") + else if (command == "name"_s) { - PRINTF("name <account_id>\n"); - PRINTF(" Give the name of an account.\n"); + PRINTF("name <account_id>\n"_fmt); + PRINTF(" Give the name of an account.\n"_fmt); } - else if (command == "password") + else if (command == "password"_s) { - PRINTF("password <account_name> <new_password>\n"); - PRINTF(" Change the password of an account.\n"); - PRINTF(" When new password is omitted,\n"); - PRINTF(" the input is done without displaying of the pressed keys.\n"); + PRINTF("password <account_name> <new_password>\n"_fmt); + PRINTF(" Change the password of an account.\n"_fmt); + PRINTF(" When new password is omitted,\n"_fmt); + PRINTF(" the input is done without displaying of the pressed keys.\n"_fmt); } - else if (command == "reloadgm") + else if (command == "reloadgm"_s) { - PRINTF("reloadGM\n"); - PRINTF(" Reload GM configuration file\n"); + PRINTF("reloadGM\n"_fmt); + PRINTF(" Reload GM configuration file\n"_fmt); } - else if (command == "search") + else if (command == "search"_s) { - PRINTF("search <expression>\n"); - PRINTF(" Seek accounts.\n"); - PRINTF(" Displays the accounts whose names correspond.\n"); + PRINTF("search <expression>\n"_fmt); + PRINTF(" Seek accounts.\n"_fmt); + PRINTF(" Displays the accounts whose names correspond.\n"_fmt); } - else if (command == "sex") + else if (command == "sex"_s) { - PRINTF("sex <account_name> <sex>\n"); - PRINTF(" Modify the sex of an account.\n"); - PRINTF(" <example> sex testname Male\n"); + PRINTF("sex <account_name> <sex>\n"_fmt); + PRINTF(" Modify the sex of an account.\n"_fmt); + PRINTF(" <example> sex testname Male\n"_fmt); } - else if (command == "state") + else if (command == "state"_s) { - PRINTF("state <account_name> <new_state> <error_message_#7>\n"); - PRINTF(" Change the state of an account.\n"); - PRINTF(" 'new_state': state is the state of the packet 0x006a + 1.\n"); - PRINTF(" The possibilities are:\n"); - PRINTF(" 0 = Account ok\n"); - PRINTF(" 1 = Unregistered ID\n"); - PRINTF(" 2 = Incorrect Password\n"); - PRINTF(" 3 = This ID is expired\n"); - PRINTF(" 4 = Rejected from Server\n"); - PRINTF(" 5 = You have been blocked by the GM Team\n"); - PRINTF(" 6 = Your Game's EXE file is not the latest version\n"); - PRINTF(" 7 = You are Prohibited to log in until...\n"); - PRINTF(" 8 = Server is jammed due to over populated\n"); - PRINTF(" 9 = No MSG\n"); - PRINTF(" 100 = This ID has been totally erased\n"); - PRINTF(" all other values are 'No MSG', then use state 9 please.\n"); - PRINTF(" 'error_message_#7': message of the code error 6\n"); - PRINTF(" = Your are Prohibited to log in until... (packet 0x006a)\n"); + PRINTF("state <account_name> <new_state> <error_message_#7>\n"_fmt); + PRINTF(" Change the state of an account.\n"_fmt); + PRINTF(" 'new_state': state is the state of the packet 0x006a + 1.\n"_fmt); + PRINTF(" The possibilities are:\n"_fmt); + PRINTF(" 0 = Account ok\n"_fmt); + PRINTF(" 1 = Unregistered ID\n"_fmt); + PRINTF(" 2 = Incorrect Password\n"_fmt); + PRINTF(" 3 = This ID is expired\n"_fmt); + PRINTF(" 4 = Rejected from Server\n"_fmt); + PRINTF(" 5 = You have been blocked by the GM Team\n"_fmt); + PRINTF(" 6 = Your Game's EXE file is not the latest version\n"_fmt); + PRINTF(" 7 = You are Prohibited to log in until...\n"_fmt); + PRINTF(" 8 = Server is jammed due to over populated\n"_fmt); + PRINTF(" 9 = No MSG\n"_fmt); + PRINTF(" 100 = This ID has been totally erased\n"_fmt); + PRINTF(" all other values are 'No MSG', then use state 9 please.\n"_fmt); + PRINTF(" 'error_message_#7': message of the code error 6\n"_fmt); + PRINTF(" = Your are Prohibited to log in until... (packet 0x006a)\n"_fmt); } - else if (command == "timeadd") + else if (command == "timeadd"_s) { - PRINTF("timeadd <account_name> <modifier>\n"); - PRINTF(" Adds or substracts time from the validity limit of an account.\n"); - PRINTF(" Modifier is done as follows:\n"); - PRINTF(" Adjustment value (-1, 1, +1, etc...)\n"); - PRINTF(" Modified element:\n"); - PRINTF(" a or y: year\n"); - PRINTF(" m: month\n"); - PRINTF(" j or d: day\n"); - PRINTF(" h: hour\n"); - PRINTF(" mn: minute\n"); - PRINTF(" s: second\n"); - PRINTF(" <example> timeadd testname +1m-2mn1s-6y\n"); - PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"); - PRINTF(" and 6 years at the same time.\n"); - PRINTF("NOTE: You can not modify a unlimited validity limit.\n"); - PRINTF(" If you want modify it, you want probably create a limited validity limit.\n"); - PRINTF(" So, at first, you must set the validity limit to a date/time.\n"); + PRINTF("timeadd <account_name> <modifier>\n"_fmt); + PRINTF(" Adds or substracts time from the validity limit of an account.\n"_fmt); + PRINTF(" Modifier is done as follows:\n"_fmt); + PRINTF(" Adjustment value (-1, 1, +1, etc...)\n"_fmt); + PRINTF(" Modified element:\n"_fmt); + PRINTF(" a or y: year\n"_fmt); + PRINTF(" m: month\n"_fmt); + PRINTF(" j or d: day\n"_fmt); + PRINTF(" h: hour\n"_fmt); + PRINTF(" mn: minute\n"_fmt); + PRINTF(" s: second\n"_fmt); + PRINTF(" <example> timeadd testname +1m-2mn1s-6y\n"_fmt); + PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"_fmt); + PRINTF(" and 6 years at the same time.\n"_fmt); + PRINTF("NOTE: You can not modify a unlimited validity limit.\n"_fmt); + PRINTF(" If you want modify it, you want probably create a limited validity limit.\n"_fmt); + PRINTF(" So, at first, you must set the validity limit to a date/time.\n"_fmt); } - else if (command == "timeadd") + else if (command == "timeadd"_s) { - PRINTF("timeset <account_name> yyyy/mm/dd [hh:mm:ss]\n"); - PRINTF(" Changes the validity limit of an account.\n"); - PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"); - PRINTF("timeset <account_name> 0\n"); - PRINTF(" Gives an unlimited validity limit (0 = unlimited).\n"); + PRINTF("timeset <account_name> yyyy/mm/dd [hh:mm:ss]\n"_fmt); + PRINTF(" Changes the validity limit of an account.\n"_fmt); + PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"_fmt); + PRINTF("timeset <account_name> 0\n"_fmt); + PRINTF(" Gives an unlimited validity limit (0 = unlimited).\n"_fmt); } - else if (command == "unban") + else if (command == "unban"_s) { - PRINTF("unban/unbanish <account name>\n"); - PRINTF(" Remove the banishment of an account.\n"); - PRINTF(" This command works like banset <account_name> 0.\n"); + PRINTF("unban/unbanish <account name>\n"_fmt); + PRINTF(" Remove the banishment of an account.\n"_fmt); + PRINTF(" This command works like banset <account_name> 0.\n"_fmt); } - else if (command == "unblock") + else if (command == "unblock"_s) { - PRINTF("unblock <account name>\n"); - PRINTF(" Set state 0 (Account ok) to an account.\n"); - PRINTF(" This command works like state <account_name> 0.\n"); + PRINTF("unblock <account name>\n"_fmt); + PRINTF(" Set state 0 (Account ok) to an account.\n"_fmt); + PRINTF(" This command works like state <account_name> 0.\n"_fmt); } - else if (command == "version") + else if (command == "version"_s) { - PRINTF("version\n"); - PRINTF(" Display the version of the login-server.\n"); + PRINTF("version\n"_fmt); + PRINTF(" Display the version of the login-server.\n"_fmt); } - else if (command == "who") + else if (command == "who"_s) { - PRINTF("who <account name>\n"); - PRINTF(" Displays complete information of an account.\n"); + PRINTF("who <account name>\n"_fmt); + PRINTF(" Displays complete information of an account.\n"_fmt); } - else if (command == "quit" - || command == "exit" - || command == "end") - { - PRINTF("quit/end/exit\n"); - PRINTF(" End of the program of administration.\n"); + else if (command == "quit"_s + || command == "exit"_s + || command == "end"_s) + { + PRINTF("quit/end/exit\n"_fmt); + PRINTF(" End of the program of administration.\n"_fmt); } else { if (command) - PRINTF("Unknown command [%s] for help. Displaying of all commands.\n", - AString(command)); - PRINTF(" help/? -- Display this help\n"); - PRINTF(" help/? [command] -- Display the help of the command\n"); - PRINTF(" add <account_name> <sex> <password> -- Create an account with default email\n"); - PRINTF(" ban yyyy/mm/dd hh:mm:ss <account name> -- Change final date of a ban\n"); - PRINTF(" banadd <account_name> <modifier> -- Add or substract time from the final\n"); - PRINTF(" example: ba apple +1m-2mn1s-2y date of a banishment of an account\n"); - PRINTF(" banset <account_name> yyyy/mm/dd [hh:mm:ss] -- Change final date of a ban\n"); - PRINTF(" banset <account_name> 0 -- Un-banish an account\n"); - PRINTF(" block <account name> -- Set state 5 (blocked by the GM Team) to an account\n"); - PRINTF(" check <account_name> <password> -- Check the validity of a password\n"); - PRINTF(" create <account_name> <sex> <email> <passwrd> -- Create an account with email\n"); - PRINTF(" delete <account name> -- Remove an account\n"); - PRINTF(" email <account_name> <email> -- Modify an email of an account\n"); - PRINTF(" getcount -- Give the number of players online\n"); - PRINTF(" gm <account_name> [GM_level] -- Modify the GM level of an account\n"); - PRINTF(" id <account name> -- Give the id of an account\n"); - PRINTF(" info <account_id> -- Display all information of an account\n"); - PRINTF(" itemfrob <source-id> <dest-id> -- Map all items from one item ID to another\n"); - PRINTF(" kami <message> -- Sends a broadcast message (in yellow)\n"); - PRINTF(" kamib <message> -- Sends a broadcast message (in blue)\n"); - PRINTF(" list [First_id [Last_id]] -- Display a list of accounts\n"); - PRINTF(" listban [First_id [Last_id] ] -- Display a list of accounts\n"); - PRINTF(" with state or banished\n"); - PRINTF(" listgm [First_id [Last_id]] -- Display a list of GM accounts\n"); - PRINTF(" listok [First_id [Last_id] ] -- Display a list of accounts\n"); - PRINTF(" without state and not banished\n"); - PRINTF(" memo <account_name> <memo> -- Modify the memo of an account\n"); - PRINTF(" name <account_id> -- Give the name of an account\n"); - PRINTF(" password <account_name> <new_password> -- Change the password of an account\n"); - PRINTF(" quit/end/exit -- End of the program of administation\n"); - PRINTF(" reloadGM -- Reload GM configuration file\n"); - PRINTF(" search <expression> -- Seek accounts\n"); - PRINTF(" sex <nomcompte> <sexe> -- Modify the sex of an account\n"); - PRINTF(" state <account_name> <new_state> <error_message_#7> -- Change the state\n"); - PRINTF(" timeadd <account_name> <modifier> -- Add or substract time from the\n"); - PRINTF(" example: ta apple +1m-2mn1s-2y validity limit of an account\n"); - PRINTF(" timeset <account_name> yyyy/mm/dd [hh:mm:ss] -- Change the validify limit\n"); - PRINTF(" timeset <account_name> 0 -- Give a unlimited validity limit\n"); - PRINTF(" unban <account name> -- Remove the banishment of an account\n"); - PRINTF(" unblock <account name> -- Set state 0 (Account ok) to an account\n"); - PRINTF(" version -- Gives the version of the login-server\n"); - PRINTF(" who <account name> -- Display all information of an account\n"); - PRINTF(" who <account name> -- Display all information of an account\n"); - PRINTF(" Note: To use spaces in an account name, type \"<account name>\" (or ').\n"); + PRINTF("Unknown command [%s] for help. Displaying of all commands.\n"_fmt, + AString(command)); + PRINTF(" help/? -- Display this help\n"_fmt); + PRINTF(" help/? [command] -- Display the help of the command\n"_fmt); + PRINTF(" add <account_name> <sex> <password> -- Create an account with default email\n"_fmt); + PRINTF(" ban yyyy/mm/dd hh:mm:ss <account name> -- Change final date of a ban\n"_fmt); + PRINTF(" banadd <account_name> <modifier> -- Add or substract time from the final\n"_fmt); + PRINTF(" example: ba apple +1m-2mn1s-2y date of a banishment of an account\n"_fmt); + PRINTF(" banset <account_name> yyyy/mm/dd [hh:mm:ss] -- Change final date of a ban\n"_fmt); + PRINTF(" banset <account_name> 0 -- Un-banish an account\n"_fmt); + PRINTF(" block <account name> -- Set state 5 (blocked by the GM Team) to an account\n"_fmt); + PRINTF(" check <account_name> <password> -- Check the validity of a password\n"_fmt); + PRINTF(" create <account_name> <sex> <email> <passwrd> -- Create an account with email\n"_fmt); + PRINTF(" delete <account name> -- Remove an account\n"_fmt); + PRINTF(" email <account_name> <email> -- Modify an email of an account\n"_fmt); + PRINTF(" getcount -- Give the number of players online\n"_fmt); + PRINTF(" gm <account_name> [GM_level] -- Modify the GM level of an account\n"_fmt); + PRINTF(" id <account name> -- Give the id of an account\n"_fmt); + PRINTF(" info <account_id> -- Display all information of an account\n"_fmt); + PRINTF(" itemfrob <source-id> <dest-id> -- Map all items from one item ID to another\n"_fmt); + PRINTF(" kami <message> -- Sends a broadcast message (in yellow)\n"_fmt); + PRINTF(" kamib <message> -- Sends a broadcast message (in blue)\n"_fmt); + PRINTF(" list [First_id [Last_id]] -- Display a list of accounts\n"_fmt); + PRINTF(" listban [First_id [Last_id] ] -- Display a list of accounts\n"_fmt); + PRINTF(" with state or banished\n"_fmt); + PRINTF(" listgm [First_id [Last_id]] -- Display a list of GM accounts\n"_fmt); + PRINTF(" listok [First_id [Last_id] ] -- Display a list of accounts\n"_fmt); + PRINTF(" without state and not banished\n"_fmt); + PRINTF(" memo <account_name> <memo> -- Modify the memo of an account\n"_fmt); + PRINTF(" name <account_id> -- Give the name of an account\n"_fmt); + PRINTF(" password <account_name> <new_password> -- Change the password of an account\n"_fmt); + PRINTF(" quit/end/exit -- End of the program of administation\n"_fmt); + PRINTF(" reloadGM -- Reload GM configuration file\n"_fmt); + PRINTF(" search <expression> -- Seek accounts\n"_fmt); + PRINTF(" sex <nomcompte> <sexe> -- Modify the sex of an account\n"_fmt); + PRINTF(" state <account_name> <new_state> <error_message_#7> -- Change the state\n"_fmt); + PRINTF(" timeadd <account_name> <modifier> -- Add or substract time from the\n"_fmt); + PRINTF(" example: ta apple +1m-2mn1s-2y validity limit of an account\n"_fmt); + PRINTF(" timeset <account_name> yyyy/mm/dd [hh:mm:ss] -- Change the validify limit\n"_fmt); + PRINTF(" timeset <account_name> 0 -- Give a unlimited validity limit\n"_fmt); + PRINTF(" unban <account name> -- Remove the banishment of an account\n"_fmt); + PRINTF(" unblock <account name> -- Set state 0 (Account ok) to an account\n"_fmt); + PRINTF(" version -- Gives the version of the login-server\n"_fmt); + PRINTF(" who <account name> -- Display all information of an account\n"_fmt); + PRINTF(" who <account name> -- Display all information of an account\n"_fmt); + PRINTF(" Note: To use spaces in an account name, type \"<account name>\" (or ').\n"_fmt); } } @@ -680,9 +690,9 @@ void addaccount(ZString param, int emailflag) // add command if (!qsplit(param, &name, &sex_, &password)) { - PRINTF("Please input an account name, a sex and a password.\n"); - PRINTF("<example> add testname Male testpass\n"); - LADMIN_LOG("Incomplete parameters to create an account ('add' command).\n"); + PRINTF("Please input an account name, a sex and a password.\n"_fmt); + PRINTF("<example> add testname Male testpass\n"_fmt); + LADMIN_LOG("Incomplete parameters to create an account ('add' command).\n"_fmt); return; } email_ = DEFAULT_EMAIL; @@ -692,9 +702,9 @@ void addaccount(ZString param, int emailflag) // 1: create command if (!qsplit(param, &name, &sex_, &email_, &password)) { - PRINTF("Please input an account name, a sex and a password.\n"); - PRINTF("<example> create testname Male my@mail.com testpass\n"); - LADMIN_LOG("Incomplete parameters to create an account ('create' command).\n"); + PRINTF("Please input an account name, a sex and a password.\n"_fmt); + PRINTF("<example> create testname Male my@mail.com testpass\n"_fmt); + LADMIN_LOG("Incomplete parameters to create an account ('create' command).\n"_fmt); return; } } @@ -702,18 +712,18 @@ void addaccount(ZString param, int emailflag) if (!name.is_print()) return; - if (!XString("MF").contains(sex)) + if (!"MF"_s.contains(sex)) { - PRINTF("Illegal gender [%c]. Please input M or F.\n", sex); - LADMIN_LOG("Illegal gender [%c]. Please input M or F.\n", sex); + PRINTF("Illegal gender [%c]. Please input M or F.\n"_fmt, sex); + LADMIN_LOG("Illegal gender [%c]. Please input M or F.\n"_fmt, sex); return; } if (!e_mail_check(email_)) { - PRINTF("Invalid email [%s]. Please input a valid e-mail.\n", + PRINTF("Invalid email [%s]. Please input a valid e-mail.\n"_fmt, AString(email_)); - LADMIN_LOG("Invalid email [%s]. Please input a valid e-mail.\n", + LADMIN_LOG("Invalid email [%s]. Please input a valid e-mail.\n"_fmt, AString(email_)); return; } @@ -722,14 +732,14 @@ void addaccount(ZString param, int emailflag) if (!password.is_print()) return; - LADMIN_LOG("Request to login-server to create an account.\n"); + LADMIN_LOG("Request to login-server to create an account.\n"_fmt); - WFIFOW(login_session, 0) = 0x7930; - WFIFO_STRING(login_session, 2, name, 24); - WFIFO_STRING(login_session, 26, password, 24); - WFIFOB(login_session, 50) = sex; - WFIFO_STRING(login_session, 51, email, 40); - WFIFOSET(login_session, 91); + Packet_Fixed<0x7930> fixed_30; + fixed_30.account_name = name; + fixed_30.password = password; + fixed_30.sex = sex_from_char(sex); + fixed_30.email = email; + send_fpacket<0x7930, 91>(login_session, fixed_30); bytes_to_read = 1; } @@ -744,11 +754,11 @@ void banaddaccount(ZString param) if (!qsplit(param, &name, &modif)) { - PRINTF("Please input an account name and a modifier.\n"); - PRINTF(" <example>: banadd testname +1m-2mn1s-6y\n"); - PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"); - PRINTF(" and 6 years at the same time.\n"); - LADMIN_LOG("Incomplete parameters to modify the ban date/time of an account ('banadd' command).\n"); + PRINTF("Please input an account name and a modifier.\n"_fmt); + PRINTF(" <example>: banadd testname +1m-2mn1s-6y\n"_fmt); + PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"_fmt); + PRINTF(" and 6 years at the same time.\n"_fmt); + LADMIN_LOG("Incomplete parameters to modify the ban date/time of an account ('banadd' command).\n"_fmt); return; } if (!name.is_print()) @@ -756,28 +766,28 @@ void banaddaccount(ZString param) if (!modif) { - PRINTF("Please give an adjustment with this command:\n"); - PRINTF(" Adjustment value (-1, 1, +1, etc...)\n"); - PRINTF(" Modified element:\n"); - PRINTF(" a or y: year\n"); - PRINTF(" m: month\n"); - PRINTF(" j or d: day\n"); - PRINTF(" h: hour\n"); - PRINTF(" mn: minute\n"); - PRINTF(" s: second\n"); - PRINTF(" <example> banadd testname +1m-2mn1s-6y\n"); - PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"); - PRINTF(" and 6 years at the same time.\n"); - LADMIN_LOG("No adjustment isn't an adjustment ('banadd' command).\n"); + PRINTF("Please give an adjustment with this command:\n"_fmt); + PRINTF(" Adjustment value (-1, 1, +1, etc...)\n"_fmt); + PRINTF(" Modified element:\n"_fmt); + PRINTF(" a or y: year\n"_fmt); + PRINTF(" m: month\n"_fmt); + PRINTF(" j or d: day\n"_fmt); + PRINTF(" h: hour\n"_fmt); + PRINTF(" mn: minute\n"_fmt); + PRINTF(" s: second\n"_fmt); + PRINTF(" <example> banadd testname +1m-2mn1s-6y\n"_fmt); + PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"_fmt); + PRINTF(" and 6 years at the same time.\n"_fmt); + LADMIN_LOG("No adjustment isn't an adjustment ('banadd' command).\n"_fmt); return; } - LADMIN_LOG("Request to login-server to modify a ban date/time.\n"); + LADMIN_LOG("Request to login-server to modify a ban date/time.\n"_fmt); - WFIFOW(login_session, 0) = 0x794c; - WFIFO_STRING(login_session, 2, name, 24); - WFIFO_STRUCT(login_session, 26, modif); - WFIFOSET(login_session, 38); + Packet_Fixed<0x794c> fixed_4c; + fixed_4c.account_name = name; + fixed_4c.ban_add = modif; + send_fpacket<0x794c, 38>(login_session, fixed_4c); bytes_to_read = 1; } @@ -798,19 +808,19 @@ void bansetaccountsub(AccountName name, XString date, XString time_) if (!name.is_print()) return; - if (date != "0" + if (date != "0"_s && ((!extract(date, record<'/'>(&year, &month, &day)) && !extract(date, record<'-'>(&year, &month, &day)) && !extract(date, record<'.'>(&year, &month, &day))) || !extract(time_, record<':'>(&hour, &minute, &second)))) { - PRINTF("Please input a date and a time (format: yyyy/mm/dd hh:mm:ss).\n"); - PRINTF("You can imput 0 instead of if you use 'banset' command.\n"); - LADMIN_LOG("Invalid format for the date/time ('banset' or 'ban' command).\n"); + PRINTF("Please input a date and a time (format: yyyy/mm/dd hh:mm:ss).\n"_fmt); + PRINTF("You can imput 0 instead of if you use 'banset' command.\n"_fmt); + LADMIN_LOG("Invalid format for the date/time ('banset' or 'ban' command).\n"_fmt); return; } - if (date == "0") + if (date == "0"_s) { ban_until_time = TimeT(); } @@ -826,41 +836,41 @@ void bansetaccountsub(AccountName name, XString date, XString time_) } if (month < 1 || month > 12) { - PRINTF("Please give a correct value for the month (from 1 to 12).\n"); - LADMIN_LOG("Invalid month for the date ('banset' or 'ban' command).\n"); + PRINTF("Please give a correct value for the month (from 1 to 12).\n"_fmt); + LADMIN_LOG("Invalid month for the date ('banset' or 'ban' command).\n"_fmt); return; } month = month - 1; if (day < 1 || day > 31) { - PRINTF("Please give a correct value for the day (from 1 to 31).\n"); - LADMIN_LOG("Invalid day for the date ('banset' or 'ban' command).\n"); + PRINTF("Please give a correct value for the day (from 1 to 31).\n"_fmt); + LADMIN_LOG("Invalid day for the date ('banset' or 'ban' command).\n"_fmt); return; } if (((month == 3 || month == 5 || month == 8 || month == 10) && day > 30) || (month == 1 && day > 29)) { - PRINTF("Please give a correct value for a day of this month (%d).\n", - month); - LADMIN_LOG("Invalid day for this month ('banset' or 'ban' command).\n"); + PRINTF("Please give a correct value for a day of this month (%d).\n"_fmt, + month); + LADMIN_LOG("Invalid day for this month ('banset' or 'ban' command).\n"_fmt); return; } if (hour < 0 || hour > 23) { - PRINTF("Please give a correct value for the hour (from 0 to 23).\n"); - LADMIN_LOG("Invalid hour for the time ('banset' or 'ban' command).\n"); + PRINTF("Please give a correct value for the hour (from 0 to 23).\n"_fmt); + LADMIN_LOG("Invalid hour for the time ('banset' or 'ban' command).\n"_fmt); return; } if (minute < 0 || minute > 59) { - PRINTF("Please give a correct value for the minutes (from 0 to 59).\n"); - LADMIN_LOG("Invalid minute for the time ('banset' or 'ban' command).\n"); + PRINTF("Please give a correct value for the minutes (from 0 to 59).\n"_fmt); + LADMIN_LOG("Invalid minute for the time ('banset' or 'ban' command).\n"_fmt); return; } if (second < 0 || second > 59) { - PRINTF("Please give a correct value for the seconds (from 0 to 59).\n"); - LADMIN_LOG("Invalid second for the time ('banset' or 'ban' command).\n"); + PRINTF("Please give a correct value for the seconds (from 0 to 59).\n"_fmt); + LADMIN_LOG("Invalid second for the time ('banset' or 'ban' command).\n"_fmt); return; } tmtime.tm_year = year; @@ -873,20 +883,20 @@ void bansetaccountsub(AccountName name, XString date, XString time_) ban_until_time = tmtime; if (ban_until_time.error()) { - PRINTF("Invalid date.\n"); - PRINTF("Please input a date and a time (format: yyyy/mm/dd hh:mm:ss).\n"); - PRINTF("You can imput 0 instead of if you use 'banset' command.\n"); - LADMIN_LOG("Invalid date. ('banset' or 'ban' command).\n"); + PRINTF("Invalid date.\n"_fmt); + PRINTF("Please input a date and a time (format: yyyy/mm/dd hh:mm:ss).\n"_fmt); + PRINTF("You can imput 0 instead of if you use 'banset' command.\n"_fmt); + LADMIN_LOG("Invalid date. ('banset' or 'ban' command).\n"_fmt); return; } } - LADMIN_LOG("Request to login-server to set a ban.\n"); + LADMIN_LOG("Request to login-server to set a ban.\n"_fmt); - WFIFOW(login_session, 0) = 0x794a; - WFIFO_STRING(login_session, 2, name, 24); - WFIFOL(login_session, 26) = static_cast<time_t>(ban_until_time); - WFIFOSET(login_session, 30); + Packet_Fixed<0x794a> fixed_4a; + fixed_4a.account_name = name; + fixed_4a.ban_until = ban_until_time; + send_fpacket<0x794a, 30>(login_session, fixed_4a); bytes_to_read = 1; } @@ -902,18 +912,18 @@ void banaccount(ZString param) if (!qsplit(param, &date, &time_, &name)) { - PRINTF("Please input an account name, a date and a hour.\n"); - PRINTF("<example>: banset <account_name> yyyy/mm/dd [hh:mm:ss]\n"); - PRINTF(" banset <account_name> 0 (0 = un-banished)\n"); - PRINTF(" ban/banish yyyy/mm/dd hh:mm:ss <account name>\n"); - PRINTF(" unban/unbanish <account name>\n"); - PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"); - LADMIN_LOG("Incomplete parameters to set a ban ('banset' or 'ban' command).\n"); + PRINTF("Please input an account name, a date and a hour.\n"_fmt); + PRINTF("<example>: banset <account_name> yyyy/mm/dd [hh:mm:ss]\n"_fmt); + PRINTF(" banset <account_name> 0 (0 = un-banished)\n"_fmt); + PRINTF(" ban/banish yyyy/mm/dd hh:mm:ss <account name>\n"_fmt); + PRINTF(" unban/unbanish <account name>\n"_fmt); + PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"_fmt); + LADMIN_LOG("Incomplete parameters to set a ban ('banset' or 'ban' command).\n"_fmt); return; } if (!time_) - time_ = "23:59:59"; + time_ = "23:59:59"_s; bansetaccountsub(name, date, time_); } @@ -931,18 +941,18 @@ void bansetaccount(ZString param) if (!qsplit(param, &name, &date, &time_) && !qsplit(param, &name, &date)) { - PRINTF("Please input an account name, a date and a hour.\n"); - PRINTF("<example>: banset <account_name> yyyy/mm/dd [hh:mm:ss]\n"); - PRINTF(" banset <account_name> 0 (0 = un-banished)\n"); - PRINTF(" ban/banish yyyy/mm/dd hh:mm:ss <account name>\n"); - PRINTF(" unban/unbanish <account name>\n"); - PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"); - LADMIN_LOG("Incomplete parameters to set a ban ('banset' or 'ban' command).\n"); + PRINTF("Please input an account name, a date and a hour.\n"_fmt); + PRINTF("<example>: banset <account_name> yyyy/mm/dd [hh:mm:ss]\n"_fmt); + PRINTF(" banset <account_name> 0 (0 = un-banished)\n"_fmt); + PRINTF(" ban/banish yyyy/mm/dd hh:mm:ss <account name>\n"_fmt); + PRINTF(" unban/unbanish <account name>\n"_fmt); + PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"_fmt); + LADMIN_LOG("Incomplete parameters to set a ban ('banset' or 'ban' command).\n"_fmt); return; } if (!time_) - time_ = "23:59:59"; + time_ = "23:59:59"_s; bansetaccountsub(name, date, time_); } @@ -957,17 +967,17 @@ void unbanaccount(ZString param) if (!qsplit(param, &name)) { - PRINTF("Please input an account name.\n"); - PRINTF("<example>: banset <account_name> yyyy/mm/dd [hh:mm:ss]\n"); - PRINTF(" banset <account_name> 0 (0 = un-banished)\n"); - PRINTF(" ban/banish yyyy/mm/dd hh:mm:ss <account name>\n"); - PRINTF(" unban/unbanish <account name>\n"); - PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"); - LADMIN_LOG("Incomplete parameters to set a ban ('unban' command).\n"); + PRINTF("Please input an account name.\n"_fmt); + PRINTF("<example>: banset <account_name> yyyy/mm/dd [hh:mm:ss]\n"_fmt); + PRINTF(" banset <account_name> 0 (0 = un-banished)\n"_fmt); + PRINTF(" ban/banish yyyy/mm/dd hh:mm:ss <account name>\n"_fmt); + PRINTF(" unban/unbanish <account name>\n"_fmt); + PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"_fmt); + LADMIN_LOG("Incomplete parameters to set a ban ('unban' command).\n"_fmt); return; } - bansetaccountsub(name, "0", ""); + bansetaccountsub(name, "0"_s, ""_s); } //--------------------------------------------------------- @@ -982,9 +992,9 @@ void checkaccount(ZString param) if (!qsplit(param, &name, &password)) { - PRINTF("Please input an account name.\n"); - PRINTF("<example> check testname password\n"); - LADMIN_LOG("Incomplete parameters to check the password of an account ('check' command).\n"); + PRINTF("Please input an account name.\n"_fmt); + PRINTF("<example> check testname password\n"_fmt); + LADMIN_LOG("Incomplete parameters to check the password of an account ('check' command).\n"_fmt); return; } @@ -994,12 +1004,12 @@ void checkaccount(ZString param) if (!password.is_print()) return; - LADMIN_LOG("Request to login-server to check a password.\n"); + LADMIN_LOG("Request to login-server to check a password.\n"_fmt); - WFIFOW(login_session, 0) = 0x793a; - WFIFO_STRING(login_session, 2, name, 24); - WFIFO_STRING(login_session, 26, password, 24); - WFIFOSET(login_session, 50); + Packet_Fixed<0x793a> fixed_3a; + fixed_3a.account_name = name; + fixed_3a.password = password; + send_fpacket<0x793a, 50>(login_session, fixed_3a); bytes_to_read = 1; } @@ -1013,9 +1023,9 @@ void delaccount(ZString param) if (!qsplit(param, &name)) { - PRINTF("Please input an account name.\n"); - PRINTF("<example> delete testnametodelete\n"); - LADMIN_LOG("No name given to delete an account ('delete' command).\n"); + PRINTF("Please input an account name.\n"_fmt); + PRINTF("<example> delete testnametodelete\n"_fmt); + LADMIN_LOG("No name given to delete an account ('delete' command).\n"_fmt); return; } @@ -1025,7 +1035,7 @@ void delaccount(ZString param) char confirm; do { - PRINTF(SGR_BOLD SGR_CYAN " ** Are you really sure to DELETE account [%s]? (y/n) > " SGR_RESET, name); + PRINTF(SGR_BOLD SGR_CYAN " ** Are you really sure to DELETE account [%s]? (y/n) > " SGR_RESET ""_fmt, name); fflush(stdout); int seek = getchar(); confirm = seek; @@ -1035,20 +1045,20 @@ void delaccount(ZString param) while (seek != '\n' && seek != EOF) seek = getchar(); } - while (!XString("yn").contains(confirm)); + while (!"yn"_s.contains(confirm)); if (confirm == 'n') { - PRINTF("Deletion canceled.\n"); - LADMIN_LOG("Deletion canceled by user ('delete' command).\n"); + PRINTF("Deletion canceled.\n"_fmt); + LADMIN_LOG("Deletion canceled by user ('delete' command).\n"_fmt); return; } - LADMIN_LOG("Request to login-server to delete an acount.\n"); + LADMIN_LOG("Request to login-server to delete an acount.\n"_fmt); - WFIFOW(login_session, 0) = 0x7932; - WFIFO_STRING(login_session, 2, name, 24); - WFIFOSET(login_session, 26); + Packet_Fixed<0x7932> fixed_32; + fixed_32.account_name = name; + send_fpacket<0x7932, 26>(login_session, fixed_32); bytes_to_read = 1; } @@ -1062,9 +1072,9 @@ void changeemail(ZString param) XString email_; if (!qsplit(param, &name, &email_)) { - PRINTF("Please input an account name and an email.\n"); - PRINTF("<example> email testname newemail\n"); - LADMIN_LOG("Incomplete parameters to change the email of an account ('email' command).\n"); + PRINTF("Please input an account name and an email.\n"_fmt); + PRINTF("<example> email testname newemail\n"_fmt); + LADMIN_LOG("Incomplete parameters to change the email of an account ('email' command).\n"_fmt); return; } @@ -1073,20 +1083,20 @@ void changeemail(ZString param) if (!e_mail_check(email_)) { - PRINTF("Invalid email [%s]. Please input a valid e-mail.\n", + PRINTF("Invalid email [%s]. Please input a valid e-mail.\n"_fmt, AString(email_)); - LADMIN_LOG("Invalid email [%s]. Please input a valid e-mail.\n", + LADMIN_LOG("Invalid email [%s]. Please input a valid e-mail.\n"_fmt, AString(email_)); return; } AccountEmail email = stringish<AccountEmail>(email_); - LADMIN_LOG("Request to login-server to change an email.\n"); + LADMIN_LOG("Request to login-server to change an email.\n"_fmt); - WFIFOW(login_session, 0) = 0x7940; - WFIFO_STRING(login_session, 2, name, 24); - WFIFO_STRING(login_session, 26, email, 40); - WFIFOSET(login_session, 66); + Packet_Fixed<0x7940> fixed_40; + fixed_40.account_name = name; + fixed_40.email = email; + send_fpacket<0x7940, 66>(login_session, fixed_40); bytes_to_read = 1; } @@ -1096,10 +1106,10 @@ void changeemail(ZString param) static void getlogincount(void) { - LADMIN_LOG("Request to login-server to obtain the # of online players.\n"); + LADMIN_LOG("Request to login-server to obtain the # of online players.\n"_fmt); - WFIFOW(login_session, 0) = 0x7938; - WFIFOSET(login_session, 2); + Packet_Fixed<0x7938> fixed_38; + send_fpacket<0x7938, 2>(login_session, fixed_38); bytes_to_read = 1; } @@ -1110,34 +1120,25 @@ static void changegmlevel(ZString param) { AccountName name; - int GM_level = 0; + GmLevel GM_level; if (!qsplit(param, &name, &GM_level)) { - PRINTF("Please input an account name and a GM level.\n"); - PRINTF("<example> gm testname 80\n"); - LADMIN_LOG("Incomplete parameters to change the GM level of an account ('gm' command).\n"); + PRINTF("Please input an account name and a GM level.\n"_fmt); + PRINTF("<example> gm testname 80\n"_fmt); + LADMIN_LOG("Incomplete parameters to change the GM level of an account ('gm' command).\n"_fmt); return; } if (!name.is_print()) return; - if (GM_level < 0 || GM_level > 99) - { - PRINTF("Illegal GM level [%d]. Please input a value from 0 to 99.\n", - GM_level); - LADMIN_LOG("Illegal GM level [%d]. The value can be from 0 to 99.\n", - GM_level); - return; - } - - LADMIN_LOG("Request to login-server to change a GM level.\n"); + LADMIN_LOG("Request to login-server to change a GM level.\n"_fmt); - WFIFOW(login_session, 0) = 0x793e; - WFIFO_STRING(login_session, 2, name, 24); - WFIFOB(login_session, 26) = GM_level; - WFIFOSET(login_session, 27); + Packet_Fixed<0x793e> fixed_3e; + fixed_3e.account_name = name; + fixed_3e.gm_level = GM_level; + send_fpacket<0x793e, 27>(login_session, fixed_3e); bytes_to_read = 1; } @@ -1151,9 +1152,9 @@ void idaccount(ZString param) if (!qsplit(param, &name)) { - PRINTF("Please input an account name.\n"); - PRINTF("<example> id testname\n"); - LADMIN_LOG("No name given to search an account id ('id' command).\n"); + PRINTF("Please input an account name.\n"_fmt); + PRINTF("<example> id testname\n"_fmt); + LADMIN_LOG("No name given to search an account id ('id' command).\n"_fmt); return; } @@ -1162,11 +1163,11 @@ void idaccount(ZString param) return; } - LADMIN_LOG("Request to login-server to know an account id.\n"); + LADMIN_LOG("Request to login-server to know an account id.\n"_fmt); - WFIFOW(login_session, 0) = 0x7944; - WFIFO_STRING(login_session, 2, name, 24); - WFIFOSET(login_session, 26); + Packet_Fixed<0x7944> fixed_44; + fixed_44.account_name = name; + send_fpacket<0x7944, 26>(login_session, fixed_44); bytes_to_read = 1; } @@ -1174,20 +1175,13 @@ void idaccount(ZString param) // Sub-function: Asking to displaying information about an account (by its id) //---------------------------------------------------------------------------- static -void infoaccount(int account_id) +void infoaccount(AccountId account_id) { - if (account_id < 0) - { - PRINTF("Please input a positive value for the id.\n"); - LADMIN_LOG("Negative value was given to found the account.\n"); - return; - } + LADMIN_LOG("Request to login-server to obtain information about an account (by its id).\n"_fmt); - LADMIN_LOG("Request to login-server to obtain information about an account (by its id).\n"); - - WFIFOW(login_session, 0) = 0x7954; - WFIFOL(login_session, 2) = account_id; - WFIFOSET(login_session, 6); + Packet_Fixed<0x7954> fixed_54; + fixed_54.account_id = account_id; + send_fpacket<0x7954, 6>(login_session, fixed_54); bytes_to_read = 1; } @@ -1199,20 +1193,17 @@ void sendbroadcast(ZString message) { if (!message) { - PRINTF("Please input a message.\n"); + PRINTF("Please input a message.\n"_fmt); { - PRINTF("<example> kami a message\n"); + PRINTF("<example> kami a message\n"_fmt); } - LADMIN_LOG("The message is void ('kami' command).\n"); + LADMIN_LOG("The message is void ('kami' command).\n"_fmt); return; } - WFIFOW(login_session, 0) = 0x794e; - WFIFOW(login_session, 2) = 0; - size_t len = message.size() + 1; - WFIFOL(login_session, 4) = len; - WFIFO_STRING(login_session, 8, message, len); - WFIFOSET(login_session, 8 + len); + Packet_Head<0x794e> head_4e; + head_4e.unused = 0; + send_vpacket<0x794e, 8, 1>(login_session, head_4e, message); bytes_to_read = 1; } @@ -1227,8 +1218,8 @@ void listaccount(ZString param, int type) list_type = type; // set default values - list_first = 0; - list_last = 0; + list_first = AccountId(); + list_last = AccountId(); if (list_type == 1) { // if listgm @@ -1250,24 +1241,22 @@ void listaccount(ZString param, int type) { // if list (list_type == 0) extract(param, record<' '>(&list_first, &list_last)); - if (list_first < 0) - list_first = 0; - if (list_last < list_first || list_last < 0) - list_last = 0; + if (list_last < list_first) + list_last = AccountId(); } - LADMIN_LOG("Request to login-server to obtain the list of accounts from %d to %d.\n", - list_first, list_last); + LADMIN_LOG("Request to login-server to obtain the list of accounts from %d to %d.\n"_fmt, + list_first, list_last); - WFIFOW(login_session, 0) = 0x7920; - WFIFOL(login_session, 2) = list_first; - WFIFOL(login_session, 6) = list_last; - WFIFOSET(login_session, 10); + Packet_Fixed<0x7920> fixed_20; + fixed_20.start_account_id = list_first; + fixed_20.end_account_id = list_last; + send_fpacket<0x7920, 10>(login_session, fixed_20); bytes_to_read = 1; // 0123456789 01 01234567890123456789012301234 012345 0123456789012345678901234567 - Iprintf("account_id GM user_name sex count state\n"); - Iprintf("-------------------------------------------------------------------------------\n"); + Iprintf("account_id GM user_name sex count state\n"_fmt); + Iprintf("-------------------------------------------------------------------------------\n"_fmt); list_count = 0; } @@ -1277,18 +1266,18 @@ void listaccount(ZString param, int type) static int itemfrob(ZString param) { - int source_id, dest_id; + ItemNameId source_id, dest_id; if (!extract(param, record<' '>(&source_id, &dest_id))) { - PRINTF("You must provide the source and destination item IDs.\n"); + PRINTF("You must provide the source and destination item IDs.\n"_fmt); return 1; } - WFIFOW(login_session, 0) = 0x7924; - WFIFOL(login_session, 2) = source_id; - WFIFOL(login_session, 6) = dest_id; - WFIFOSET(login_session, 10); + Packet_Fixed<0x7924> fixed_24; + fixed_24.source_item_id = source_id; + fixed_24.dest_item_id = dest_id; + send_fpacket<0x7924, 10>(login_session, fixed_24); bytes_to_read = 1; // all logging is done to the three main servers return 0; @@ -1305,9 +1294,9 @@ void changememo(ZString param) if (!qsplit(param, &name, &memo) && !qsplit(param, &name)) { - PRINTF("Please input an account name and a memo.\n"); - PRINTF("<example> memo testname new memo\n"); - LADMIN_LOG("Incomplete parameters to change the memo of an account ('email' command).\n"); + PRINTF("Please input an account name and a memo.\n"_fmt); + PRINTF("<example> memo testname new memo\n"_fmt); + LADMIN_LOG("Incomplete parameters to change the memo of an account ('email' command).\n"_fmt); return; } @@ -1315,23 +1304,20 @@ void changememo(ZString param) return; size_t len = memo.size(); - size_t len1 = len + 1; if (len > 254) { - PRINTF("Memo is too long (%zu characters).\n", len); - PRINTF("Please input a memo of 254 bytes at the maximum.\n"); - LADMIN_LOG("Email is too long (%zu characters). Please input a memo of 254 bytes at the maximum.\n", - len); + PRINTF("Memo is too long (%zu characters).\n"_fmt, len); + PRINTF("Please input a memo of 254 bytes at the maximum.\n"_fmt); + LADMIN_LOG("Email is too long (%zu characters). Please input a memo of 254 bytes at the maximum.\n"_fmt, + len); return; } - LADMIN_LOG("Request to login-server to change a memo.\n"); + LADMIN_LOG("Request to login-server to change a memo.\n"_fmt); - WFIFOW(login_session, 0) = 0x7942; - WFIFO_STRING(login_session, 2, name, 24); - WFIFOW(login_session, 26) = len1; - WFIFO_STRING(login_session, 28, memo, len); - WFIFOSET(login_session, 28 + len1); + Packet_Head<0x7942> head_42; + head_42.account_name = name; + send_vpacket<0x7942, 28, 1>(login_session, head_42, memo); bytes_to_read = 1; } @@ -1339,20 +1325,13 @@ void changememo(ZString param) // Sub-function: Asking to obtain an account name //----------------------------------------------- static -void nameaccount(int id) +void nameaccount(AccountId id) { - if (id < 0) - { - PRINTF("Please input a positive value for the id.\n"); - LADMIN_LOG("Negativ id given to search an account name ('name' command).\n"); - return; - } - - LADMIN_LOG("Request to login-server to know an account name.\n"); + LADMIN_LOG("Request to login-server to know an account name.\n"_fmt); - WFIFOW(login_session, 0) = 0x7946; - WFIFOL(login_session, 2) = id; - WFIFOSET(login_session, 6); + Packet_Fixed<0x7946> fixed_46; + fixed_46.account_id = id; + send_fpacket<0x7946, 6>(login_session, fixed_46); bytes_to_read = 1; } @@ -1368,9 +1347,9 @@ void changepasswd(ZString param) if (!qsplit(param, &name, &password)) { - PRINTF("Please input an account name.\n"); - PRINTF("<example> password testname newpassword\n"); - LADMIN_LOG("Incomplete parameters to change the password of an account ('password' command).\n"); + PRINTF("Please input an account name.\n"_fmt); + PRINTF("<example> password testname newpassword\n"_fmt); + LADMIN_LOG("Incomplete parameters to change the password of an account ('password' command).\n"_fmt); return; } @@ -1382,12 +1361,12 @@ void changepasswd(ZString param) if (!password.is_print()) return; - LADMIN_LOG("Request to login-server to change a password.\n"); + LADMIN_LOG("Request to login-server to change a password.\n"_fmt); - WFIFOW(login_session, 0) = 0x7934; - WFIFO_STRING(login_session, 2, name, 24); - WFIFO_STRING(login_session, 26, password, 24); - WFIFOSET(login_session, 50); + Packet_Fixed<0x7934> fixed_34; + fixed_34.account_name = name; + fixed_34.password = password; + send_fpacket<0x7934, 50>(login_session, fixed_34); bytes_to_read = 1; } @@ -1398,13 +1377,13 @@ void changepasswd(ZString param) static void reloadGM(ZString params) { - WFIFOW(login_session, 0) = 0x7955; - WFIFOSET(login_session, 2); + Packet_Fixed<0x7955> fixed_55; + send_fpacket<0x7955, 2>(login_session, fixed_55); bytes_to_read = 0; - LADMIN_LOG("Request to reload the GM configuration file sended.\n"); - PRINTF("Request to reload the GM configuration file sended.\n"); - PRINTF("Check the actual GM accounts (after reloading):\n"); + LADMIN_LOG("Request to reload the GM configuration file sended.\n"_fmt); + PRINTF("Request to reload the GM configuration file sended.\n"_fmt); + PRINTF("Check the actual GM accounts (after reloading):\n"_fmt); listaccount(params, 1); // 1: to list only GM } @@ -1419,32 +1398,32 @@ void changesex(ZString param) if (!qsplit(param, &name, &sex_)) { - PRINTF("Please input an account name and a sex.\n"); - PRINTF("<example> sex testname Male\n"); - LADMIN_LOG("Incomplete parameters to change the sex of an account ('sex' command).\n"); + PRINTF("Please input an account name and a sex.\n"_fmt); + PRINTF("<example> sex testname Male\n"_fmt); + LADMIN_LOG("Incomplete parameters to change the sex of an account ('sex' command).\n"_fmt); return; } char sex = sex_.front(); if (!name.is_print()) { - PRINTF("bad name\n"); + PRINTF("bad name\n"_fmt); return; } - if (!XString("MF").contains(sex)) + if (!"MF"_s.contains(sex)) { - PRINTF("Illegal gender [%c]. Please input M or F.\n", sex); - LADMIN_LOG("Illegal gender [%c]. Please input M or F.\n", sex); + PRINTF("Illegal gender [%c]. Please input M or F.\n"_fmt, sex); + LADMIN_LOG("Illegal gender [%c]. Please input M or F.\n"_fmt, sex); return; } - LADMIN_LOG("Request to login-server to change a sex.\n"); + LADMIN_LOG("Request to login-server to change a sex.\n"_fmt); - WFIFOW(login_session, 0) = 0x793c; - WFIFO_STRING(login_session, 2, name, 24); - WFIFOB(login_session, 26) = sex; - WFIFOSET(login_session, 27); + Packet_Fixed<0x793c> fixed_3c; + fixed_3c.account_name = name; + fixed_3c.sex = sex_from_char(sex); + send_fpacket<0x793c, 27>(login_session, fixed_3c); bytes_to_read = 1; } @@ -1457,18 +1436,18 @@ void changestatesub(AccountName name, int state, XString error_message) { if ((state < 0 || state > 9) && state != 100) { // Valid values: 0: ok, or value of the 0x006a packet + 1 - PRINTF("Please input one of these states:\n"); - PRINTF(" 0 = Account ok 6 = Your Game's EXE file is not the latest version\n"); - PRINTF(" 1 = Unregistered ID 7 = You are Prohibited to log in until + message\n"); - PRINTF(" 2 = Incorrect Password 8 = Server is jammed due to over populated\n"); - PRINTF(" 3 = This ID is expired 9 = No MSG\n"); - PRINTF(" 4 = Rejected from Server 100 = This ID has been totally erased\n"); - PRINTF(" 5 = You have been blocked by the GM Team\n"); - PRINTF("<examples> state testname 5\n"); - PRINTF(" state testname 7 end of your ban\n"); - PRINTF(" block <account name>\n"); - PRINTF(" unblock <account name>\n"); - LADMIN_LOG("Invalid value for the state of an account ('state', 'block' or 'unblock' command).\n"); + PRINTF("Please input one of these states:\n"_fmt); + PRINTF(" 0 = Account ok 6 = Your Game's EXE file is not the latest version\n"_fmt); + PRINTF(" 1 = Unregistered ID 7 = You are Prohibited to log in until + message\n"_fmt); + PRINTF(" 2 = Incorrect Password 8 = Server is jammed due to over populated\n"_fmt); + PRINTF(" 3 = This ID is expired 9 = No MSG\n"_fmt); + PRINTF(" 4 = Rejected from Server 100 = This ID has been totally erased\n"_fmt); + PRINTF(" 5 = You have been blocked by the GM Team\n"_fmt); + PRINTF("<examples> state testname 5\n"_fmt); + PRINTF(" state testname 7 end of your ban\n"_fmt); + PRINTF(" block <account name>\n"_fmt); + PRINTF(" unblock <account name>\n"_fmt); + LADMIN_LOG("Invalid value for the state of an account ('state', 'block' or 'unblock' command).\n"_fmt); return; } @@ -1477,31 +1456,31 @@ void changestatesub(AccountName name, int state, XString error_message) if (state != 7) { - error_message = "-"; + error_message = "-"_s; } else { if (error_message.size() < 1) { - PRINTF("Error message is too short. Please input a message of 1-19 bytes.\n"); - LADMIN_LOG("Error message is too short. Please input a message of 1-19 bytes.\n"); + PRINTF("Error message is too short. Please input a message of 1-19 bytes.\n"_fmt); + LADMIN_LOG("Error message is too short. Please input a message of 1-19 bytes.\n"_fmt); return; } if (error_message.size() > 19) { - PRINTF("Error message is too long. Please input a message of 1-19 bytes.\n"); - LADMIN_LOG("Error message is too long. Please input a message of 1-19 bytes.\n"); + PRINTF("Error message is too long. Please input a message of 1-19 bytes.\n"_fmt); + LADMIN_LOG("Error message is too long. Please input a message of 1-19 bytes.\n"_fmt); return; } } - LADMIN_LOG("Request to login-server to change a state.\n"); + LADMIN_LOG("Request to login-server to change a state.\n"_fmt); - WFIFOW(login_session, 0) = 0x7936; - WFIFO_STRING(login_session, 2, name, 24); - WFIFOL(login_session, 26) = state; - WFIFO_STRING(login_session, 30, error_message, 20); - WFIFOSET(login_session, 50); + Packet_Fixed<0x7936> fixed_36; + fixed_36.account_name = name; + fixed_36.status = state; + fixed_36.error_message = stringish<timestamp_seconds_buffer>(error_message); + send_fpacket<0x7936, 50>(login_session, fixed_36); bytes_to_read = 1; } @@ -1517,12 +1496,12 @@ void changestate(ZString param) if (!qsplit(param, &name, &state, &error_message) && !qsplit(param, &name, &state)) { - PRINTF("Please input an account name and a state.\n"); - PRINTF("<examples> state testname 5\n"); - PRINTF(" state testname 7 end of your ban\n"); - PRINTF(" block <account name>\n"); - PRINTF(" unblock <account name>\n"); - LADMIN_LOG("Incomplete parameters to change the state of an account ('state' command).\n"); + PRINTF("Please input an account name and a state.\n"_fmt); + PRINTF("<examples> state testname 5\n"_fmt); + PRINTF(" state testname 7 end of your ban\n"_fmt); + PRINTF(" block <account name>\n"_fmt); + PRINTF(" unblock <account name>\n"_fmt); + LADMIN_LOG("Incomplete parameters to change the state of an account ('state' command).\n"_fmt); return; } @@ -1539,16 +1518,16 @@ void unblockaccount(ZString param) if (!qsplit(param, &name)) { - PRINTF("Please input an account name.\n"); - PRINTF("<examples> state testname 5\n"); - PRINTF(" state testname 7 end of your ban\n"); - PRINTF(" block <account name>\n"); - PRINTF(" unblock <account name>\n"); - LADMIN_LOG("Incomplete parameters to change the state of an account ('unblock' command).\n"); + PRINTF("Please input an account name.\n"_fmt); + PRINTF("<examples> state testname 5\n"_fmt); + PRINTF(" state testname 7 end of your ban\n"_fmt); + PRINTF(" block <account name>\n"_fmt); + PRINTF(" unblock <account name>\n"_fmt); + LADMIN_LOG("Incomplete parameters to change the state of an account ('unblock' command).\n"_fmt); return; } - changestatesub(name, 0, "-"); // state 0, no error message + changestatesub(name, 0, "-"_s); // state 0, no error message } //------------------------------------------- @@ -1561,16 +1540,16 @@ void blockaccount(ZString param) if (!qsplit(param, &name)) { - PRINTF("Please input an account name.\n"); - PRINTF("<examples> state testname 5\n"); - PRINTF(" state testname 7 end of your ban\n"); - PRINTF(" block <account name>\n"); - PRINTF(" unblock <account name>\n"); - LADMIN_LOG("Incomplete parameters to change the state of an account ('block' command).\n"); + PRINTF("Please input an account name.\n"_fmt); + PRINTF("<examples> state testname 5\n"_fmt); + PRINTF(" state testname 7 end of your ban\n"_fmt); + PRINTF(" block <account name>\n"_fmt); + PRINTF(" unblock <account name>\n"_fmt); + LADMIN_LOG("Incomplete parameters to change the state of an account ('block' command).\n"_fmt); return; } - changestatesub(name, 5, "-"); // state 5, no error message + changestatesub(name, 5, "-"_s); // state 5, no error message } //--------------------------------------------------------------------- @@ -1584,11 +1563,11 @@ void timeaddaccount(ZString param) if (!qsplit(param, &name, &modif)) { - PRINTF("Please input an account name and a modifier.\n"); - PRINTF(" <example>: timeadd testname +1m-2mn1s-6y\n"); - PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"); - PRINTF(" and 6 years at the same time.\n"); - LADMIN_LOG("Incomplete parameters to modify a limit time ('timeadd' command).\n"); + PRINTF("Please input an account name and a modifier.\n"_fmt); + PRINTF(" <example>: timeadd testname +1m-2mn1s-6y\n"_fmt); + PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"_fmt); + PRINTF(" and 6 years at the same time.\n"_fmt); + LADMIN_LOG("Incomplete parameters to modify a limit time ('timeadd' command).\n"_fmt); return; } if (name.is_print()) @@ -1598,28 +1577,28 @@ void timeaddaccount(ZString param) if (!modif) { - PRINTF("Please give an adjustment with this command:\n"); - PRINTF(" Adjustment value (-1, 1, +1, etc...)\n"); - PRINTF(" Modified element:\n"); - PRINTF(" a or y: year\n"); - PRINTF(" m: month\n"); - PRINTF(" j or d: day\n"); - PRINTF(" h: hour\n"); - PRINTF(" mn: minute\n"); - PRINTF(" s: second\n"); - PRINTF(" <example> timeadd testname +1m-2mn1s-6y\n"); - PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"); - PRINTF(" and 6 years at the same time.\n"); - LADMIN_LOG("No adjustment isn't an adjustment ('timeadd' command).\n"); + PRINTF("Please give an adjustment with this command:\n"_fmt); + PRINTF(" Adjustment value (-1, 1, +1, etc...)\n"_fmt); + PRINTF(" Modified element:\n"_fmt); + PRINTF(" a or y: year\n"_fmt); + PRINTF(" m: month\n"_fmt); + PRINTF(" j or d: day\n"_fmt); + PRINTF(" h: hour\n"_fmt); + PRINTF(" mn: minute\n"_fmt); + PRINTF(" s: second\n"_fmt); + PRINTF(" <example> timeadd testname +1m-2mn1s-6y\n"_fmt); + PRINTF(" this example adds 1 month and 1 second, and substracts 2 minutes\n"_fmt); + PRINTF(" and 6 years at the same time.\n"_fmt); + LADMIN_LOG("No adjustment isn't an adjustment ('timeadd' command).\n"_fmt); return; } - LADMIN_LOG("Request to login-server to modify a time limit.\n"); + LADMIN_LOG("Request to login-server to modify a time limit.\n"_fmt); - WFIFOW(login_session, 0) = 0x7950; - WFIFO_STRING(login_session, 2, name, 24); - WFIFO_STRUCT(login_session, 26, modif); - WFIFOSET(login_session, 38); + Packet_Fixed<0x7950> fixed_50; + fixed_50.account_name = name; + fixed_50.valid_add = modif; + send_fpacket<0x7950, 38>(login_session, fixed_50); bytes_to_read = 1; } @@ -1643,31 +1622,31 @@ void timesetaccount(ZString param) if (!qsplit(param, &name, &date, &time_) && !qsplit(param, &name, &date)) { - PRINTF("Please input an account name, a date and a hour.\n"); - PRINTF("<example>: timeset <account_name> yyyy/mm/dd [hh:mm:ss]\n"); - PRINTF(" timeset <account_name> 0 (0 = unlimited)\n"); - PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"); - LADMIN_LOG("Incomplete parameters to set a limit time ('timeset' command).\n"); + PRINTF("Please input an account name, a date and a hour.\n"_fmt); + PRINTF("<example>: timeset <account_name> yyyy/mm/dd [hh:mm:ss]\n"_fmt); + PRINTF(" timeset <account_name> 0 (0 = unlimited)\n"_fmt); + PRINTF(" Default time [hh:mm:ss]: 23:59:59.\n"_fmt); + LADMIN_LOG("Incomplete parameters to set a limit time ('timeset' command).\n"_fmt); return; } if (!name.is_print()) return; if (!time_) - time_ = "23:59:59"; + time_ = "23:59:59"_s; - if (date != "0" + if (date != "0"_s && ((!extract(date, record<'/'>(&year, &month, &day)) && !extract(date, record<'-'>(&year, &month, &day)) && !extract(date, record<'.'>(&year, &month, &day))) || !extract(time_, record<':'>(&hour, &minute, &second)))) { - PRINTF("Please input 0 or a date and a time (format: 0 or yyyy/mm/dd hh:mm:ss).\n"); - LADMIN_LOG("Invalid format for the date/time ('timeset' command).\n"); + PRINTF("Please input 0 or a date and a time (format: 0 or yyyy/mm/dd hh:mm:ss).\n"_fmt); + LADMIN_LOG("Invalid format for the date/time ('timeset' command).\n"_fmt); return; } - if (date == "0") + if (date == "0"_s) { connect_until_time = TimeT(); } @@ -1683,41 +1662,41 @@ void timesetaccount(ZString param) } if (month < 1 || month > 12) { - PRINTF("Please give a correct value for the month (from 1 to 12).\n"); - LADMIN_LOG("Invalid month for the date ('timeset' command).\n"); + PRINTF("Please give a correct value for the month (from 1 to 12).\n"_fmt); + LADMIN_LOG("Invalid month for the date ('timeset' command).\n"_fmt); return; } month = month - 1; if (day < 1 || day > 31) { - PRINTF("Please give a correct value for the day (from 1 to 31).\n"); - LADMIN_LOG("Invalid day for the date ('timeset' command).\n"); + PRINTF("Please give a correct value for the day (from 1 to 31).\n"_fmt); + LADMIN_LOG("Invalid day for the date ('timeset' command).\n"_fmt); return; } if (((month == 3 || month == 5 || month == 8 || month == 10) && day > 30) ||(month == 1 && day > 29)) { - PRINTF("Please give a correct value for a day of this month (%d).\n", - month); - LADMIN_LOG("Invalid day for this month ('timeset' command).\n"); + PRINTF("Please give a correct value for a day of this month (%d).\n"_fmt, + month); + LADMIN_LOG("Invalid day for this month ('timeset' command).\n"_fmt); return; } if (hour < 0 || hour > 23) { - PRINTF("Please give a correct value for the hour (from 0 to 23).\n"); - LADMIN_LOG("Invalid hour for the time ('timeset' command).\n"); + PRINTF("Please give a correct value for the hour (from 0 to 23).\n"_fmt); + LADMIN_LOG("Invalid hour for the time ('timeset' command).\n"_fmt); return; } if (minute < 0 || minute > 59) { - PRINTF("Please give a correct value for the minutes (from 0 to 59).\n"); - LADMIN_LOG("Invalid minute for the time ('timeset' command).\n"); + PRINTF("Please give a correct value for the minutes (from 0 to 59).\n"_fmt); + LADMIN_LOG("Invalid minute for the time ('timeset' command).\n"_fmt); return; } if (second < 0 || second > 59) { - PRINTF("Please give a correct value for the seconds (from 0 to 59).\n"); - LADMIN_LOG("Invalid second for the time ('timeset' command).\n"); + PRINTF("Please give a correct value for the seconds (from 0 to 59).\n"_fmt); + LADMIN_LOG("Invalid second for the time ('timeset' command).\n"_fmt); return; } tmtime.tm_year = year; @@ -1730,19 +1709,19 @@ void timesetaccount(ZString param) connect_until_time = tmtime; if (connect_until_time.error()) { - PRINTF("Invalid date.\n"); - PRINTF("Please add 0 or a date and a time (format: 0 or yyyy/mm/dd hh:mm:ss).\n"); - LADMIN_LOG("Invalid date. ('timeset' command).\n"); + PRINTF("Invalid date.\n"_fmt); + PRINTF("Please add 0 or a date and a time (format: 0 or yyyy/mm/dd hh:mm:ss).\n"_fmt); + LADMIN_LOG("Invalid date. ('timeset' command).\n"_fmt); return; } } - LADMIN_LOG("Request to login-server to set a time limit.\n"); + LADMIN_LOG("Request to login-server to set a time limit.\n"_fmt); - WFIFOW(login_session, 0) = 0x7948; - WFIFO_STRING(login_session, 2, name, 24); - WFIFOL(login_session, 26) = static_cast<time_t>(connect_until_time); - WFIFOSET(login_session, 30); + Packet_Fixed<0x7948> fixed_48; + fixed_48.account_name = name; + fixed_48.valid_until = connect_until_time; + send_fpacket<0x7948, 30>(login_session, fixed_48); bytes_to_read = 1; } @@ -1756,9 +1735,9 @@ void whoaccount(ZString param) if (!qsplit(param, &name)) { - PRINTF("Please input an account name.\n"); - PRINTF("<example> who testname\n"); - LADMIN_LOG("No name was given to found the account.\n"); + PRINTF("Please input an account name.\n"_fmt); + PRINTF("<example> who testname\n"_fmt); + LADMIN_LOG("No name was given to found the account.\n"_fmt); return; } if (!name.is_print()) @@ -1766,11 +1745,11 @@ void whoaccount(ZString param) return; } - LADMIN_LOG("Request to login-server to obtain information about an account (by its name).\n"); + LADMIN_LOG("Request to login-server to obtain information about an account (by its name).\n"_fmt); - WFIFOW(login_session, 0) = 0x7952; - WFIFO_STRING(login_session, 2, name, 24); - WFIFOSET(login_session, 26); + Packet_Fixed<0x7952> fixed_52; + fixed_52.account_name = name; + send_fpacket<0x7952, 26>(login_session, fixed_52); bytes_to_read = 1; } @@ -1780,10 +1759,10 @@ void whoaccount(ZString param) static void checkloginversion(void) { - LADMIN_LOG("Request to login-server to obtain its version.\n"); + LADMIN_LOG("Request to login-server to obtain its version.\n"_fmt); - WFIFOW(login_session, 0) = 0x7530; - WFIFOSET(login_session, 2); + Packet_Fixed<0x7530> fixed_30; + send_fpacket<0x7530, 2>(login_session, fixed_30); bytes_to_read = 1; } @@ -1798,10 +1777,10 @@ void prompt(void) // while we don't wait new packets while (bytes_to_read == 0) { - Iprintf("\n"); - Iprintf(SGR_GREEN "To list the commands, type 'enter'." SGR_RESET "\n"); - Iprintf(SGR_CYAN "Ladmin-> " SGR_RESET); - Iprintf(SGR_BOLD); + Iprintf("\n"_fmt); + Iprintf(SGR_GREEN "To list the commands, type 'enter'." SGR_RESET "\n"_fmt); + Iprintf(SGR_CYAN "Ladmin-> " SGR_RESET ""_fmt); + Iprintf(SGR_BOLD ""_fmt); fflush(stdout); // get command and parameter @@ -1810,7 +1789,7 @@ void prompt(void) AString buf; cin->getline(buf); - Iprintf(SGR_RESET); + Iprintf(SGR_RESET ""_fmt); fflush(stdout); if (!cin->is_open()) @@ -1818,8 +1797,8 @@ void prompt(void) if (!buf.is_print()) { - printf("Cowardly refusing to execute a command that includes control or non-ascii characters\n"); - LADMIN_LOG("Cowardly refusing to execute a command that includes control or non-ascii characters\n"); + PRINTF("Cowardly refusing to execute a command that includes control or non-ascii characters\n"_fmt); + LADMIN_LOG("Cowardly refusing to execute a command that includes control or non-ascii characters\n"_fmt); continue; } @@ -1832,116 +1811,116 @@ void prompt(void) parameters = buf.xislice_t(space); if (!command || command.startswith('?')) - command = "help"; + command = "help"_s; if (!parameters) { - LADMIN_LOG("Command: '%s' (without parameters)\n", + LADMIN_LOG("Command: '%s' (without parameters)\n"_fmt, command); } else { // We don't want passwords in the log - Camel - if (command == "create" || command == "add" || command == "password") { + if (command == "create"_s || command == "add"_s || command == "password"_s) { AString name, email_, password; VString<1> sex_; if (qsplit(parameters, &name, &sex_, &email_, &password)) - LADMIN_LOG("Command: '%s', parameters: '%s %s %s ***'\n", + LADMIN_LOG("Command: '%s', parameters: '%s %s %s ***'\n"_fmt, command, name, sex_, email_); else if (qsplit(parameters, &name, &sex_, &password)) - LADMIN_LOG("Command: '%s', parameters: '%s %s ***'\n", + LADMIN_LOG("Command: '%s', parameters: '%s %s ***'\n"_fmt, command, name, sex_); else if (qsplit(parameters, &name, &password)) - LADMIN_LOG("Command: '%s', parameters: '%s ***'\n", + LADMIN_LOG("Command: '%s', parameters: '%s ***'\n"_fmt, command, name); else - LADMIN_LOG("Command: '%s' (invalid parameters)\n", command); + LADMIN_LOG("Command: '%s' (invalid parameters)\n"_fmt, command); } else { - LADMIN_LOG("Command: '%s', parameters: '%s'\n", + LADMIN_LOG("Command: '%s', parameters: '%s'\n"_fmt, command, parameters); } } // Analyse of the command - if (command == "help") + if (command == "help"_s) display_help(parameters); - else if (command == "add") + else if (command == "add"_s) addaccount(parameters, 0); // 0: no email - else if (command == "ban") + else if (command == "ban"_s) banaccount(parameters); - else if (command == "banadd") + else if (command == "banadd"_s) banaddaccount(parameters); - else if (command == "banset") + else if (command == "banset"_s) bansetaccount(parameters); - else if (command == "block") + else if (command == "block"_s) blockaccount(parameters); - else if (command == "check") + else if (command == "check"_s) checkaccount(parameters); - else if (command == "create") + else if (command == "create"_s) addaccount(parameters, 1); // 1: with email - else if (command == "delete") + else if (command == "delete"_s) delaccount(parameters); - else if (command == "email") + else if (command == "email"_s) changeemail(parameters); - else if (command == "getcount") + else if (command == "getcount"_s) getlogincount(); - else if (command == "gm") + else if (command == "gm"_s) changegmlevel(parameters); - else if (command == "id") + else if (command == "id"_s) idaccount(parameters); - else if (command == "info") - infoaccount(atoi(parameters.c_str())); - else if (command == "kami") + else if (command == "info"_s) + infoaccount(wrap<AccountId>(static_cast<uint32_t>(atoi(parameters.c_str())))); + else if (command == "kami"_s) sendbroadcast(parameters); // flag for normal - else if (command == "itemfrob") + else if (command == "itemfrob"_s) itemfrob(parameters); // 0: to list all - else if (command == "list") + else if (command == "list"_s) listaccount(parameters, 0); // 0: to list all - else if (command == "listban") + else if (command == "listban"_s) listaccount(parameters, 3); // 3: to list only accounts with state or bannished - else if (command == "listgm") + else if (command == "listgm"_s) listaccount(parameters, 1); // 1: to list only GM - else if (command == "listok") + else if (command == "listok"_s) listaccount(parameters, 4); // 4: to list only accounts without state and not bannished - else if (command == "memo") + else if (command == "memo"_s) changememo(parameters); - else if (command == "name") - nameaccount(atoi(parameters.c_str())); - else if (command == "password") + else if (command == "name"_s) + nameaccount(wrap<AccountId>(static_cast<uint32_t>(atoi(parameters.c_str())))); + else if (command == "password"_s) changepasswd(parameters); - else if (command == "reloadgm") + else if (command == "reloadgm"_s) reloadGM(parameters); - else if (command == "search") + else if (command == "search"_s) listaccount(parameters, 2); // 2: to list with pattern - else if (command == "sex") + else if (command == "sex"_s) changesex(parameters); - else if (command == "state") + else if (command == "state"_s) changestate(parameters); - else if (command == "timeadd") + else if (command == "timeadd"_s) timeaddaccount(parameters); - else if (command == "timeset") + else if (command == "timeset"_s) timesetaccount(parameters); - else if (command == "unban") + else if (command == "unban"_s) unbanaccount(parameters); - else if (command == "unblock") + else if (command == "unblock"_s) unblockaccount(parameters); - else if (command == "version") + else if (command == "version"_s) checkloginversion(); - else if (command == "who") + else if (command == "who"_s) whoaccount(parameters); - else if (command == "quit" - || command == "exit" - || command == "end") + else if (command == "quit"_s + || command == "exit"_s + || command == "end"_s) { - PRINTF("Bye.\n"); + PRINTF("Bye.\n"_fmt); exit(0); } else { - PRINTF("Unknown command [%s].\n", buf); - LADMIN_LOG("Unknown command [%s].\n", buf); + PRINTF("Unknown command [%s].\n"_fmt, buf); + LADMIN_LOG("Unknown command [%s].\n"_fmt, buf); } } } @@ -1952,828 +1931,905 @@ void prompt(void) static void parse_fromlogin(Session *s) { -// PRINTF("parse_fromlogin : %d %d %d\n", fd, RFIFOREST(fd), RFIFOW(fd,0)); - - while (RFIFOREST(s) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id)) { - switch (RFIFOW(s, 0)) + switch (packet_id) { case 0x7919: // answer of a connection request - if (RFIFOREST(s) < 3) - return; - if (RFIFOB(s, 2) != 0) + { + Packet_Fixed<0x7919> fixed; + rv = recv_fpacket<0x7919, 3>(s, fixed); + if (rv != RecvResult::Complete) + break; + + if (fixed.error != 0) { - PRINTF("Error at login:\n"); - PRINTF(" - incorrect password,\n"); - PRINTF(" - administration system not activated, or\n"); - PRINTF(" - unauthorised IP.\n"); - LADMIN_LOG("Error at login: incorrect password, administration system not activated, or unauthorised IP.\n"); + PRINTF("Error at login:\n"_fmt); + PRINTF(" - incorrect password,\n"_fmt); + PRINTF(" - administration system not activated, or\n"_fmt); + PRINTF(" - unauthorised IP.\n"_fmt); + LADMIN_LOG("Error at login: incorrect password, administration system not activated, or unauthorised IP.\n"_fmt); s->set_eof(); //bytes_to_read = 1; // not stop at prompt } else { - Iprintf("Established connection.\n"); - LADMIN_LOG("Established connection.\n"); - Iprintf("Reading of the version of the login-server...\n"); - LADMIN_LOG("Reading of the version of the login-server...\n"); + Iprintf("Established connection.\n"_fmt); + LADMIN_LOG("Established connection.\n"_fmt); + Iprintf("Reading of the version of the login-server...\n"_fmt); + LADMIN_LOG("Reading of the version of the login-server...\n"_fmt); //bytes_to_read = 1; // unchanged checkloginversion(); } - RFIFOSKIP(s, 3); break; + } case 0x7531: // Displaying of the version of the login-server - if (RFIFOREST(s) < 10) - return; { - Iprintf(" Login-Server [%s:%d]\n", + Packet_Fixed<0x7531> fixed; + rv = recv_fpacket<0x7531, 10>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Iprintf(" Login-Server [%s:%d]\n"_fmt, login_ip, login_port); - Version version; - RFIFO_STRUCT(login_session, 2, version); - Iprintf(" tmwA version %hhu.%hhu.%hhu (dev? %hhu) (flags %hhx) (which %hhx) (vend %hu)\n", + Version version = fixed.version; + Iprintf(" tmwA version %hhu.%hhu.%hhu (dev? %hhu) (flags %hhx) (which %hhx) (vend %hu)\n"_fmt, version.major, version.minor, version.patch, version.devel, version.flags, version.which, version.vend); - } bytes_to_read = 0; - RFIFOSKIP(s, 10); break; + } case 0x7925: // Itemfrob-OK - RFIFOSKIP(s, 2); + { + Packet_Fixed<0x7925> fixed; + rv = recv_fpacket<0x7925, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + bytes_to_read = 0; break; + } case 0x7921: // Displaying of the list of accounts - if (RFIFOREST(s) < 4 || RFIFOREST(s) < RFIFOW(s, 2)) - return; - if (RFIFOW(s, 2) < 5) + { + std::vector<Packet_Repeat<0x7921>> repeat; + rv = recv_packet_repeatonly<0x7921, 4, 38>(s, repeat); + if (rv != RecvResult::Complete) + break; + + // the admin client resends the request with a shrunken + // range until an empty reply is given + if (repeat.empty()) { - LADMIN_LOG(" Receiving of a void accounts list.\n"); + LADMIN_LOG(" Receiving of a void accounts list.\n"_fmt); if (list_count == 0) { - Iprintf("No account found.\n"); + Iprintf("No account found.\n"_fmt); } else if (list_count == 1) { - Iprintf("1 account found.\n"); + Iprintf("1 account found.\n"_fmt); } else - Iprintf("%d accounts found.\n", list_count); + Iprintf("%d accounts found.\n"_fmt, list_count); bytes_to_read = 0; } else { - int i; - LADMIN_LOG(" Receiving of a accounts list.\n"); - for (i = 4; i < RFIFOW(s, 2); i += 38) + LADMIN_LOG(" Receiving of a accounts list.\n"_fmt); + for (const Packet_Repeat<0x7921>& info : repeat) { - AccountName userid = stringish<AccountName>(RFIFO_STRING<24>(s, i + 5)); + AccountName userid = info.account_name; VString<23> lower_userid = userid.to_lower(); - list_first = RFIFOL(s, i) + 1; + // this is ad-hoc block streaming + // (with a global variable) + list_first = next(info.account_id); // here are checks... if (list_type == 0 - || (list_type == 1 && RFIFOB(s, i + 4) > 0) + || (list_type == 1 && info.gm_level) || (list_type == 2 && lower_userid.contains_seq(parameters)) - || (list_type == 3 && RFIFOL(s, i + 34) != 0) - || (list_type == 4 && RFIFOL(s, i + 34) == 0)) + || (list_type == 3 && info.status != 0) + || (list_type == 4 && info.status == 0)) { - PRINTF("%10d ", RFIFOL(s, i)); - if (RFIFOB(s, i + 4) == 0) - PRINTF(" "); + PRINTF("%10d "_fmt, info.account_id); + if (!info.gm_level) + PRINTF(" "_fmt); else - PRINTF("%2d ", RFIFOB(s, i + 4)); - PRINTF("%-24s", userid); - if (RFIFOB(s, i + 29) == 0) - PRINTF("%-5s ", "Femal"); - else if (RFIFOB(s, i + 29) == 1) - PRINTF("%-5s ", "Male"); + PRINTF("%2d "_fmt, info.gm_level); + PRINTF("%-24s"_fmt, userid); + if (info.sex == SEX::FEMALE) + PRINTF("%-5s "_fmt, "Femal"_s); + else if (info.sex == SEX::MALE) + PRINTF("%-5s "_fmt, "Male"_s); else - PRINTF("%-5s ", "Servr"); - PRINTF("%6d ", RFIFOL(s, i + 30)); - switch (RFIFOL(s, i + 34)) + PRINTF("%-5s "_fmt, "Servr"_s); + PRINTF("%6d "_fmt, info.login_count); + switch (info.status) { case 0: - PRINTF("%-27s\n", "Account OK"); + PRINTF("%-27s\n"_fmt, "Account OK"_s); break; case 1: - PRINTF("%-27s\n", "Unregistered ID"); + PRINTF("%-27s\n"_fmt, "Unregistered ID"_s); break; case 2: - PRINTF("%-27s\n", "Incorrect Password"); + PRINTF("%-27s\n"_fmt, "Incorrect Password"_s); break; case 3: - PRINTF("%-27s\n", "This ID is expired"); + PRINTF("%-27s\n"_fmt, "This ID is expired"_s); break; case 4: - PRINTF("%-27s\n", - "Rejected from Server"); + PRINTF("%-27s\n"_fmt, + "Rejected from Server"_s); break; case 5: - PRINTF("%-27s\n", "Blocked by the GM Team"); // You have been blocked by the GM Team + PRINTF("%-27s\n"_fmt, "Blocked by the GM Team"_s); // You have been blocked by the GM Team break; case 6: - PRINTF("%-27s\n", "Your EXE file is too old"); // Your Game's EXE file is not the latest version + PRINTF("%-27s\n"_fmt, "Your EXE file is too old"_s); // Your Game's EXE file is not the latest version break; case 7: - PRINTF("%-27s\n", "Banishement or"); - PRINTF(" Prohibited to login until...\n"); // You are Prohibited to log in until %s + PRINTF("%-27s\n"_fmt, "Banishement or"_s); + PRINTF(" Prohibited to login until...\n"_fmt); // You are Prohibited to log in until %s break; case 8: - PRINTF("%-27s\n", - "Server is over populated"); + PRINTF("%-27s\n"_fmt, + "Server is over populated"_s); break; case 9: - PRINTF("%-27s\n", "No MSG"); + PRINTF("%-27s\n"_fmt, "No MSG"_s); break; default: // 100 - PRINTF("%-27s\n", "This ID is totally erased"); // This ID has been totally erased + PRINTF("%-27s\n"_fmt, "This ID is totally erased"_s); // This ID has been totally erased break; } list_count++; } } // asking of the following acounts - LADMIN_LOG("Request to login-server to obtain the list of accounts from %d to %d (complement).\n", - list_first, list_last); - WFIFOW(login_session, 0) = 0x7920; - WFIFOL(login_session, 2) = list_first; - WFIFOL(login_session, 6) = list_last; - WFIFOSET(login_session, 10); + LADMIN_LOG("Request to login-server to obtain the list of accounts from %d to %d (complement).\n"_fmt, + list_first, list_last); + Packet_Fixed<0x7920> fixed_20; + fixed_20.start_account_id = list_first; + fixed_20.end_account_id = list_last; + send_fpacket<0x7920, 10>(login_session, fixed_20); bytes_to_read = 1; } - RFIFOSKIP(s, RFIFOW(s, 2)); break; + } case 0x7931: // Answer of login-server about an account creation - if (RFIFOREST(s) < 30) - return; { - int accid = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (accid == -1) + Packet_Fixed<0x7931> fixed; + rv = recv_fpacket<0x7931, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId accid = fixed.account_id; + AccountName name = fixed.account_name; + if (!accid) { - PRINTF("Account [%s] creation failed. Same account already exists.\n", + PRINTF("Account [%s] creation failed. Same account already exists.\n"_fmt, name); - LADMIN_LOG("Account [%s] creation failed. Same account already exists.\n", + LADMIN_LOG("Account [%s] creation failed. Same account already exists.\n"_fmt, name); } else { - PRINTF("Account [%s] is successfully created [id: %d].\n", + PRINTF("Account [%s] is successfully created [id: %d].\n"_fmt, name, accid); - LADMIN_LOG("Account [%s] is successfully created [id: %d].\n", + LADMIN_LOG("Account [%s] is successfully created [id: %d].\n"_fmt, name, accid); } bytes_to_read = 0; - } - RFIFOSKIP(s, 30); break; + } case 0x7933: // Answer of login-server about an account deletion - if (RFIFOREST(s) < 30) - return; { - int accid = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (accid == -1) + Packet_Fixed<0x7933> fixed; + rv = recv_fpacket<0x7933, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId accid = fixed.account_id; + AccountName name = fixed.account_name; + if (!accid) { - PRINTF("Account [%s] deletion failed. Account doesn't exist.\n", + PRINTF("Account [%s] deletion failed. Account doesn't exist.\n"_fmt, name); - LADMIN_LOG("Account [%s] deletion failed. Account doesn't exist.\n", + LADMIN_LOG("Account [%s] deletion failed. Account doesn't exist.\n"_fmt, name); } else { - PRINTF("Account [%s][id: %d] is successfully DELETED.\n", + PRINTF("Account [%s][id: %d] is successfully DELETED.\n"_fmt, name, accid); - LADMIN_LOG("Account [%s][id: %d] is successfully DELETED.\n", + LADMIN_LOG("Account [%s][id: %d] is successfully DELETED.\n"_fmt, name, accid); } bytes_to_read = 0; - } - RFIFOSKIP(s, 30); break; + } case 0x7935: // answer of the change of an account password - if (RFIFOREST(s) < 30) - return; { - int accid = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (accid == -1) + Packet_Fixed<0x7935> fixed; + rv = recv_fpacket<0x7935, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId accid = fixed.account_id; + AccountName name = fixed.account_name; + if (!accid) { - PRINTF("Account [%s] password changing failed.\n", + PRINTF("Account [%s] password changing failed.\n"_fmt, name); - PRINTF("Account [%s] doesn't exist.\n", + PRINTF("Account [%s] doesn't exist.\n"_fmt, name); - LADMIN_LOG("Account password changing failed. The compte [%s] doesn't exist.\n", + LADMIN_LOG("Account password changing failed. The compte [%s] doesn't exist.\n"_fmt, name); } else { - PRINTF("Account [%s][id: %d] password successfully changed.\n", + PRINTF("Account [%s][id: %d] password successfully changed.\n"_fmt, name, accid); - LADMIN_LOG("Account [%s][id: %d] password successfully changed.\n", + LADMIN_LOG("Account [%s][id: %d] password successfully changed.\n"_fmt, name, accid); } bytes_to_read = 0; - } - RFIFOSKIP(s, 30); break; + } case 0x7937: // answer of the change of an account state - if (RFIFOREST(s) < 34) - return; { - int accid = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - int state = RFIFOL(s, 30); - if (accid == -1) + Packet_Fixed<0x7937> fixed; + rv = recv_fpacket<0x7937, 34>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId accid = fixed.account_id; + AccountName name = fixed.account_name; + int state = fixed.status; + if (!accid) { - PRINTF("Account [%s] state changing failed. Account doesn't exist.\n", + PRINTF("Account [%s] state changing failed. Account doesn't exist.\n"_fmt, name); - LADMIN_LOG("Account [%s] state changing failed. Account doesn't exist.\n", + LADMIN_LOG("Account [%s] state changing failed. Account doesn't exist.\n"_fmt, name); } else { MString tmpstr; tmpstr += STRPRINTF( - "Account [%s] state successfully changed in [", + "Account [%s] state successfully changed in ["_fmt, name); switch (state) { case 0: - tmpstr += "0: Account OK"; + tmpstr += "0: Account OK"_s; break; case 1: - tmpstr += "1: Unregistered ID"; + tmpstr += "1: Unregistered ID"_s; break; case 2: - tmpstr += "2: Incorrect Password"; + tmpstr += "2: Incorrect Password"_s; break; case 3: - tmpstr += "3: This ID is expired"; + tmpstr += "3: This ID is expired"_s; break; case 4: - tmpstr += "4: Rejected from Server"; + tmpstr += "4: Rejected from Server"_s; break; case 5: - tmpstr += "5: You have been blocked by the GM Team"; + tmpstr += "5: You have been blocked by the GM Team"_s; break; case 6: - tmpstr += "6: [Your Game's EXE file is not the latest version"; + tmpstr += "6: [Your Game's EXE file is not the latest version"_s; break; case 7: - tmpstr += "7: You are Prohibited to log in until..."; + tmpstr += "7: You are Prohibited to log in until..."_s; break; case 8: - tmpstr += "8: Server is jammed due to over populated"; + tmpstr += "8: Server is jammed due to over populated"_s; break; case 9: - tmpstr += "9: No MSG"; + tmpstr += "9: No MSG"_s; break; default: // 100 - tmpstr += "100: This ID is totally erased"; + tmpstr += "100: This ID is totally erased"_s; break; } tmpstr += ']'; AString tmpstr_ = AString(tmpstr); - PRINTF("%s\n", tmpstr_); - LADMIN_LOG("%s\n", tmpstr_); + PRINTF("%s\n"_fmt, tmpstr_); + LADMIN_LOG("%s\n"_fmt, tmpstr_); } bytes_to_read = 0; - } - RFIFOSKIP(s, 34); break; + } case 0x7939: // answer of the number of online players - if (RFIFOREST(s) < 4 || RFIFOREST(s) < RFIFOW(s, 2)) - return; + { + std::vector<Packet_Repeat<0x7939>> repeat; + rv = recv_packet_repeatonly<0x7939, 4, 32>(s, repeat); + if (rv != RecvResult::Complete) + break; + { // Get length of the received packet - LADMIN_LOG(" Receiving of the number of online players.\n"); + LADMIN_LOG(" Receiving of the number of online players.\n"_fmt); // Read information of the servers - if (RFIFOW(s, 2) < 5) + if (repeat.empty()) { - PRINTF(" No server is connected to the login-server.\n"); + PRINTF(" No server is connected to the login-server.\n"_fmt); } else { - PRINTF(" Number of online players (server: number).\n"); + PRINTF(" Number of online players (server: number).\n"_fmt); // Displaying of result - for (int i = 4; i < RFIFOW(s, 2); i += 32) + for (const Packet_Repeat<0x7939>& info : repeat) { - ServerName name = stringish<ServerName>(RFIFO_STRING<20>(s, i + 6)); - PRINTF(" %-20s : %5d\n", name, - RFIFOW(s, i + 26)); + // info.ip + // info.port + ServerName name = info.name; + PRINTF(" %-20s : %5d\n"_fmt, name, + info.users); + // info.maintenance + // info.is_new } } } bytes_to_read = 0; - RFIFOSKIP(s, RFIFOW(s, 2)); break; + } case 0x793b: // answer of the check of a password - if (RFIFOREST(s) < 30) - return; { - int account_id = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (account_id == -1) + Packet_Fixed<0x793b> fixed; + rv = recv_fpacket<0x793b, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + AccountName name = fixed.account_name; + if (!account_id) { - PRINTF("The account [%s] doesn't exist or the password is incorrect.\n", + PRINTF("The account [%s] doesn't exist or the password is incorrect.\n"_fmt, name); - LADMIN_LOG("The account [%s] doesn't exist or the password is incorrect.\n", + LADMIN_LOG("The account [%s] doesn't exist or the password is incorrect.\n"_fmt, name); } else { - PRINTF("The proposed password is correct for the account [%s][id: %d].\n", + PRINTF("The proposed password is correct for the account [%s][id: %d].\n"_fmt, name, account_id); - LADMIN_LOG("The proposed password is correct for the account [%s][id: %d].\n", + LADMIN_LOG("The proposed password is correct for the account [%s][id: %d].\n"_fmt, name, account_id); } bytes_to_read = 0; - } - RFIFOSKIP(s, 30); break; + } case 0x793d: // answer of the change of an account sex - if (RFIFOREST(s) < 30) - return; { - int account_id = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (account_id == -1) + Packet_Fixed<0x793d> fixed; + rv = recv_fpacket<0x793d, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + AccountName name = fixed.account_name; + if (!account_id) { - PRINTF("Account [%s] sex changing failed.\n", + PRINTF("Account [%s] sex changing failed.\n"_fmt, name); - PRINTF("Account [%s] doesn't exist or the sex is already the good sex.\n", + PRINTF("Account [%s] doesn't exist or the sex is already the good sex.\n"_fmt, name); - LADMIN_LOG("Account sex changing failed. The compte [%s] doesn't exist or the sex is already the good sex.\n", + LADMIN_LOG("Account sex changing failed. The compte [%s] doesn't exist or the sex is already the good sex.\n"_fmt, name); } else { - PRINTF("Account [%s][id: %d] sex successfully changed.\n", + PRINTF("Account [%s][id: %d] sex successfully changed.\n"_fmt, name, account_id); - LADMIN_LOG("Account [%s][id: %d] sex successfully changed.\n", + LADMIN_LOG("Account [%s][id: %d] sex successfully changed.\n"_fmt, name, account_id); } bytes_to_read = 0; - } - RFIFOSKIP(s, 30); break; + } case 0x793f: // answer of the change of an account GM level - if (RFIFOREST(s) < 30) - return; { - int account_id = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (account_id == -1) + Packet_Fixed<0x793f> fixed; + rv = recv_fpacket<0x793f, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + AccountName name = fixed.account_name; + if (!account_id) { - PRINTF("Account [%s] GM level changing failed.\n", + PRINTF("Account [%s] GM level changing failed.\n"_fmt, name); - PRINTF("Account [%s] doesn't exist, the GM level is already the good GM level\n", + PRINTF("Account [%s] doesn't exist, the GM level is already the good GM level\n"_fmt, name); - PRINTF("or it's impossible to modify the GM accounts file.\n"); - LADMIN_LOG("Account GM level changing failed. The compte [%s] doesn't exist, the GM level is already the good sex or it's impossible to modify the GM accounts file.\n", + PRINTF("or it's impossible to modify the GM accounts file.\n"_fmt); + LADMIN_LOG("Account GM level changing failed. The compte [%s] doesn't exist, the GM level is already the good sex or it's impossible to modify the GM accounts file.\n"_fmt, name); } else { - PRINTF("Account [%s][id: %d] GM level successfully changed.\n", + PRINTF("Account [%s][id: %d] GM level successfully changed.\n"_fmt, name, account_id); - LADMIN_LOG("Account [%s][id: %d] GM level successfully changed.\n", + LADMIN_LOG("Account [%s][id: %d] GM level successfully changed.\n"_fmt, name, account_id); } bytes_to_read = 0; - } - RFIFOSKIP(s, 30); break; + } case 0x7941: // answer of the change of an account email - if (RFIFOREST(s) < 30) - return; { - int account_id = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (account_id == -1) + Packet_Fixed<0x7941> fixed; + rv = recv_fpacket<0x7941, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + AccountName name = fixed.account_name; + if (!account_id) { - PRINTF("Account [%s] e-mail changing failed.\n", + PRINTF("Account [%s] e-mail changing failed.\n"_fmt, name); - PRINTF("Account [%s] doesn't exist.\n", + PRINTF("Account [%s] doesn't exist.\n"_fmt, name); - LADMIN_LOG("Account e-mail changing failed. The compte [%s] doesn't exist.\n", + LADMIN_LOG("Account e-mail changing failed. The compte [%s] doesn't exist.\n"_fmt, name); } else { - PRINTF("Account [%s][id: %d] e-mail successfully changed.\n", + PRINTF("Account [%s][id: %d] e-mail successfully changed.\n"_fmt, name, account_id); - LADMIN_LOG("Account [%s][id: %d] e-mail successfully changed.\n", + LADMIN_LOG("Account [%s][id: %d] e-mail successfully changed.\n"_fmt, name, account_id); } bytes_to_read = 0; - } - RFIFOSKIP(s, 30); break; + } case 0x7943: // answer of the change of an account memo - if (RFIFOREST(s) < 30) - return; { - int account_id = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (account_id == -1) + Packet_Fixed<0x7943> fixed; + rv = recv_fpacket<0x7943, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + AccountName name = fixed.account_name; + if (!account_id) { - PRINTF("Account [%s] memo changing failed. Account doesn't exist.\n", + PRINTF("Account [%s] memo changing failed. Account doesn't exist.\n"_fmt, name); - LADMIN_LOG("Account [%s] memo changing failed. Account doesn't exist.\n", + LADMIN_LOG("Account [%s] memo changing failed. Account doesn't exist.\n"_fmt, name); } else { - PRINTF("Account [%s][id: %d] memo successfully changed.\n", + PRINTF("Account [%s][id: %d] memo successfully changed.\n"_fmt, name, account_id); - LADMIN_LOG("Account [%s][id: %d] memo successfully changed.\n", + LADMIN_LOG("Account [%s][id: %d] memo successfully changed.\n"_fmt, name, account_id); } bytes_to_read = 0; - } - RFIFOSKIP(s, 30); break; + } case 0x7945: // answer of an account id search - if (RFIFOREST(s) < 30) - return; { - int account_id = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (account_id == -1) + Packet_Fixed<0x7945> fixed; + rv = recv_fpacket<0x7945, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + AccountName name = fixed.account_name; + if (!account_id) { - PRINTF("Unable to find the account [%s] id. Account doesn't exist.\n", + PRINTF("Unable to find the account [%s] id. Account doesn't exist.\n"_fmt, name); - LADMIN_LOG("Unable to find the account [%s] id. Account doesn't exist.\n", + LADMIN_LOG("Unable to find the account [%s] id. Account doesn't exist.\n"_fmt, name); } else { - PRINTF("The account [%s] have the id: %d.\n", + PRINTF("The account [%s] have the id: %d.\n"_fmt, name, account_id); - LADMIN_LOG("The account [%s] have the id: %d.\n", + LADMIN_LOG("The account [%s] have the id: %d.\n"_fmt, name, account_id); } bytes_to_read = 0; - } - RFIFOSKIP(s, 30); break; + } case 0x7947: // answer of an account name search - if (RFIFOREST(s) < 30) - return; { - int account_id = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); + Packet_Fixed<0x7947> fixed; + rv = recv_fpacket<0x7947, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + AccountName name = fixed.account_name; if (!name) { - PRINTF("Unable to find the account [%d] name. Account doesn't exist.\n", + PRINTF("Unable to find the account [%d] name. Account doesn't exist.\n"_fmt, account_id); - LADMIN_LOG("Unable to find the account [%d] name. Account doesn't exist.\n", + LADMIN_LOG("Unable to find the account [%d] name. Account doesn't exist.\n"_fmt, account_id); } else { - PRINTF("The account [id: %d] have the name: %s.\n", + PRINTF("The account [id: %d] have the name: %s.\n"_fmt, account_id, name); - LADMIN_LOG("The account [id: %d] have the name: %s.\n", + LADMIN_LOG("The account [id: %d] have the name: %s.\n"_fmt, account_id, name); } bytes_to_read = 0; - } - RFIFOSKIP(s, 30); break; + } case 0x7949: // answer of an account validity limit set - if (RFIFOREST(s) < 34) - return; { - int account_id = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (RFIFOL(s, 2) == -1) + Packet_Fixed<0x7949> fixed; + rv = recv_fpacket<0x7949, 34>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + AccountName name = fixed.account_name; + if (!account_id) { - PRINTF("Account [%s] validity limit changing failed. Account doesn't exist.\n", + PRINTF("Account [%s] validity limit changing failed. Account doesn't exist.\n"_fmt, name); - LADMIN_LOG("Account [%s] validity limit changing failed. Account doesn't exist.\n", + LADMIN_LOG("Account [%s] validity limit changing failed. Account doesn't exist.\n"_fmt, name); } else { - TimeT timestamp = static_cast<time_t>(RFIFOL(s, 30)); + TimeT timestamp = fixed.valid_until; if (!timestamp) { - PRINTF("Validity Limit of the account [%s][id: %d] successfully changed to [unlimited].\n", + PRINTF("Validity Limit of the account [%s][id: %d] successfully changed to [unlimited].\n"_fmt, name, account_id); - LADMIN_LOG("Validity Limit of the account [%s][id: %d] successfully changed to [unlimited].\n", + LADMIN_LOG("Validity Limit of the account [%s][id: %d] successfully changed to [unlimited].\n"_fmt, name, account_id); } else { timestamp_seconds_buffer tmpstr; stamp_time(tmpstr, ×tamp); - PRINTF("Validity Limit of the account [%s][id: %d] successfully changed to be until %s.\n", + PRINTF("Validity Limit of the account [%s][id: %d] successfully changed to be until %s.\n"_fmt, name, account_id, tmpstr); - LADMIN_LOG("Validity Limit of the account [%s][id: %d] successfully changed to be until %s.\n", + LADMIN_LOG("Validity Limit of the account [%s][id: %d] successfully changed to be until %s.\n"_fmt, name, account_id, tmpstr); } } bytes_to_read = 0; - } - RFIFOSKIP(s, 34); break; + } case 0x794b: // answer of an account ban set - if (RFIFOREST(s) < 34) - return; { - int account_id = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (account_id == -1) + Packet_Fixed<0x794b> fixed; + rv = recv_fpacket<0x794b, 34>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + AccountName name = fixed.account_name; + if (!account_id) { - PRINTF("Account [%s] final date of banishment changing failed. Account doesn't exist.\n", + PRINTF("Account [%s] final date of banishment changing failed. Account doesn't exist.\n"_fmt, name); - LADMIN_LOG("Account [%s] final date of banishment changing failed. Account doesn't exist.\n", + LADMIN_LOG("Account [%s] final date of banishment changing failed. Account doesn't exist.\n"_fmt, name); } else { - TimeT timestamp = static_cast<time_t>(RFIFOL(s, 30)); + TimeT timestamp = fixed.ban_until; if (!timestamp) { - PRINTF("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n", + PRINTF("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n"_fmt, name, account_id); - LADMIN_LOG("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n", + LADMIN_LOG("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n"_fmt, name, account_id); } else { timestamp_seconds_buffer tmpstr; stamp_time(tmpstr, ×tamp); - PRINTF("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n", - name, RFIFOL(s, 2), tmpstr); - LADMIN_LOG("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n", - name, RFIFOL(s, 2), + PRINTF("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n"_fmt, + name, account_id, tmpstr); + LADMIN_LOG("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n"_fmt, + name, account_id, tmpstr); } } bytes_to_read = 0; - } - RFIFOSKIP(s, 34); break; + } case 0x794d: // answer of an account ban date/time changing - if (RFIFOREST(s) < 34) - return; { - int account_id = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (account_id == -1) + Packet_Fixed<0x794d> fixed; + rv = recv_fpacket<0x794d, 34>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + AccountName name = fixed.account_name; + if (!account_id) { - PRINTF("Account [%s] final date of banishment changing failed. Account doesn't exist.\n", + PRINTF("Account [%s] final date of banishment changing failed. Account doesn't exist.\n"_fmt, name); - LADMIN_LOG("Account [%s] final date of banishment changing failed. Account doesn't exist.\n", + LADMIN_LOG("Account [%s] final date of banishment changing failed. Account doesn't exist.\n"_fmt, name); } else { - TimeT timestamp = static_cast<time_t>(RFIFOL(s, 30)); + TimeT timestamp = fixed.ban_until; if (!timestamp) { - PRINTF("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n", + PRINTF("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n"_fmt, name, account_id); - LADMIN_LOG("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n", + LADMIN_LOG("Final date of banishment of the account [%s][id: %d] successfully changed to [unbanished].\n"_fmt, name, account_id); } else { timestamp_seconds_buffer tmpstr; stamp_time(tmpstr, ×tamp); - PRINTF("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n", + PRINTF("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n"_fmt, name, account_id, tmpstr); - LADMIN_LOG("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n", + LADMIN_LOG("Final date of banishment of the account [%s][id: %d] successfully changed to be until %s.\n"_fmt, name, account_id, tmpstr); } } bytes_to_read = 0; - } - RFIFOSKIP(s, 34); break; + } case 0x794f: // answer of a broadcast - if (RFIFOREST(s) < 4) - return; - if (RFIFOW(s, 2) == static_cast<uint16_t>(-1)) + { + Packet_Fixed<0x794f> fixed; + rv = recv_fpacket<0x794f, 4>(s, fixed); + if (rv != RecvResult::Complete) + break; + + if (fixed.error == static_cast<uint16_t>(-1)) { - PRINTF("Message sending failed. No online char-server.\n"); - LADMIN_LOG("Message sending failed. No online char-server.\n"); + PRINTF("Message sending failed. No online char-server.\n"_fmt); + LADMIN_LOG("Message sending failed. No online char-server.\n"_fmt); } else { - PRINTF("Message successfully sended to login-server.\n"); - LADMIN_LOG("Message successfully sended to login-server.\n"); + PRINTF("Message successfully sended to login-server.\n"_fmt); + LADMIN_LOG("Message successfully sended to login-server.\n"_fmt); } bytes_to_read = 0; - RFIFOSKIP(s, 4); break; + } case 0x7951: // answer of an account validity limit changing - if (RFIFOREST(s) < 34) - return; { - int account_id = RFIFOL(s, 2); - AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - if (account_id == -1) + Packet_Fixed<0x7951> fixed; + rv = recv_fpacket<0x7951, 34>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + AccountName name = fixed.account_name; + if (!account_id) { - PRINTF("Account [%s] validity limit changing failed. Account doesn't exist.\n", + PRINTF("Account [%s] validity limit changing failed. Account doesn't exist.\n"_fmt, name); - LADMIN_LOG("Account [%s] validity limit changing failed. Account doesn't exist.\n", + LADMIN_LOG("Account [%s] validity limit changing failed. Account doesn't exist.\n"_fmt, name); } else { - TimeT timestamp = static_cast<time_t>(RFIFOL(s, 30)); + TimeT timestamp = fixed.valid_until; if (!timestamp) { - PRINTF("Validity limit of the account [%s][id: %d] unchanged.\n", + PRINTF("Validity limit of the account [%s][id: %d] unchanged.\n"_fmt, name, account_id); - PRINTF("The account have an unlimited validity limit or\n"); - PRINTF("the changing is impossible with the proposed adjustments.\n"); - LADMIN_LOG("Validity limit of the account [%s][id: %d] unchanged. The account have an unlimited validity limit or the changing is impossible with the proposed adjustments.\n", + PRINTF("The account have an unlimited validity limit or\n"_fmt); + PRINTF("the changing is impossible with the proposed adjustments.\n"_fmt); + LADMIN_LOG("Validity limit of the account [%s][id: %d] unchanged. The account have an unlimited validity limit or the changing is impossible with the proposed adjustments.\n"_fmt, name, account_id); } else { timestamp_seconds_buffer tmpstr; stamp_time(tmpstr, ×tamp); - PRINTF("Validity limit of the account [%s][id: %d] successfully changed to be until %s.\n", + PRINTF("Validity limit of the account [%s][id: %d] successfully changed to be until %s.\n"_fmt, name, account_id, tmpstr); - LADMIN_LOG("Validity limit of the account [%s][id: %d] successfully changed to be until %s.\n", + LADMIN_LOG("Validity limit of the account [%s][id: %d] successfully changed to be until %s.\n"_fmt, name, account_id, tmpstr); } } bytes_to_read = 0; - } - RFIFOSKIP(s, 34); break; + } case 0x7953: // answer of a request about informations of an account (by account name/id) - if (RFIFOREST(s) < 150 - || RFIFOREST(s) < (150 + RFIFOW(s, 148))) - return; + { + Packet_Head<0x7953> head; + AString repeat; + rv = recv_vpacket<0x7953, 150, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + break; + { - int account_id = RFIFOL(s, 2); - uint8_t gm = RFIFOB(s, 6); - AccountName userid = stringish<AccountName>(RFIFO_STRING<24>(s, 7)); - uint8_t sex = RFIFOB(s, 31); - int connections = RFIFOL(s, 32); - int state = RFIFOL(s, 36); - timestamp_seconds_buffer error_message = stringish<timestamp_seconds_buffer>(RFIFO_STRING<20>(s, 40)); - timestamp_milliseconds_buffer lastlogin = stringish<timestamp_milliseconds_buffer>(RFIFO_STRING<24>(s, 60)); - VString<15> last_ip_ = RFIFO_STRING<16>(s, 84); - AccountEmail email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 100)); - TimeT connect_until_time = static_cast<time_t>(RFIFOL(s, 140)); - TimeT ban_until_time = static_cast<time_t>(RFIFOL(s, 144)); - AString memo = RFIFO_STRING(s, 150, RFIFOW(s, 148)); - if (account_id == -1) + AccountId account_id = head.account_id; + // TODO fix size (there's a lot of other stuff wrong with this packet too + GmLevel gm = head.gm_level; + AccountName userid = head.account_name; + SEX sex = head.sex; + int connections = head.login_count; + int state = head.state; + timestamp_seconds_buffer error_message = head.error_message; + timestamp_milliseconds_buffer lastlogin = head.last_login_string; + VString<15> last_ip_ = head.ip_string; + AccountEmail email = head.email; + TimeT connect_until_time = head.connect_until; + TimeT ban_until_time = head.ban_until; + AString& memo = repeat; + if (!account_id) { - PRINTF("Unabled to find the account [%s]. Account doesn't exist.\n", + PRINTF("Unabled to find the account [%s]. Account doesn't exist.\n"_fmt, userid); - LADMIN_LOG("Unabled to find the account [%s]. Account doesn't exist.\n", + LADMIN_LOG("Unabled to find the account [%s]. Account doesn't exist.\n"_fmt, userid); } else if (!userid) { - PRINTF("Unabled to find the account [id: %d]. Account doesn't exist.\n", + PRINTF("Unabled to find the account [id: %d]. Account doesn't exist.\n"_fmt, account_id); - LADMIN_LOG("Unabled to find the account [id: %d]. Account doesn't exist.\n", + LADMIN_LOG("Unabled to find the account [id: %d]. Account doesn't exist.\n"_fmt, account_id); } else { - LADMIN_LOG("Receiving information about an account.\n"); - PRINTF("The account is set with:\n"); + LADMIN_LOG("Receiving information about an account.\n"_fmt); + PRINTF("The account is set with:\n"_fmt); if (!gm) { - PRINTF(" Id: %d (non-GM)\n", account_id); + PRINTF(" Id: %d (non-GM)\n"_fmt, account_id); } else { - PRINTF(" Id: %d (GM level %d)\n", + PRINTF(" Id: %d (GM level %d)\n"_fmt, account_id, gm); } - PRINTF(" Name: '%s'\n", userid); - if (sex == 0) - PRINTF(" Sex: Female\n"); - else if (sex == 1) - PRINTF(" Sex: Male\n"); - else - PRINTF(" Sex: Server\n"); - PRINTF(" E-mail: %s\n", email); + PRINTF(" Name: '%s'\n"_fmt, userid); + if (sex == SEX::FEMALE) + PRINTF(" Sex: Female\n"_fmt); + else if (sex == SEX::MALE) + PRINTF(" Sex: Male\n"_fmt); + else // doesn't happen anymore + PRINTF(" Sex: Server\n"_fmt); + PRINTF(" E-mail: %s\n"_fmt, email); switch (state) { case 0: - PRINTF(" Statut: 0 [Account OK]\n"); + PRINTF(" Statut: 0 [Account OK]\n"_fmt); break; case 1: - PRINTF(" Statut: 1 [Unregistered ID]\n"); + PRINTF(" Statut: 1 [Unregistered ID]\n"_fmt); break; case 2: - PRINTF(" Statut: 2 [Incorrect Password]\n"); + PRINTF(" Statut: 2 [Incorrect Password]\n"_fmt); break; case 3: - PRINTF(" Statut: 3 [This ID is expired]\n"); + PRINTF(" Statut: 3 [This ID is expired]\n"_fmt); break; case 4: - PRINTF(" Statut: 4 [Rejected from Server]\n"); + PRINTF(" Statut: 4 [Rejected from Server]\n"_fmt); break; case 5: - PRINTF(" Statut: 5 [You have been blocked by the GM Team]\n"); + PRINTF(" Statut: 5 [You have been blocked by the GM Team]\n"_fmt); break; case 6: - PRINTF(" Statut: 6 [Your Game's EXE file is not the latest version]\n"); + PRINTF(" Statut: 6 [Your Game's EXE file is not the latest version]\n"_fmt); break; case 7: - PRINTF(" Statut: 7 [You are Prohibited to log in until %s]\n", - error_message); + PRINTF(" Statut: 7 [You are Prohibited to log in until %s]\n"_fmt, + error_message); break; case 8: - PRINTF(" Statut: 8 [Server is jammed due to over populated]\n"); + PRINTF(" Statut: 8 [Server is jammed due to over populated]\n"_fmt); break; case 9: - PRINTF(" Statut: 9 [No MSG]\n"); + PRINTF(" Statut: 9 [No MSG]\n"_fmt); break; default: // 100 - PRINTF(" Statut: %d [This ID is totally erased]\n", + PRINTF(" Statut: %d [This ID is totally erased]\n"_fmt, state); break; } if (!ban_until_time) { - PRINTF(" Banishment: not banished.\n"); + PRINTF(" Banishment: not banished.\n"_fmt); } else { timestamp_seconds_buffer tmpstr; stamp_time(tmpstr, &ban_until_time); - PRINTF(" Banishment: until %s.\n", tmpstr); + PRINTF(" Banishment: until %s.\n"_fmt, tmpstr); } if (connections > 1) - PRINTF(" Count: %d connections.\n", + PRINTF(" Count: %d connections.\n"_fmt, connections); else - PRINTF(" Count: %d connection.\n", + PRINTF(" Count: %d connection.\n"_fmt, connections); - PRINTF(" Last connection at: %s (ip: %s)\n", + PRINTF(" Last connection at: %s (ip: %s)\n"_fmt, lastlogin, last_ip_); if (!connect_until_time) { - PRINTF(" Validity limit: unlimited.\n"); + PRINTF(" Validity limit: unlimited.\n"_fmt); } else { timestamp_seconds_buffer tmpstr; stamp_time(tmpstr, &connect_until_time); - PRINTF(" Validity limit: until %s.\n", + PRINTF(" Validity limit: until %s.\n"_fmt, tmpstr); } - PRINTF(" Memo: '%s'\n", memo); + PRINTF(" Memo: '%s'\n"_fmt, memo); } } bytes_to_read = 0; - RFIFOSKIP(s, 150 + RFIFOW(s, 148)); break; + } default: - PRINTF("Remote administration has been disconnected (unknown packet).\n"); - LADMIN_LOG("'End of connection, unknown packet.\n"); + { + PRINTF("Remote administration has been disconnected (unknown packet).\n"_fmt); + LADMIN_LOG("'End of connection, unknown packet.\n"_fmt); s->set_eof(); return; + } } } + if (rv == RecvResult::Error) + { + s->set_eof(); + return; + } + + // The following was almost certainly wrong and only worked because + // localhost is a fast enough network to never split byte 1 vs byte 2 + // if we don't wait new packets, do the prompt - prompt(); + if (bytes_to_read == 0) + prompt(); } //------------------------------------ @@ -2782,23 +2838,23 @@ void parse_fromlogin(Session *s) static int Connect_login_server(void) { - Iprintf("Attempt to connect to login-server...\n"); - LADMIN_LOG("Attempt to connect to login-server...\n"); + Iprintf("Attempt to connect to login-server...\n"_fmt); + LADMIN_LOG("Attempt to connect to login-server...\n"_fmt); - login_session = make_connection(login_ip, login_port, SessionParsers{func_parse: parse_fromlogin, func_delete: delete_fromlogin}); + login_session = make_connection(login_ip, login_port, SessionParsers{.func_parse= parse_fromlogin, .func_delete= delete_fromlogin}); if (!login_session) return 0; { - WFIFOW(login_session, 0) = 0x7918; // Request for administation login - WFIFOW(login_session, 2) = 0; // no encrypted - WFIFO_STRING(login_session, 4, admin_pass, 24); - WFIFOSET(login_session, 28); + Packet_Fixed<0x7918> fixed_18; + fixed_18.encryption_zero = 0; + fixed_18.account_pass = admin_pass; + send_fpacket<0x7918, 28>(login_session, fixed_18); bytes_to_read = 1; - Iprintf("Sending of the password...\n"); - LADMIN_LOG("Sending of the password...\n"); + Iprintf("Sending of the password...\n"_fmt); + LADMIN_LOG("Sending of the password...\n"_fmt); } return 0; @@ -2808,12 +2864,12 @@ static bool admin_confs(XString w1, ZString w2) { { - if (w1 == "login_ip") + if (w1 == "login_ip"_s) { struct hostent *h = gethostbyname(w2.c_str()); - if (h != NULL) + if (h != nullptr) { - Iprintf("Login server IP address: %s -> %s\n", + Iprintf("Login server IP address: %s -> %s\n"_fmt, w2, login_ip); login_ip = IP4Address({ static_cast<uint8_t>(h->h_addr[0]), @@ -2823,21 +2879,21 @@ bool admin_confs(XString w1, ZString w2) }); } } - else if (w1 == "login_port") + else if (w1 == "login_port"_s) { login_port = atoi(w2.c_str()); } - else if (w1 == "admin_pass") + else if (w1 == "admin_pass"_s) { admin_pass = stringish<AccountPass>(w2); } - else if (w1 == "ladmin_log_filename") + else if (w1 == "ladmin_log_filename"_s) { ladmin_log_filename = w2; } else { - PRINTF("WARNING: unknown ladmin config key: %s\n", AString(w1)); + PRINTF("WARNING: unknown ladmin config key: %s\n"_fmt, AString(w1)); return false; } } @@ -2854,8 +2910,8 @@ void term_func(void) { delete_session(login_session); - Iprintf(SGR_RESET "----End of Ladmin (normal end with closing of all files).\n"); - LADMIN_LOG("----End of Ladmin (normal end with closing of all files).\n"); + Iprintf(SGR_RESET "----End of Ladmin (normal end with closing of all files).\n"_fmt); + LADMIN_LOG("----End of Ladmin (normal end with closing of all files).\n"_fmt); already_exit_function = 1; } @@ -2873,20 +2929,20 @@ int do_init(Slice<ZString> argv) ZString argvi = argv.pop_front(); if (argvi.startswith('-')) { - if (argvi == "--help") + if (argvi == "--help"_s) { - PRINTF("Usage: %s [--help] [--version] [files...]\n", + PRINTF("Usage: %s [--help] [--version] [files...]\n"_fmt, argv0); exit(0); } - else if (argvi == "--version") + else if (argvi == "--version"_s) { - PRINTF("%s\n", CURRENT_VERSION_STRING); + PRINTF("%s\n"_fmt, CURRENT_VERSION_STRING); exit(0); } else { - FPRINTF(stderr, "Unknown argument: %s\n", argvi); + FPRINTF(stderr, "Unknown argument: %s\n"_fmt, argvi); runflag = false; } } @@ -2898,26 +2954,27 @@ int do_init(Slice<ZString> argv) } if (!loaded_config_yet) - runflag &= load_config_file("conf/tmwa-admin.conf", admin_confs); + runflag &= load_config_file("conf/tmwa-admin.conf"_s, admin_confs); eathena_interactive_session = isatty(0); - LADMIN_LOG(""); - LADMIN_LOG("Configuration file readed.\n"); + LADMIN_LOG(""_fmt); + LADMIN_LOG("Configuration file readed.\n"_fmt); - Iprintf("EAthena login-server administration tool.\n"); + Iprintf("EAthena login-server administration tool.\n"_fmt); Version version = CURRENT_LOGIN_SERVER_VERSION; - Iprintf("for tmwA version %hhu.%hhu.%hhu (dev? %hhu) (flags %hhx) (which %hhx) (vend %hu)\n", + Iprintf("for tmwA version %hhu.%hhu.%hhu (dev? %hhu) (flags %hhx) (which %hhx) (vend %hu)\n"_fmt, version.major, version.minor, version.patch, version.devel, version.flags, version.which, version.vend); - LADMIN_LOG("Ladmin is ready.\n"); - Iprintf("Ladmin is " SGR_BOLD SGR_GREEN "ready" SGR_RESET ".\n\n"); + LADMIN_LOG("Ladmin is ready.\n"_fmt); + Iprintf("Ladmin is " SGR_BOLD SGR_GREEN "ready" SGR_RESET ".\n\n"_fmt); Connect_login_server(); return 0; } +} // namespace tmwa diff --git a/src/admin/ladmin.hpp b/src/admin/ladmin.hpp index 034f644..94783ac 100644 --- a/src/admin/ladmin.hpp +++ b/src/admin/ladmin.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_ADMIN_LADMIN_HPP -#define TMWA_ADMIN_LADMIN_HPP +#pragma once // ladmin.hpp - dummy header to make Make dependencies work. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,6 +18,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -#endif // TMWA_ADMIN_LADMIN_HPP + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/admin/main.cpp b/src/admin/main.cpp index c6f075e..678286e 100644 --- a/src/admin/main.cpp +++ b/src/admin/main.cpp @@ -1,4 +1,3 @@ -#include "ladmin.hpp" // admin/main.cpp - dummy file to make Make dependencies work // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -18,4 +17,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include "ladmin.hpp" + #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/char/char.cpp b/src/char/char.cpp index f8e12c0..b9cf17b 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -22,8 +22,6 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <arpa/inet.h> -#include <sys/socket.h> #include <sys/wait.h> #include <netdb.h> @@ -33,32 +31,45 @@ #include <cassert> #include <cstdlib> -#include <cstring> -#include <ctime> +#include <algorithm> +#include <array> #include <bitset> +#include <chrono> #include <set> -#include "../compat/alg.hpp" +#include "../ints/cmp.hpp" +#include "../ints/udl.hpp" #include "../strings/mstring.hpp" #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" -#include "../generic/db.hpp" +#include "../generic/array.hpp" #include "../io/cxxstdio.hpp" #include "../io/lock.hpp" #include "../io/read.hpp" #include "../io/tty.hpp" +#include "../io/write.hpp" + +#include "../net/packets.hpp" +#include "../net/socket.hpp" +#include "../net/timer.hpp" + +#include "../proto2/any-user.hpp" +#include "../proto2/login-admin.hpp" +#include "../proto2/login-char.hpp" +#include "../proto2/char-map.hpp" +#include "../proto2/char-user.hpp" #include "../mmo/config_parse.hpp" #include "../mmo/core.hpp" #include "../mmo/extract.hpp" #include "../mmo/human_time_diff.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" +#include "../mmo/mmo.hpp" +#include "../mmo/utils.hpp" #include "../mmo/version.hpp" #include "inter.hpp" @@ -67,6 +78,9 @@ #include "../poison.hpp" + +namespace tmwa +{ static Array<struct mmo_map_server, MAX_MAP_SERVERS> server; static @@ -76,11 +90,11 @@ Array<int, MAX_MAP_SERVERS> server_freezeflag; // Map-server anti-freeze syst static int anti_freeze_enable = 0; static -std::chrono::seconds anti_freeze_interval = std::chrono::seconds(6); +std::chrono::seconds anti_freeze_interval = 6_s; constexpr std::chrono::milliseconds DEFAULT_AUTOSAVE_INTERVAL = - std::chrono::minutes(5); + 5_min; static Session *login_session, *char_session; @@ -91,7 +105,7 @@ AccountPass passwd; static ServerName server_name; static -CharName wisp_server_name = stringish<CharName>("Server"); +CharName wisp_server_name = stringish<CharName>("Server"_s); static IP4Address login_ip; static @@ -103,9 +117,9 @@ int char_port = 6121; static AString char_txt; static -CharName unknown_char_name = stringish<CharName>("Unknown"); +CharName unknown_char_name = stringish<CharName>("Unknown"_s); static -AString char_log_filename = "log/char.log"; +AString char_log_filename = "log/char.log"_s; //Added for lan support static IP4Address lan_map_ip = IP4_LOCALHOST; @@ -115,10 +129,14 @@ static int char_name_option = 0; // Option to know which letters/symbols are authorised in the name of a character (0: all, 1: only those in char_name_letters, 2: all EXCEPT those in char_name_letters) by [Yor] static std::bitset<256> char_name_letters; // list of letters/symbols authorised (or not) in a character name. by [Yor] +static constexpr +GmLevel default_gm_level = GmLevel::from(0_u32); + struct char_session_data : SessionData { - int account_id, login_id1, login_id2; + AccountId account_id; + int login_id1, login_id2; SEX sex; unsigned short packet_tmw_version; AccountEmail email; @@ -132,8 +150,8 @@ void SessionDeleter::operator()(SessionData *sd) struct AuthFifoEntry { - int account_id; - int char_id; + AccountId account_id; + CharId char_id; int login_id1, login_id2; IP4Address ip; int delflag; @@ -150,7 +168,7 @@ static int check_ip_flag = 1; // It's to check IP of a player between char-server and other servers (part of anti-hacking system) static -int char_id_count = 150000; +CharId char_id_count = wrap<CharId>(150000); static std::vector<CharPair> char_keys; static @@ -160,22 +178,22 @@ std::chrono::milliseconds autosave_time = DEFAULT_AUTOSAVE_INTERVAL; // Initial position (it's possible to set it in conf file) static -struct point start_point = { {"001-1.gat"}, 273, 354 }; +Point start_point = { {"001-1.gat"_s}, 273, 354 }; static std::vector<GM_Account> gm_accounts; // online players by [Yor] static -AString online_txt_filename = "online.txt"; +AString online_txt_filename = "online.txt"_s; static -AString online_html_filename = "online.html"; +AString online_html_filename = "online.html"_s; static int online_sorting_option = 0; // sorting option to display online players in online files static int online_refresh_html = 20; // refresh time (in sec) of the html file in the explorer static -int online_gm_display_min_level = 20; // minimum GM level to display 'GM' when we want to display it +GmLevel online_gm_display_min_level = GmLevel::from(20_u32); // minimum GM level to display 'GM' when we want to display it static std::vector<Session *> online_chars; // same size of char_keys, and id value of current server (or -1) @@ -185,6 +203,14 @@ TimeT update_online; // to update online files when we receiving infor static pid_t pid = 0; // For forked DB writes + +auto iter_map_sessions() -> decltype(filter_iterator<Session *>(std::declval<Array<Session *, MAX_MAP_SERVERS> *>())) +{ + return filter_iterator<Session *>(&server_session); +} + + + static void create_online_files(void); @@ -192,7 +218,7 @@ static void delete_tologin(Session *sess) { assert (sess == login_session); - PRINTF("Char-server can't connect to login-server (connection #%d).\n", + PRINTF("Char-server can't connect to login-server (connection #%d).\n"_fmt, sess); login_session = nullptr; } @@ -207,7 +233,7 @@ void delete_frommap(Session *sess) auto it = std::find(server_session.begin(), server_session.end(), sess); assert (it != server_session.end()); int id = it - server_session.begin(); - PRINTF("Map-server %d (session #%d) has disconnected.\n", id, + PRINTF("Map-server %d (session #%d) has disconnected.\n"_fmt, id, sess); server[id] = mmo_map_server{}; server_session[id] = nullptr; @@ -233,12 +259,12 @@ void char_log(XString line) // and returns its level (or 0 if it isn't a GM account or if not found) //---------------------------------------------------------------------- static -int isGM(int account_id) +GmLevel isGM(AccountId account_id) { for (GM_Account& gma : gm_accounts) if (gma.account_id == account_id) return gma.level; - return 0; + return default_gm_level; } //---------------------------------------------- @@ -264,7 +290,7 @@ const CharPair *search_character(CharName character_name) return nullptr; } -const CharPair *search_character_id(int char_id) +const CharPair *search_character_id(CharId char_id) { for (const CharPair& cd : char_keys) { @@ -317,7 +343,7 @@ AString mmo_char_tostr(struct CharPair *cp) "%d,%d,%d\t" "%d,%d,%d,%d,%d\t" "%s,%d,%d\t" - "%s,%d,%d,%d\t", + "%s,%d,%d,%d\t"_fmt, k->char_id, k->account_id, k->char_num, k->name, @@ -336,11 +362,12 @@ AString mmo_char_tostr(struct CharPair *cp) // memos were here (no longer supported) str_p += '\t'; - for (int i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) + { if (p->inventory[i].nameid) { - str_p += STRPRINTF("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ", - p->inventory[i].id, + str_p += STRPRINTF("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d "_fmt, + 0 /*id*/, p->inventory[i].nameid, p->inventory[i].amount, p->inventory[i].equip, @@ -353,33 +380,40 @@ AString mmo_char_tostr(struct CharPair *cp) 0 /*card[3]*/, 0 /*broken*/); } + } str_p += '\t'; // cart was here (no longer supported) str_p += '\t'; for (SkillID i : erange(SkillID(), MAX_SKILL)) + { if (p->skill[i].lv) { - str_p += STRPRINTF("%d,%d ", + str_p += STRPRINTF("%d,%d "_fmt, i, - p->skill[i].lv | (uint16_t(p->skill[i].flags) << 16)); + p->skill[i].lv | (static_cast<uint16_t>(p->skill[i].flags) << 16)); } + } str_p += '\t'; assert (p->global_reg_num < GLOBAL_REG_NUM); for (int i = 0; i < p->global_reg_num; i++) + { if (p->global_reg[i].str) - str_p += STRPRINTF("%s,%d ", + { + str_p += STRPRINTF("%s,%d "_fmt, p->global_reg[i].str, p->global_reg[i].value); + } + } str_p += '\t'; return AString(str_p); } static -bool extract(XString str, struct point *p) +bool extract(XString str, Point *p) { return extract(str, record<','>(&p->map_, &p->x, &p->y)); } @@ -414,10 +448,11 @@ bool extract(XString str, CharPair *cp) uint32_t unused_guild_id, unused_pet_id; XString unused_memos; - std::vector<struct item> inventory; + std::vector<Item> inventory; XString unused_cart; std::vector<struct skill_loader> skills; - std::vector<struct global_reg> vars; + std::vector<GlobalReg> vars; + XString hair_style; if (!extract(str, record<'\t'>( &k->char_id, @@ -430,7 +465,7 @@ bool extract(XString str, CharPair *cp) record<','>(&p->status_point, &p->skill_point), record<','>(&p->option, &p->karma, &p->manner), record<','>(&p->party_id, &unused_guild_id, &unused_pet_id), - record<','>(&p->hair, &p->hair_color, &p->clothes_color), + record<','>(&hair_style, &p->hair_color, &p->clothes_color), record<','>(&p->weapon, &p->shield, &p->head_top, &p->head_mid, &p->head_bottom), &p->last_point, // somebody was silly and stuck partner id as a field @@ -444,11 +479,19 @@ bool extract(XString str, CharPair *cp) vrec<' '>(&vars)))) return false; + // leftover corruption from Platinum + if (hair_style == "-1"_s) + { + p->hair = 0; + } + else if (!extract(hair_style, &p->hair)) + return false; + if (wisp_server_name == k->name) return false; // TODO replace *every* lookup with a map lookup - static std::set<int> seen_ids; + static std::set<CharId> seen_ids; static std::set<CharName> seen_names; // we don't have to worry about deleted characters, // this is only called during startup @@ -499,10 +542,10 @@ int mmo_char_init(void) io::ReadFile in(char_txt); if (!in.is_open()) { - PRINTF("Characters file not found: %s.\n", char_txt); - CHAR_LOG("Characters file not found: %s.\n", char_txt); - CHAR_LOG("Id for the next created character: %d.\n", - char_id_count); + PRINTF("Characters file not found: %s.\n"_fmt, char_txt); + CHAR_LOG("Characters file not found: %s.\n"_fmt, char_txt); + CHAR_LOG("Id for the next created character: %d.\n"_fmt, + char_id_count); return 0; } @@ -516,8 +559,8 @@ int mmo_char_init(void) continue; { - int i, j = 0; - if (SSCANF(line, "%d\t%%newid%%%n", &i, &j) == 1 && j > 0) + CharId i; + if (extract(line, record<'\t'>(&i, "%newid%"_s))) { if (char_id_count < i) char_id_count = i; @@ -528,21 +571,21 @@ int mmo_char_init(void) CharPair cd; if (!extract(line, &cd)) { - CHAR_LOG("Char skipped\n%s", line); + CHAR_LOG("Char skipped\n%s"_fmt, line); continue; } - if (cd.key.char_id >= char_id_count) - char_id_count = cd.key.char_id + 1; + if (char_id_count < next(cd.key.char_id)) + char_id_count = next(cd.key.char_id); char_keys.push_back(std::move(cd)); online_chars.push_back(nullptr); } - PRINTF("mmo_char_init: %zu characters read in %s.\n", + PRINTF("mmo_char_init: %zu characters read in %s.\n"_fmt, char_keys.size(), char_txt); - CHAR_LOG("mmo_char_init: %zu characters read in %s.\n", + CHAR_LOG("mmo_char_init: %zu characters read in %s.\n"_fmt, char_keys.size(), char_txt); - CHAR_LOG("Id for the next created character: %d.\n", + CHAR_LOG("Id for the next created character: %d.\n"_fmt, char_id_count); return 0; @@ -557,8 +600,8 @@ void mmo_char_sync(void) io::WriteLock fp(char_txt); if (!fp.is_open()) { - PRINTF("WARNING: Server can't not save characters.\n"); - CHAR_LOG("WARNING: Server can't not save characters.\n"); + PRINTF("WARNING: Server can't not save characters.\n"_fmt); + CHAR_LOG("WARNING: Server can't not save characters.\n"_fmt); return; } { @@ -568,7 +611,7 @@ void mmo_char_sync(void) AString line = mmo_char_tostr(&cd); fp.put_line(line); } - FPRINTF(fp, "%d\t%%newid%%\n", char_id_count); + FPRINTF(fp, "%d\t%%newid%%\n"_fmt, char_id_count); } } @@ -612,7 +655,7 @@ void mmo_char_sync_timer(TimerData *, tick_t) // Function to create a new character //----------------------------------- static -CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], uint8_t slot, uint16_t hair_color, uint16_t hair_style) +CharPair *make_new_char(Session *s, CharName name, const Stats6& stats, uint8_t slot, uint16_t hair_color, uint16_t hair_style) { // ugh char_session_data *sd = static_cast<char_session_data *>(s->session_data.get()); @@ -620,24 +663,24 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui // remove control characters from the name if (!name.to__actual().is_print()) { - CHAR_LOG("Make new char error (control char received in the name): (connection #%d, account: %d).\n", - s, sd->account_id); + CHAR_LOG("Make new char error (control char received in the name): (connection #%d, account: %d).\n"_fmt, + s, sd->account_id); return nullptr; } // Eliminate whitespace if (name.to__actual() != name.to__actual().strip()) { - CHAR_LOG("Make new char error (leading/trailing whitespace): (connection #%d, account: %d, name: '%s'.\n", - s, sd->account_id, name); + CHAR_LOG("Make new char error (leading/trailing whitespace): (connection #%d, account: %d, name: '%s'.\n"_fmt, + s, sd->account_id, name); return nullptr; } // check lenght of character name if (name.to__actual().size() < 4) { - CHAR_LOG("Make new char error (character name too small): (connection #%d, account: %d, name: '%s').\n", - s, sd->account_id, name); + CHAR_LOG("Make new char error (character name too small): (connection #%d, account: %d, name: '%s').\n"_fmt, + s, sd->account_id, name); return nullptr; } @@ -648,7 +691,7 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui for (uint8_t c : name.to__actual()) if (!char_name_letters[c]) { - CHAR_LOG("Make new char error (invalid letter in the name): (connection #%d, account: %d), name: %s, invalid letter: %c.\n", + CHAR_LOG("Make new char error (invalid letter in the name): (connection #%d, account: %d), name: %s, invalid letter: %c.\n"_fmt, s, sd->account_id, name, c); return nullptr; } @@ -659,36 +702,38 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui for (uint8_t c : name.to__actual()) if (char_name_letters[c]) { - CHAR_LOG("Make new char error (invalid letter in the name): (connection #%d, account: %d), name: %s, invalid letter: %c.\n", + CHAR_LOG("Make new char error (invalid letter in the name): (connection #%d, account: %d), name: %s, invalid letter: %c.\n"_fmt, s, sd->account_id, name, c); return nullptr; } } // else, all letters/symbols are authorised (except control char removed before) + // TODO this comment is obsolete // this is why it needs to be unsigned - if (stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5] != 5 * 6 || // stats + if (stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk != 5 * 6 || // stats slot >= 9 || hair_style >= 20 || hair_color >= 12) { - CHAR_LOG("Make new char error (invalid values): (connection #%d, account: %d) slot %d, name: %s, stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d\n", - s, sd->account_id, slot, name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], - hair_style, hair_color); + CHAR_LOG("Make new char error (invalid values): (connection #%d, account: %d) slot %d, name: %s, stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d\n"_fmt, + s, sd->account_id, slot, name, + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, + hair_style, hair_color); return nullptr; } // check individual stat value for (int i = 0; i < 6; i++) { - if (stats[i] < 1 || stats[i] > 9) + uint8_t statsi = reinterpret_cast<const uint8_t *>(&stats)[i]; + if (statsi < 1 || statsi > 9) { - CHAR_LOG("Make new char error (invalid stat value: not between 1 to 9): (connection #%d, account: %d) slot %d, name: %s, stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d\n", - s, sd->account_id, slot, name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], - hair_style, hair_color); + CHAR_LOG("Make new char error (invalid stat value: not between 1 to 9): (connection #%d, account: %d) slot %d, name: %s, stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d\n"_fmt, + s, sd->account_id, slot, name, + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, + hair_style, hair_color); return nullptr; } } @@ -697,63 +742,63 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui { if (cd.key.name == name) { - CHAR_LOG("Make new char error (name already exists): (connection #%d, account: %d) slot %d, name: %s (actual name of other char: %s), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d.\n", - s, sd->account_id, slot, name, cd.key.name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], - hair_style, hair_color); + CHAR_LOG("Make new char error (name already exists): (connection #%d, account: %d) slot %d, name: %s (actual name of other char: %s), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d.\n"_fmt, + s, sd->account_id, slot, name, cd.key.name, + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, + hair_style, hair_color); return nullptr; } if (cd.key.account_id == sd->account_id && cd.key.char_num == slot) { - CHAR_LOG("Make new char error (slot already used): (connection #%d, account: %d) slot %d, name: %s (actual name of other char: %s), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d.\n", - s, sd->account_id, slot, name, cd.key.name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], - hair_style, hair_color); + CHAR_LOG("Make new char error (slot already used): (connection #%d, account: %d) slot %d, name: %s (actual name of other char: %s), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d.\n"_fmt, + s, sd->account_id, slot, name, cd.key.name, + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, + hair_style, hair_color); return nullptr; } } if (wisp_server_name == name) { - CHAR_LOG("Make new char error (name used is wisp name for server): (connection #%d, account: %d) slot %d, name: %s (actual name whisper server: %s), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d.\n", - s, sd->account_id, slot, name, wisp_server_name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], - hair_style, hair_color); + CHAR_LOG("Make new char error (name used is wisp name for server): (connection #%d, account: %d) slot %d, name: %s (actual name whisper server: %s), stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d.\n"_fmt, + s, sd->account_id, slot, name, wisp_server_name, + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, + hair_style, hair_color); return nullptr; } IP4Address ip = s->client_ip; - CHAR_LOG("Creation of New Character: (connection #%d, account: %d) slot %d, character Name: %s, stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d. [%s]\n", - s, sd->account_id, slot, name, - stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], - stats[0] + stats[1] + stats[2] + stats[3] + stats[4] + stats[5], - hair_style, hair_color, ip); + CHAR_LOG("Creation of New Character: (connection #%d, account: %d) slot %d, character Name: %s, stats: %d+%d+%d+%d+%d+%d=%d, hair: %d, hair color: %d. [%s]\n"_fmt, + s, sd->account_id, slot, name, + stats.str, stats.agi, stats.vit, stats.int_, stats.dex, stats.luk, + stats.str + stats.agi + stats.vit + stats.int_ + stats.dex + stats.luk, + hair_style, hair_color, ip); CharPair cp; CharKey& ck = cp.key; CharData& cd = *cp.data; - ck.char_id = char_id_count++; + ck.char_id = char_id_count; char_id_count = next(char_id_count); ck.account_id = sd->account_id; ck.char_num = slot; ck.name = name; - cd.species = 0; + cd.species = Species(); cd.base_level = 1; cd.job_level = 1; cd.base_exp = 0; cd.job_exp = 0; cd.zeny = 0; - cd.attrs[ATTR::STR] = stats[0]; - cd.attrs[ATTR::AGI] = stats[1]; - cd.attrs[ATTR::VIT] = stats[2]; - cd.attrs[ATTR::INT] = stats[3]; - cd.attrs[ATTR::DEX] = stats[4]; - cd.attrs[ATTR::LUK] = stats[5]; + cd.attrs[ATTR::STR] = stats.str; + cd.attrs[ATTR::AGI] = stats.agi; + cd.attrs[ATTR::VIT] = stats.vit; + cd.attrs[ATTR::INT] = stats.int_; + cd.attrs[ATTR::DEX] = stats.dex; + cd.attrs[ATTR::LUK] = stats.luk; cd.max_hp = 40 * (100 + cd.attrs[ATTR::VIT]) / 100; cd.max_sp = 11 * (100 + cd.attrs[ATTR::INT]) / 100; cd.hp = cd.max_hp; @@ -763,17 +808,17 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui cd.option = static_cast<Option>(0x0000); // Option is only declared cd.karma = 0; cd.manner = 0; - cd.party_id = 0; + cd.party_id = PartyId(); //cd.guild_id = 0; cd.hair = hair_style; cd.hair_color = hair_color; cd.clothes_color = 0; // removed initial armor/weapon - unused and problematic cd.weapon = ItemLook::NONE; - cd.shield = 0; - cd.head_top = 0; - cd.head_mid = 0; - cd.head_bottom = 0; + cd.shield = ItemNameId(); + cd.head_top = ItemNameId(); + cd.head_mid = ItemNameId(); + cd.head_bottom = ItemNameId(); cd.last_point = start_point; cd.save_point = start_point; char_keys.push_back(std::move(cp)); @@ -799,17 +844,17 @@ void create_online_files(void) timestamp_seconds_buffer timetemp; stamp_time(timetemp); // write heading - FPRINTF(fp2, "<HTML>\n"); - FPRINTF(fp2, " <META http-equiv=\"Refresh\" content=\"%d\">\n", online_refresh_html); // update on client explorer every x seconds - FPRINTF(fp2, " <HEAD>\n"); - FPRINTF(fp2, " <TITLE>Online Players on %s</TITLE>\n", - server_name); - FPRINTF(fp2, " </HEAD>\n"); - FPRINTF(fp2, " <BODY>\n"); - FPRINTF(fp2, " <H3>Online Players on %s (%s):</H3>\n", - server_name, timetemp); - FPRINTF(fp, "Online Players on %s (%s):\n", server_name, timetemp); - FPRINTF(fp, "\n"); + FPRINTF(fp2, "<HTML>\n"_fmt); + FPRINTF(fp2, " <META http-equiv=\"Refresh\" content=\"%d\">\n"_fmt, online_refresh_html); // update on client explorer every x seconds + FPRINTF(fp2, " <HEAD>\n"_fmt); + FPRINTF(fp2, " <TITLE>Online Players on %s</TITLE>\n"_fmt, + server_name); + FPRINTF(fp2, " </HEAD>\n"_fmt); + FPRINTF(fp2, " <BODY>\n"_fmt); + FPRINTF(fp2, " <H3>Online Players on %s (%s):</H3>\n"_fmt, + server_name, timetemp); + FPRINTF(fp, "Online Players on %s (%s):\n"_fmt, server_name, timetemp); + FPRINTF(fp, "\n"_fmt); int players = 0; // This used to be conditional on having any players, @@ -817,20 +862,20 @@ void create_online_files(void) //if (players > 0) { int j = 0; // count the number of characters for the txt version and to set the separate line - FPRINTF(fp2, " <table border=\"1\" cellspacing=\"1\">\n"); - FPRINTF(fp2, " <tr>\n"); + FPRINTF(fp2, " <table border=\"1\" cellspacing=\"1\">\n"_fmt); + FPRINTF(fp2, " <tr>\n"_fmt); { - FPRINTF(fp2, " <th>Name</th>\n"); + FPRINTF(fp2, " <th>Name</th>\n"_fmt); { - FPRINTF(fp, "Name "); // 30 + FPRINTF(fp, "Name "_fmt); // 30 j += 30; } } - FPRINTF(fp2, " </tr>\n"); - FPRINTF(fp, "\n"); + FPRINTF(fp2, " </tr>\n"_fmt); + FPRINTF(fp, "\n"_fmt); for (int k = 0; k < j; k++) - FPRINTF(fp, "-"); - FPRINTF(fp, "\n"); + FPRINTF(fp, "-"_fmt); + FPRINTF(fp, "\n"_fmt); // display each player. for (CharPair& cd : char_keys) @@ -838,55 +883,55 @@ void create_online_files(void) if (!server_for(&cd)) continue; players++; - FPRINTF(fp2, " <tr>\n"); + FPRINTF(fp2, " <tr>\n"_fmt); // displaying the character name { // without/with 'GM' display - int gml = isGM(cd.key.account_id); + GmLevel gml = isGM(cd.key.account_id); { - if (gml >= online_gm_display_min_level) - FPRINTF(fp, "%-24s (GM) ", cd.key.name); + if (gml.satisfies(online_gm_display_min_level)) + FPRINTF(fp, "%-24s (GM) "_fmt, cd.key.name); else - FPRINTF(fp, "%-24s ", cd.key.name); + FPRINTF(fp, "%-24s "_fmt, cd.key.name); } // name of the character in the html (no < >, because that create problem in html code) - FPRINTF(fp2, " <td>"); - if (gml >= online_gm_display_min_level) - FPRINTF(fp2, "<b>"); + FPRINTF(fp2, " <td>"_fmt); + if (gml.satisfies(online_gm_display_min_level)) + FPRINTF(fp2, "<b>"_fmt); for (char c : cd.key.name.to__actual()) { switch (c) { case '&': - FPRINTF(fp2, "&"); + FPRINTF(fp2, "&"_fmt); break; case '<': - FPRINTF(fp2, "<"); + FPRINTF(fp2, "<"_fmt); break; case '>': - FPRINTF(fp2, ">"); + FPRINTF(fp2, ">"_fmt); break; default: - FPRINTF(fp2, "%c", c); + FPRINTF(fp2, "%c"_fmt, c); break; }; } - if (gml >= online_gm_display_min_level) - FPRINTF(fp2, "</b> (GM)"); - FPRINTF(fp2, "</td>\n"); + if (gml.satisfies(online_gm_display_min_level)) + FPRINTF(fp2, "</b> (GM)"_fmt); + FPRINTF(fp2, "</td>\n"_fmt); } - FPRINTF(fp, "\n"); - FPRINTF(fp2, " </tr>\n"); + FPRINTF(fp, "\n"_fmt); + FPRINTF(fp2, " </tr>\n"_fmt); } - FPRINTF(fp2, " </table>\n"); - FPRINTF(fp, "\n"); + FPRINTF(fp2, " </table>\n"_fmt); + FPRINTF(fp, "\n"_fmt); } // Displaying number of online players if (players == 0) { - FPRINTF(fp2, " <p>No user is online.</p>\n"); - FPRINTF(fp, "No user is online.\n"); + FPRINTF(fp2, " <p>No user is online.</p>\n"_fmt); + FPRINTF(fp, "No user is online.\n"_fmt); } else if (players == 1) { @@ -894,11 +939,11 @@ void create_online_files(void) } else { - FPRINTF(fp2, " <p>%d users are online.</p>\n", players); - FPRINTF(fp, "%d users are online.\n", players); + FPRINTF(fp2, " <p>%d users are online.</p>\n"_fmt, players); + FPRINTF(fp, "%d users are online.\n"_fmt, players); } - FPRINTF(fp2, " </BODY>\n"); - FPRINTF(fp2, "</HTML>\n"); + FPRINTF(fp2, " </BODY>\n"_fmt); + FPRINTF(fp2, "</HTML>\n"_fmt); } } @@ -925,14 +970,18 @@ int count_users(void) // [Fate] Find inventory item based on equipment mask, return view. ID must match view ID (!). //---------------------------------------- static -int find_equip_view(const CharPair *cp, EPOS equipmask) +ItemNameId find_equip_view(const CharPair *cp, EPOS equipmask) { CharData *p = cp->data.get(); - for (int i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) + { if (p->inventory[i].nameid && p->inventory[i].amount && bool(p->inventory[i].equip & equipmask)) + { return p->inventory[i].nameid; - return 0; + } + } + return ItemNameId(); } //---------------------------------------- @@ -954,72 +1003,75 @@ int mmo_char_send006b(Session *s, struct char_session_data *sd) } } - const int offset = 24; - WFIFO_ZERO(s, 0, offset + found_num * 106); - WFIFOW(s, 0) = 0x6b; - WFIFOW(s, 2) = offset + found_num * 106; + Packet_Head<0x006b> head_6b; + std::vector<Packet_Repeat<0x006b>> repeat_6b; + + head_6b.unused = {}; for (int i = 0; i < found_num; i++) { const CharPair *cp = found_char[i]; - int j = offset + (i * 106); const CharKey *k = &cp->key; const CharData *p = cp->data.get(); - WFIFOL(s, j) = k->char_id; - WFIFOL(s, j + 4) = p->base_exp; - WFIFOL(s, j + 8) = p->zeny; - WFIFOL(s, j + 12) = p->job_exp; - WFIFOL(s, j + 16) = p->job_level; - - WFIFOW(s, j + 20) = find_equip_view(cp, EPOS::SHOES); - WFIFOW(s, j + 22) = find_equip_view(cp, EPOS::GLOVES); - WFIFOW(s, j + 24) = find_equip_view(cp, EPOS::CAPE); - WFIFOW(s, j + 26) = find_equip_view(cp, EPOS::MISC1); - WFIFOL(s, j + 28) = static_cast<uint16_t>(p->option); - - WFIFOL(s, j + 32) = p->karma; - WFIFOL(s, j + 36) = p->manner; - - WFIFOW(s, j + 40) = p->status_point; - WFIFOW(s, j + 42) = (p->hp > 0x7fff) ? 0x7fff : p->hp; - WFIFOW(s, j + 44) = (p->max_hp > 0x7fff) ? 0x7fff : p->max_hp; - WFIFOW(s, j + 46) = (p->sp > 0x7fff) ? 0x7fff : p->sp; - WFIFOW(s, j + 48) = (p->max_sp > 0x7fff) ? 0x7fff : p->max_sp; - WFIFOW(s, j + 50) = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // p->speed; - WFIFOW(s, j + 52) = p->species; - WFIFOW(s, j + 54) = p->hair; -// WFIFOW(s,j+56) = p->weapon; // dont send weapon since TMW does not support it - WFIFOW(s, j + 56) = 0; - WFIFOW(s, j + 58) = p->base_level; - WFIFOW(s, j + 60) = p->skill_point; - WFIFOW(s, j + 62) = p->head_bottom; - WFIFOW(s, j + 64) = p->shield; - WFIFOW(s, j + 66) = p->head_top; - WFIFOW(s, j + 68) = p->head_mid; - WFIFOW(s, j + 70) = p->hair_color; - WFIFOW(s, j + 72) = find_equip_view(cp, EPOS::MISC2); -// WFIFOW(s,j+72) = p->clothes_color; - - WFIFO_STRING(s, j + 74, k->name.to__actual(), 24); - - WFIFOB(s, j + 98) = min(p->attrs[ATTR::STR], 255); - WFIFOB(s, j + 99) = min(p->attrs[ATTR::AGI], 255); - WFIFOB(s, j + 100) = min(p->attrs[ATTR::VIT], 255); - WFIFOB(s, j + 101) = min(p->attrs[ATTR::INT], 255); - WFIFOB(s, j + 102) = min(p->attrs[ATTR::DEX], 255); - WFIFOB(s, j + 103) = min(p->attrs[ATTR::LUK], 255); - WFIFOB(s, j + 104) = k->char_num; + Packet_Repeat<0x006b> info; + CharSelect& sel = info.char_select; + + sel.char_id = k->char_id; + sel.base_exp = p->base_exp; + sel.zeny = p->zeny; + sel.job_exp = p->job_exp; + sel.job_level = p->job_level; + + sel.shoes = find_equip_view(cp, EPOS::SHOES); + sel.gloves = find_equip_view(cp, EPOS::GLOVES); + sel.cape = find_equip_view(cp, EPOS::CAPE); + sel.misc1 = find_equip_view(cp, EPOS::MISC1); + sel.option = p->option; + + sel.karma = p->karma; + sel.manner = p->manner; + + sel.status_point = p->status_point; + sel.hp = std::min(p->hp, 0x7fff); + sel.max_hp = std::min(p->max_hp, 0x7fff); + sel.sp = std::min(p->sp, 0x7fff); + sel.max_sp = std::min(p->max_sp, 0x7fff); + sel.speed = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // p->speed; + sel.species = p->species; + sel.hair_style = p->hair; + sel.weapon = 0; // p->weapon; // dont send weapon since TMW does not support it + sel.base_level = p->base_level; + sel.skill_point = p->skill_point; + sel.head_bottom = p->head_bottom; + sel.shield = p->shield; + sel.head_top = p->head_top; + sel.head_mid = p->head_mid; + sel.hair_color = p->hair_color; + sel.misc2 = find_equip_view(cp, EPOS::MISC2); // = p->clothes_color; + + sel.char_name = k->name; + + sel.stats.str = saturate<uint8_t>(p->attrs[ATTR::STR]); + sel.stats.agi = saturate<uint8_t>(p->attrs[ATTR::AGI]); + sel.stats.vit = saturate<uint8_t>(p->attrs[ATTR::VIT]); + sel.stats.int_ = saturate<uint8_t>(p->attrs[ATTR::INT]); + sel.stats.dex = saturate<uint8_t>(p->attrs[ATTR::DEX]); + sel.stats.luk = saturate<uint8_t>(p->attrs[ATTR::LUK]); + sel.char_num = k->char_num; + sel.unused = 0; + + repeat_6b.push_back(info); } - WFIFOSET(s, WFIFOW(s, 2)); + send_vpacket<0x006b, 24, 106>(s, head_6b, repeat_6b); return 0; } static -int set_account_reg2(int acc, Slice<global_reg> reg) +int set_account_reg2(AccountId acc, Slice<GlobalReg> reg) { size_t num = reg.size(); assert (num < ACCOUNT_REG2_NUM); @@ -1032,7 +1084,7 @@ int set_account_reg2(int acc, Slice<global_reg> reg) cd.data->account_reg2[i] = reg[i]; cd.data->account_reg2_num = num; for (int i = num; i < ACCOUNT_REG2_NUM; ++i) - cd.data->account_reg2[i] = global_reg{}; + cd.data->account_reg2[i] = GlobalReg{}; c++; } } @@ -1043,52 +1095,65 @@ int set_account_reg2(int acc, Slice<global_reg> reg) static int char_divorce(CharPair *cp) { - uint8_t buf[10]; - - if (cp == NULL) + if (cp == nullptr) return 0; CharKey *ck = &cp->key; CharData *cs = cp->data.get(); - if (cs->partner_id <= 0) + if (!cs->partner_id) { - WBUFW(buf, 0) = 0x2b12; - WBUFL(buf, 2) = ck->char_id; - WBUFL(buf, 6) = 0; // partner id 0 means failure - mapif_sendall(buf, 10); + Packet_Fixed<0x2b12> fixed_12; + fixed_12.char_id = ck->char_id; + // partner id 0 means failure + fixed_12.partner_id = cs->partner_id; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b12, 10>(ss, fixed_12); + } return 0; } - WBUFW(buf, 0) = 0x2b12; - WBUFL(buf, 2) = ck->char_id; + Packet_Fixed<0x2b12> fixed_12; + fixed_12.char_id = ck->char_id; for (CharPair& cd : char_keys) { if (cd.key.char_id == cs->partner_id && cd.data->partner_id == ck->char_id) { - WBUFL(buf, 6) = cs->partner_id; - mapif_sendall(buf, 10); - cs->partner_id = 0; - cd.data->partner_id = 0; + fixed_12.partner_id = cs->partner_id; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b12, 10>(ss, fixed_12); + } + + cs->partner_id = CharId(); + cd.data->partner_id = CharId(); return 0; } // The other char doesn't have us as their partner, so just clear our partner // Don't worry about this, as the map server should verify itself that the other doesn't have us as a partner, and so won't mess with their marriage else if (cd.key.char_id == cs->partner_id) { - WBUFL(buf, 6) = cs->partner_id; - mapif_sendall(buf, 10); - cs->partner_id = 0; + fixed_12.partner_id = cs->partner_id; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b12, 10>(ss, fixed_12); + } + + cs->partner_id = CharId(); return 0; } } // Our partner wasn't found, so just clear our marriage - WBUFL(buf, 6) = cs->partner_id; - cs->partner_id = 0; - mapif_sendall(buf, 10); + fixed_12.partner_id = cs->partner_id; + cs->partner_id = CharId(); + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b12, 10>(ss, fixed_12); + } return 0; } @@ -1097,25 +1162,24 @@ int char_divorce(CharPair *cp) // Force disconnection of an online player (with account value) by [Yor] //---------------------------------------------------------------------- static -int disconnect_player(int accound_id) +void disconnect_player(AccountId accound_id) { // disconnect player if online on char-server for (io::FD i : iter_fds()) { - if (!get_session(i)) + Session *s = get_session(i); + if (!s) continue; - struct char_session_data *sd = static_cast<char_session_data *>(get_session(i)->session_data.get()); + struct char_session_data *sd = static_cast<char_session_data *>(s->session_data.get()); if (sd) { if (sd->account_id == accound_id) { - get_session(i)->set_eof(); - return 1; + s->set_eof(); + return; } } } - - return 0; } // キャラ削除に伴うデータ削除 @@ -1134,10 +1198,12 @@ int char_delete(CharPair *cp) // Force the character (and all on the same account) to leave all map servers { - unsigned char buf[6]; - WBUFW(buf, 0) = 0x2afe; - WBUFL(buf, 2) = ck->account_id; - mapif_sendall(buf, 6); + Packet_Fixed<0x2afe> fixed_fe; + fixed_fe.account_id = ck->account_id; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2afe, 6>(ss, fixed_fe); + } } return 0; @@ -1146,143 +1212,156 @@ int char_delete(CharPair *cp) static void parse_tologin(Session *ls) { - // only login-server can have an access to here. - // so, if it isn't the login-server, we disconnect the session (fd != login_fd). - if (ls != login_session) - { - ls->set_eof(); - return; - } + assert (ls == login_session); char_session_data *sd = static_cast<char_session_data *>(ls->session_data.get()); - while (RFIFOREST(ls) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(ls, &packet_id)) { -// PRINTF("parse_tologin: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd)); - - switch (RFIFOW(ls, 0)) + switch (packet_id) { case 0x2711: - if (RFIFOREST(ls) < 3) - return; - if (RFIFOB(ls, 2)) + { + Packet_Fixed<0x2711> fixed; + rv = recv_fpacket<0x2711, 3>(ls, fixed); + if (rv != RecvResult::Complete) + break; + + if (fixed.code) { -// PRINTF("connect login server error : %d\n", RFIFOB(fd,2)); - PRINTF("Can not connect to login-server.\n"); - PRINTF("The server communication passwords (default s1/p1) is probably invalid.\n"); - PRINTF("Also, please make sure your accounts file (default: accounts.txt) has those values present.\n"); - PRINTF("If you changed the communication passwords, change them back at map_athena.conf and char_athena.conf\n"); + PRINTF("Can not connect to login-server.\n"_fmt); + PRINTF("The server communication passwords (default s1/p1) is probably invalid.\n"_fmt); + PRINTF("Also, please make sure your accounts file (default: accounts.txt) has those values present.\n"_fmt); + PRINTF("If you changed the communication passwords, change them back at map_athena.conf and char_athena.conf\n"_fmt); exit(1); } else { - PRINTF("Connected to login-server (connection #%d).\n", + PRINTF("Connected to login-server (connection #%d).\n"_fmt, ls); // if no map-server already connected, display a message... int i; for (i = 0; i < MAX_MAP_SERVERS; i++) + { if (server_session[i] && server[i].maps[0]) // if map-server online and at least 1 map break; + } if (i == MAX_MAP_SERVERS) - PRINTF("Awaiting maps from map-server.\n"); + PRINTF("Awaiting maps from map-server.\n"_fmt); } - RFIFOSKIP(ls, 3); break; + } case 0x2713: - if (RFIFOREST(ls) < 51) - return; -// PRINTF("parse_tologin 2713 : %d\n", RFIFOB(fd,6)); + { + Packet_Fixed<0x2713> fixed; + rv = recv_fpacket<0x2713, 51>(ls, fixed); + if (rv != RecvResult::Complete) + break; + for (io::FD i : iter_fds()) { + AccountId acc = fixed.account_id; Session *s2 = get_session(i); if (!s2) continue; sd = static_cast<char_session_data *>(s2->session_data.get()); - if (sd && sd->account_id == RFIFOL(ls, 2)) + if (sd && sd->account_id == acc) { - if (RFIFOB(ls, 6) != 0) + if (fixed.invalid != 0) { - WFIFOW(s2, 0) = 0x6c; - WFIFOB(s2, 2) = 0x42; - WFIFOSET(s2, 3); + Packet_Fixed<0x006c> fixed_6c; + fixed_6c.code = 0x42; + send_fpacket<0x006c, 3>(s2, fixed_6c); } else if (max_connect_user == 0 || count_users() < max_connect_user) { -// if (max_connect_user == 0) -// PRINTF("max_connect_user (unlimited) -> accepted.\n"); -// else -// PRINTF("count_users(): %d < max_connect_user (%d) -> accepted.\n", count_users(), max_connect_user); - sd->email = stringish<AccountEmail>(RFIFO_STRING<40>(ls, 7)); + sd->email = stringish<AccountEmail>(fixed.email); if (!e_mail_check(sd->email)) sd->email = DEFAULT_EMAIL; - sd->connect_until_time = static_cast<time_t>(RFIFOL(ls, 47)); + sd->connect_until_time = fixed.connect_until; // send characters to player mmo_char_send006b(s2, sd); } else { // refuse connection: too much online players -// PRINTF("count_users(): %d < max_connect_use (%d) -> fail...\n", count_users(), max_connect_user); - WFIFOW(s2, 0) = 0x6c; - WFIFOB(s2, 2) = 0; - WFIFOSET(s2, 3); + Packet_Fixed<0x006c> fixed_6c; + fixed_6c.code = 0; + send_fpacket<0x006c, 3>(s2, fixed_6c); } break; } } - RFIFOSKIP(ls, 51); break; + } // Receiving of an e-mail/time limit from the login-server (answer of a request because a player comes back from map-server to char-server) by [Yor] case 0x2717: - if (RFIFOREST(ls) < 50) - return; + { + Packet_Fixed<0x2717> fixed; + rv = recv_fpacket<0x2717, 50>(ls, fixed); + if (rv != RecvResult::Complete) + break; + for (io::FD i : iter_fds()) { + AccountId acc = fixed.account_id; Session *s2 = get_session(i); if (!s2) continue; sd = static_cast<char_session_data *>(s2->session_data.get()); if (sd) { - if (sd->account_id == RFIFOL(ls, 2)) + if (sd->account_id == acc) { - sd->email = stringish<AccountEmail>(RFIFO_STRING<40>(ls, 6)); + sd->email = fixed.email; if (!e_mail_check(sd->email)) sd->email = DEFAULT_EMAIL; - sd->connect_until_time = static_cast<time_t>(RFIFOL(ls, 46)); + sd->connect_until_time = fixed.connect_until; break; } } } - RFIFOSKIP(ls, 50); break; + } case 0x2721: // gm reply - if (RFIFOREST(ls) < 10) - return; + { + Packet_Fixed<0x2721> fixed; + rv = recv_fpacket<0x2721, 10>(ls, fixed); + if (rv != RecvResult::Complete) + break; + { - unsigned char buf[10]; - WBUFW(buf, 0) = 0x2b0b; - WBUFL(buf, 2) = RFIFOL(ls, 2); // account - WBUFL(buf, 6) = RFIFOL(ls, 6); // GM level - mapif_sendall(buf, 10); -// PRINTF("parse_tologin: To become GM answer: char -> map.\n"); + AccountId acc = fixed.account_id; + GmLevel gml = fixed.gm_level; + + Packet_Fixed<0x2b0b> fixed_2b; + fixed_2b.account_id = acc; + fixed_2b.gm_level = gml; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b0b, 10>(ss, fixed_2b); + } } - RFIFOSKIP(ls, 10); break; + } case 0x2723: // changesex reply (modified by [Yor]) - if (RFIFOREST(ls) < 7) - return; + { + Packet_Fixed<0x2723> fixed; + rv = recv_fpacket<0x2723, 7>(ls, fixed); + if (rv != RecvResult::Complete) + break; + { - unsigned char buf[7]; - int acc = RFIFOL(ls, 2); - SEX sex = static_cast<SEX>(RFIFOB(ls, 6)); - RFIFOSKIP(ls, 7); - if (acc > 0) + AccountId acc = fixed.account_id; + SEX sex = fixed.sex; + if (acc) { for (CharPair& cp : char_keys) { @@ -1293,35 +1372,43 @@ void parse_tologin(Session *ls) cd.sex = sex; // auth_fifo[i].sex = sex; // to avoid any problem with equipment and invalid sex, equipment is unequiped. - for (int j = 0; j < MAX_INVENTORY; j++) + for (IOff0 j : IOff0::iter()) { if (cd.inventory[j].nameid && bool(cd.inventory[j].equip)) cd.inventory[j].equip = EPOS::ZERO; } cd.weapon = ItemLook::NONE; - cd.shield = 0; - cd.head_top = 0; - cd.head_mid = 0; - cd.head_bottom = 0; + cd.shield = ItemNameId(); + cd.head_top = ItemNameId(); + cd.head_mid = ItemNameId(); + cd.head_bottom = ItemNameId(); } } // disconnect player if online on char-server disconnect_player(acc); } - WBUFW(buf, 0) = 0x2b0d; - WBUFL(buf, 2) = acc; - WBUFB(buf, 6) = static_cast<uint8_t>(sex); - mapif_sendall(buf, 7); + Packet_Fixed<0x2b0d> fixed_0d; + fixed_0d.account_id = acc; + fixed_0d.sex = sex; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b0d, 7>(ss, fixed_0d); + } } break; + } case 0x2726: // Request to send a broadcast message (no answer) - if (RFIFOREST(ls) < 8 - || RFIFOREST(ls) < (8 + RFIFOL(ls, 4))) - return; - if (RFIFOL(ls, 4) < 1) - CHAR_LOG("Receiving a message for broadcast, but message is void.\n"); + { + Packet_Head<0x2726> head; + AString repeat; + rv = recv_vpacket<0x2726, 8, 1>(ls, head, repeat); + if (rv != RecvResult::Complete) + break; + + if (!repeat) + CHAR_LOG("Receiving a message for broadcast, but message is void.\n"_fmt); else { int i; @@ -1330,82 +1417,100 @@ void parse_tologin(Session *ls) if (server_session[i]) break; if (i == MAX_MAP_SERVERS) - CHAR_LOG("'ladmin': Receiving a message for broadcast, but no map-server is online.\n"); + CHAR_LOG("'ladmin': Receiving a message for broadcast, but no map-server is online.\n"_fmt); else { - size_t len = RFIFOL(ls, 4); - AString message = RFIFO_STRING(ls, 8, len).to_print().lstrip(); + AString message = repeat.to_print().lstrip(); // if message is only composed of spaces if (!message) - CHAR_LOG("Receiving a message for broadcast, but message is only a lot of spaces.\n"); + CHAR_LOG("Receiving a message for broadcast, but message is only a lot of spaces.\n"_fmt); // else send message to all map-servers else { - CHAR_LOG("'ladmin': Receiving a message for broadcast (message (in yellow): %s)\n", + CHAR_LOG("'ladmin': Receiving a message for broadcast (message (in yellow): %s)\n"_fmt, message); // send broadcast to all map-servers - uint8_t buf[4 + len]; - WBUFW(buf, 0) = 0x3800; - WBUFW(buf, 2) = 4 + len; - WBUF_STRING(buf, 4, message, len); - mapif_sendall(buf, WBUFW(buf, 2)); + for (Session *ss : iter_map_sessions()) + { + send_packet_repeatonly<0x3800, 4, 1>(ss, message); + } } } } - RFIFOSKIP(ls, 8 + RFIFOL(ls, 4)); break; + } // account_reg2変更通知 case 0x2729: - if (RFIFOREST(ls) < 4 || RFIFOREST(ls) < RFIFOW(ls, 2)) - return; + { + Packet_Head<0x2729> head; + std::vector<Packet_Repeat<0x2729>> repeat; + rv = recv_vpacket<0x2729, 8, 36>(ls, head, repeat); + if (rv != RecvResult::Complete) + break; + { - Array<struct global_reg, ACCOUNT_REG2_NUM> reg; - int j, p, acc; - acc = RFIFOL(ls, 4); - for (p = 8, j = 0; - p < RFIFOW(ls, 2) && j < ACCOUNT_REG2_NUM; - p += 36, j++) + Array<GlobalReg, ACCOUNT_REG2_NUM> reg; + int j = 0; + AccountId acc = head.account_id; + for (const auto& info : repeat) + { + reg[j].str = info.name; + reg[j].value = info.value; + ++j; + if (j == ACCOUNT_REG2_NUM) + break; + } + set_account_reg2(acc, Slice<GlobalReg>(reg.begin(), j)); + + Packet_Head<0x2b11> head_11; + head_11.account_id = head.account_id; + std::vector<Packet_Repeat<0x2b11>> repeat_11(repeat.size()); + for (size_t k = 0; k < repeat.size(); ++k) + { + repeat_11[k].name = repeat[k].name; + repeat_11[k].value = repeat[k].value; + } + for (Session *ss : iter_map_sessions()) { - reg[j].str = stringish<VarName>(RFIFO_STRING<32>(ls, p)); - reg[j].value = RFIFOL(ls, p + 32); + send_vpacket<0x2b11, 8, 36>(ss, head_11, repeat_11); } - set_account_reg2(acc, Slice<struct global_reg>(reg.begin(), j)); - - size_t len = RFIFOW(ls, 2); - uint8_t buf[len]; - RFIFO_BUF_CLONE(ls, buf, len); - WBUFW(buf, 0) = 0x2b11; - mapif_sendall(buf, len); -// PRINTF("char: save_account_reg_reply\n"); } - RFIFOSKIP(ls, RFIFOW(ls, 2)); break; + } case 0x7924: { // [Fate] Itemfrob package: forwarded from login-server - if (RFIFOREST(ls) < 10) - return; - int source_id = RFIFOL(ls, 2); - int dest_id = RFIFOL(ls, 6); - unsigned char buf[10]; + Packet_Fixed<0x7924> fixed; + rv = recv_fpacket<0x7924, 10>(ls, fixed); + if (rv != RecvResult::Complete) + break; + + ItemNameId source_id = fixed.source_item_id; + ItemNameId dest_id = fixed.dest_item_id; + + Packet_Fixed<0x2afa> fixed_fa; + fixed_fa.source_item_id = source_id; + fixed_fa.dest_item_id = dest_id; - WBUFW(buf, 0) = 0x2afa; - WBUFL(buf, 2) = source_id; - WBUFL(buf, 6) = dest_id; + // forward package to map servers + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2afa, 10>(ss, fixed_fa); + } - mapif_sendall(buf, 10); // forward package to map servers for (CharPair& cp : char_keys) { CharKey *k = &cp.key; CharData& cd = *cp.data.get(); CharData *c = &cd; - struct storage *s = account2storage(k->account_id); + Storage *s = account2storage(k->account_id); int changes = 0; - int j; #define FIX(v) if (v == source_id) {v = dest_id; ++changes; } - for (j = 0; j < MAX_INVENTORY; j++) + for (IOff0 j : IOff0::iter()) + { FIX(c->inventory[j].nameid); + } // used to FIX cart, but it's no longer supported // FIX(c->weapon); FIX(c->shield); @@ -1414,26 +1519,35 @@ void parse_tologin(Session *ls) FIX(c->head_bottom); if (s) - for (j = 0; j < s->storage_amount; j++) + { + for (SOff0 j : SOff0::iter()) + { FIX(s->storage_[j].nameid); + } + } #undef FIX if (changes) - CHAR_LOG("itemfrob(%d -> %d): `%s'(%d, account %d): changed %d times\n", - source_id, dest_id, k->name, k->char_id, - k->account_id, changes); + CHAR_LOG("itemfrob(%d -> %d): `%s'(%d, account %d): changed %d times\n"_fmt, + source_id, dest_id, k->name, k->char_id, + k->account_id, changes); } mmo_char_sync(); inter_storage_save(); - RFIFOSKIP(ls, 10); break; } // Account deletion notification (from login-server) case 0x2730: - if (RFIFOREST(ls) < 6) - return; + { + Packet_Fixed<0x2730> fixed; + rv = recv_fpacket<0x2730, 6>(ls, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId aid = fixed.account_id; + // Deletion of all characters of the account //#warning "This comment is a lie, but it's still true." // needs to use index because they may move during resize @@ -1441,7 +1555,7 @@ void parse_tologin(Session *ls) { CharPair& cp = char_keys[idx]; CharKey& ck = cp.key; - if (ck.account_id == RFIFOL(ls, 2)) + if (ck.account_id == aid) { char_delete(&cp); if (&cp != &char_keys.back()) @@ -1450,7 +1564,7 @@ void parse_tologin(Session *ls) // if moved character owns to deleted account, check again it's character // YES this is the newly swapped one // we could avoid this by working backwards - if (ck.account_id == RFIFOL(ls, 2)) + if (ck.account_id == aid) { idx--; // Correct moved character reference in the character's owner by [Yor] @@ -1460,69 +1574,91 @@ void parse_tologin(Session *ls) } } // Deletion of the storage - inter_storage_delete(RFIFOL(ls, 2)); + inter_storage_delete(aid); // send to all map-servers to disconnect the player { - unsigned char buf[6]; - WBUFW(buf, 0) = 0x2b13; - WBUFL(buf, 2) = RFIFOL(ls, 2); - mapif_sendall(buf, 6); + Packet_Fixed<0x2b13> fixed_13; + fixed_13.account_id = aid; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b13, 6>(ss, fixed_13); + } } // disconnect player if online on char-server - disconnect_player(RFIFOL(ls, 2)); - RFIFOSKIP(ls, 6); + disconnect_player(aid); break; + } // State change of account/ban notification (from login-server) by [Yor] case 0x2731: - if (RFIFOREST(ls) < 11) - return; + { + Packet_Fixed<0x2731> fixed; + rv = recv_fpacket<0x2731, 11>(ls, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId aid = fixed.account_id; // send to all map-servers to disconnect the player { - unsigned char buf[11]; - WBUFW(buf, 0) = 0x2b14; - WBUFL(buf, 2) = RFIFOL(ls, 2); - WBUFB(buf, 6) = RFIFOB(ls, 6); // 0: change of statut, 1: ban - WBUFL(buf, 7) = RFIFOL(ls, 7); // status or final date of a banishment - mapif_sendall(buf, 11); + Packet_Fixed<0x2b14> fixed_14; + fixed_14.account_id = aid; + fixed_14.ban_not_status = fixed.ban_not_status; // 0: change of statut, 1: ban + fixed_14.status_or_ban_until = fixed.status_or_ban_until; // status or final date of a banishment + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b14, 11>(ss, fixed_14); + } } // disconnect player if online on char-server - disconnect_player(RFIFOL(ls, 2)); - RFIFOSKIP(ls, 11); + disconnect_player(aid); break; + } // Receiving GM acounts info from login-server (by [Yor]) case 0x2732: - if (RFIFOREST(ls) < 4 || RFIFOREST(ls) < RFIFOW(ls, 2)) - return; + { + std::vector<Packet_Repeat<0x2732>> repeat; + rv = recv_packet_repeatonly<0x2732, 4, 5>(ls, repeat); + if (rv != RecvResult::Complete) + break; + { - size_t len = RFIFOW(ls, 2); - uint8_t buf[len]; - gm_accounts.clear(); - gm_accounts.reserve((len - 4) / 5); - for (int i = 4; i < len; i += 5) + gm_accounts.resize(repeat.size()); + for (size_t k = 0; k < repeat.size(); ++k) { - gm_accounts.push_back({static_cast<int>(RFIFOL(ls, i)), RFIFOB(ls, i + 4)}); + gm_accounts[k].account_id = repeat[k].account_id; + gm_accounts[k].level = repeat[k].gm_level; } - PRINTF("From login-server: receiving of %zu GM accounts information.\n", - gm_accounts.size()); - CHAR_LOG("From login-server: receiving of %zu GM accounts information.\n", - gm_accounts.size()); + PRINTF("From login-server: receiving of %zu GM accounts information.\n"_fmt, + gm_accounts.size()); + CHAR_LOG("From login-server: receiving of %zu GM accounts information.\n"_fmt, + gm_accounts.size()); create_online_files(); // update online players files (perhaps some online players change of GM level) // send new gm acccounts level to map-servers - RFIFO_BUF_CLONE(ls, buf, len); - WBUFW(buf, 0) = 0x2b15; - mapif_sendall(buf, len); + std::vector<Packet_Repeat<0x2b15>> repeat_15(repeat.size()); + for (size_t k = 0; k < repeat.size(); ++k) + { + repeat_15[k].account_id = repeat[k].account_id; + repeat_15[k].gm_level = repeat[k].gm_level; + } + for (Session *ss : iter_map_sessions()) + { + send_packet_repeatonly<0x2b15, 4, 5>(ss, repeat_15); + } } - RFIFOSKIP(ls, RFIFOW(ls, 2)); break; + } case 0x2741: // change password reply - if (RFIFOREST(ls) < 7) - return; + { + Packet_Fixed<0x2741> fixed; + rv = recv_fpacket<0x2741, 7>(ls, fixed); + if (rv != RecvResult::Complete) + break; + { - int acc = RFIFOL(ls, 2); - int status = RFIFOB(ls, 6); + AccountId acc = fixed.account_id; + int status = fixed.status; for (io::FD i : iter_fds()) { @@ -1534,22 +1670,26 @@ void parse_tologin(Session *ls) { if (sd->account_id == acc) { - WFIFOW(s2, 0) = 0x62; - WFIFOB(s2, 2) = status; - WFIFOSET(s2, 3); + Packet_Fixed<0x0062> fixed_62; + fixed_62.status = status; + send_fpacket<0x0062, 3>(s2, fixed_62); break; } } } } - RFIFOSKIP(ls, 7); break; + } default: + { ls->set_eof(); return; + } } } + if (rv == RecvResult::Error) + ls->set_eof(); } //-------------------------------- @@ -1560,18 +1700,16 @@ void map_anti_freeze_system(TimerData *, tick_t) { int i; - //PRINTF("Entering in map_anti_freeze_system function to check freeze of servers.\n"); for (i = 0; i < MAX_MAP_SERVERS; i++) { if (server_session[i]) { // if map-server is online - //PRINTF("map_anti_freeze_system: server #%d, flag: %d.\n", i, server_freezeflag[i]); if (server_freezeflag[i]-- < 1) { // Map-server anti-freeze system. Counter. 5 ok, 4...0 freezed - PRINTF("Map-server anti-freeze system: char-server #%d is freezed -> disconnection.\n", - i); - CHAR_LOG("Map-server anti-freeze system: char-server #%d is freezed -> disconnection.\n", - i); + PRINTF("Map-server anti-freeze system: char-server #%d is freezed -> disconnection.\n"_fmt, + i); + CHAR_LOG("Map-server anti-freeze system: char-server #%d is freezed -> disconnection.\n"_fmt, + i); server_session[i]->set_eof(); } } @@ -1591,102 +1729,125 @@ void parse_frommap(Session *ms) return; } - while (RFIFOREST(ms) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(ms, &packet_id)) { -// PRINTF("parse_frommap: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd)); - - switch (RFIFOW(ms, 0)) + switch (packet_id) { // request from map-server to reload GM accounts. Transmission to login-server (by Yor) case 0x2af7: + { + Packet_Fixed<0x2af7> fixed; + rv = recv_fpacket<0x2af7, 2>(ms, fixed); + if (rv != RecvResult::Complete) + break; + if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2709; - WFIFOSET(login_session, 2); + Packet_Fixed<0x2709> fixed_09; + send_fpacket<0x2709, 2>(login_session, fixed_09); } - RFIFOSKIP(ms, 2); break; + } // Receiving map names list from the map-server case 0x2afa: - if (RFIFOREST(ms) < 4 || RFIFOREST(ms) < RFIFOW(ms, 2)) - return; { + std::vector<Packet_Repeat<0x2afa>> repeat; + rv = recv_packet_repeatonly<0x2afa, 4, 16>(ms, repeat); + if (rv != RecvResult::Complete) + break; + for (MapName &foo : server[id].maps) foo = MapName(); - int j = 0; - for (int i = 4; i < RFIFOW(ms, 2); i += 16) + + for (size_t j = 0; j < repeat.size(); ++j) { - server[id].maps[j] = RFIFO_STRING<16>(ms, i); - j++; + server[id].maps[j] = repeat[j].map_name; } + const size_t j = repeat.size(); + { - PRINTF("Map-Server %d connected: %d maps, from IP %s port %d.\n", - id, j, server[id].ip, server[id].port); - PRINTF("Map-server %d loading complete.\n", id); - CHAR_LOG("Map-Server %d connected: %d maps, from IP %s port %d. Map-server %d loading complete.\n", - id, j, server[id].ip, - server[id].port, id); + PRINTF("Map-Server %d connected: %zu maps, from IP %s port %d.\n"_fmt, + id, j, server[id].ip, server[id].port); + PRINTF("Map-server %d loading complete.\n"_fmt, id); + CHAR_LOG("Map-Server %d connected: %zu maps, from IP %s port %d. Map-server %d loading complete.\n"_fmt, + id, j, server[id].ip, + server[id].port, id); } - WFIFOW(ms, 0) = 0x2afb; - WFIFOB(ms, 2) = 0; - WFIFO_STRING(ms, 3, wisp_server_name.to__actual(), 24); - WFIFOSET(ms, 27); + + Packet_Fixed<0x2afb> fixed_fb; + fixed_fb.unknown = 0; + fixed_fb.whisper_name = wisp_server_name; + send_fpacket<0x2afb, 27>(ms, fixed_fb); + { - unsigned char buf[16384]; if (j == 0) { - PRINTF("WARNING: Map-Server %d have NO map.\n", id); - CHAR_LOG("WARNING: Map-Server %d have NO map.\n", - id); + PRINTF("WARNING: Map-Server %d have NO map.\n"_fmt, id); + CHAR_LOG("WARNING: Map-Server %d have NO map.\n"_fmt, + id); // Transmitting maps information to the other map-servers } else { - WBUFW(buf, 0) = 0x2b04; - WBUFW(buf, 2) = j * 16 + 10; - WBUFIP(buf, 4) = server[id].ip; - WBUFW(buf, 8) = server[id].port; - // server[id].maps[i] = RFIFO_STRING(fd, 4 + i * 16) + Packet_Head<0x2b04> head_04; + head_04.ip = server[id].ip; + head_04.port = server[id].port; + std::vector<Packet_Repeat<0x2b04>> repeat_04(j); for (int i = 0; i < j; ++i) - WBUF_STRING(buf, 10, server[id].maps[i], 16); - mapif_sendallwos(ms, buf, WBUFW(buf, 2)); + { + repeat_04[i].map_name = server[id].maps[i]; + } + for (Session *ss : iter_map_sessions()) + { + if (ss == ms) + continue; + send_vpacket<0x2b04, 10, 16>(ss, head_04, repeat_04); + } } // Transmitting the maps of the other map-servers to the new map-server for (int x = 0; x < MAX_MAP_SERVERS; x++) { if (server_session[x] && x != id) { - WFIFOW(ms, 0) = 0x2b04; - WFIFOIP(ms, 4) = server[x].ip; - WFIFOW(ms, 8) = server[x].port; - j = 0; + Packet_Head<0x2b04> head_04; + head_04.ip = server[x].ip; + head_04.port = server[x].port; + std::vector<Packet_Repeat<0x2b04>> repeat_04; for (int i = 0; i < MAX_MAP_PER_SERVER; i++) + { if (server[x].maps[i]) - WFIFO_STRING(ms, 10 + (j++) * 16, server[x].maps[i], 16); - if (j > 0) + { + Packet_Repeat<0x2b04> info; + info.map_name = server[x].maps[i]; + repeat_04.push_back(info); + } + } + if (repeat.size()) { - WFIFOW(ms, 2) = j * 16 + 10; - WFIFOSET(ms, WFIFOW(ms, 2)); + send_vpacket<0x2b04, 10, 16>(ms, head_04, repeat_04); } } } } - } - RFIFOSKIP(ms, RFIFOW(ms, 2)); break; + } // 認証要求 case 0x2afc: - if (RFIFOREST(ms) < 22) - return; { - int account_id = RFIFOL(ms, 2); - int char_id = RFIFOL(ms, 6); - int login_id1 = RFIFOL(ms, 10); - int login_id2 = RFIFOL(ms, 14); - IP4Address ip = RFIFOIP(ms, 18); - //PRINTF("auth_fifo search: account: %d, char: %d, secure: %08x-%08x\n", RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14)); + Packet_Fixed<0x2afc> fixed; + rv = recv_fpacket<0x2afc, 22>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + CharId char_id = fixed.char_id; + int login_id1 = fixed.login_id1; + int login_id2 = fixed.login_id2; + IP4Address ip = fixed.ip; for (AuthFifoEntry& afi : auth_fifo) { if (afi.account_id == account_id && @@ -1706,46 +1867,49 @@ void parse_frommap(Session *ms) break; } } - assert (cp && "uh-oh - deleted while in queue?"); + assert (cp && "uh-oh - deleted while in queue?"_s); CharKey *ck = &cp->key; CharData *cd = cp->data.get(); afi.delflag = 1; - WFIFOW(ms, 0) = 0x2afd; - WFIFOW(ms, 2) = 18 + sizeof(*ck) + sizeof(*cd); - WFIFOL(ms, 4) = account_id; - WFIFOL(ms, 8) = afi.login_id2; - WFIFOL(ms, 12) = static_cast<time_t>(afi.connect_until_time); + Packet_Payload<0x2afd> payload_fd; // not file descriptor + payload_fd.account_id = account_id; + payload_fd.login_id2 = afi.login_id2; + payload_fd.connect_until = afi.connect_until_time; cd->sex = afi.sex; - WFIFOW(ms, 16) = afi.packet_tmw_version; + payload_fd.packet_tmw_version = afi.packet_tmw_version; FPRINTF(stderr, - "From queue index %zd: recalling packet version %d\n", - (&afi - &auth_fifo.front()), afi.packet_tmw_version); - WFIFO_STRUCT(ms, 18, *ck); - WFIFO_STRUCT(ms, 18 + sizeof(*ck), *cd); - WFIFOSET(ms, WFIFOW(ms, 2)); - //PRINTF("auth_fifo search success (auth #%d, account %d, character: %d).\n", i, RFIFOL(fd,2), RFIFOL(fd,6)); + "From queue index %zd: recalling packet version %d\n"_fmt, + (&afi - &auth_fifo.front()), afi.packet_tmw_version); + payload_fd.char_key = *ck; + payload_fd.char_data = *cd; + send_ppacket<0x2afd>(ms, payload_fd); goto x2afc_out; } } { - WFIFOW(ms, 0) = 0x2afe; - WFIFOL(ms, 2) = account_id; - WFIFOSET(ms, 6); - PRINTF("auth_fifo search error! account %d not authentified.\n", + Packet_Fixed<0x2afe> fixed_fe; + fixed_fe.account_id = account_id; + send_fpacket<0x2afe, 6>(ms, fixed_fe); + PRINTF("auth_fifo search error! account %d not authentified.\n"_fmt, account_id); } - } x2afc_out: - RFIFOSKIP(ms, 22); break; + } // MAPサーバー上のユーザー数受信 case 0x2aff: - if (RFIFOREST(ms) < 6 || RFIFOREST(ms) < RFIFOW(ms, 2)) - return; - server[id].users = RFIFOW(ms, 4); + { + Packet_Head<0x2aff> head; + std::vector<Packet_Repeat<0x2aff>> repeat; + rv = recv_vpacket<0x2aff, 6, 4>(ms, head, repeat); + if (rv != RecvResult::Complete) + break; + + server[id].users = head.users; + assert (head.users == repeat.size()); if (anti_freeze_enable) server_freezeflag[id] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed // remove all previously online players of the server @@ -1758,7 +1922,7 @@ void parse_frommap(Session *ms) // add online players in the list by [Yor] for (int i = 0; i < server[id].users; i++) { - int char_id = RFIFOL(ms, 6 + i * 4); + CharId char_id = repeat[i].char_id; for (const CharPair& cd : char_keys) { if (cd.key.char_id == char_id) @@ -1776,306 +1940,374 @@ void parse_frommap(Session *ms) // only every 8 sec. (normally, 1 server send users every 5 sec.) Don't update every time, because that takes time, but only every 2 connection. // it set to 8 sec because is more than 5 (sec) and if we have more than 1 map-server, informations can be received in shifted. } - RFIFOSKIP(ms, RFIFOW(ms, 2)); break; + } // キャラデータ保存 case 0x2b01: - if (RFIFOREST(ms) < 4 || RFIFOREST(ms) < RFIFOW(ms, 2)) - return; + { + Packet_Payload<0x2b01> payload; + rv = recv_ppacket<0x2b01>(ms, payload); + if (rv != RecvResult::Complete) + break; + + AccountId aid = payload.account_id; + CharId cid = payload.char_id; for (CharPair& cd : char_keys) { - if (cd.key.account_id == RFIFOL(ms, 4) && - cd.key.char_id == RFIFOL(ms, 8)) + if (cd.key.account_id == aid && + cd.key.char_id == cid) { - RFIFO_STRUCT(ms, 12, cd.key); - RFIFO_STRUCT(ms, 12 + sizeof(cd.key), *cd.data); + cd.key = payload.char_key; + *cd.data = payload.char_data; break; } } - RFIFOSKIP(ms, RFIFOW(ms, 2)); break; + } // キャラセレ要求 case 0x2b02: - if (RFIFOREST(ms) < 18) - return; { - int account_id = RFIFOL(ms, 2); + Packet_Fixed<0x2b02> fixed; + rv = recv_fpacket<0x2b02, 18>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; if (auth_fifo_iter == auth_fifo.end()) auth_fifo_iter = auth_fifo.begin(); auth_fifo_iter->account_id = account_id; - auth_fifo_iter->char_id = 0; - auth_fifo_iter->login_id1 = RFIFOL(ms, 6); - auth_fifo_iter->login_id2 = RFIFOL(ms, 10); + auth_fifo_iter->char_id = CharId(); + auth_fifo_iter->login_id1 = fixed.login_id1; + auth_fifo_iter->login_id2 = fixed.login_id2; auth_fifo_iter->delflag = 2; auth_fifo_iter->connect_until_time = TimeT(); // unlimited/unknown time by default (not display in map-server) - auth_fifo_iter->ip = RFIFOIP(ms, 14); + auth_fifo_iter->ip = fixed.ip; auth_fifo_iter++; - WFIFOW(ms, 0) = 0x2b03; - WFIFOL(ms, 2) = account_id; - WFIFOB(ms, 6) = 0; - WFIFOSET(ms, 7); - } - RFIFOSKIP(ms, 18); + + Packet_Fixed<0x2b03> fixed_03; + fixed_03.account_id = account_id; + fixed_03.unknown = 0; + send_fpacket<0x2b03, 7>(ms, fixed_03); break; + } // マップサーバー間移動要求 case 0x2b05: - if (RFIFOREST(ms) < 49) - return; + { + Packet_Fixed<0x2b05> fixed; + rv = recv_fpacket<0x2b05, 49>(ms, fixed); + if (rv != RecvResult::Complete) + break; + if (auth_fifo_iter == auth_fifo.end()) auth_fifo_iter = auth_fifo.begin(); - RFIFO_WFIFO_CLONE(ms, ms, 44); - // overwrite - WFIFOW(ms, 0) = 0x2b06; - auth_fifo_iter->account_id = RFIFOL(ms, 2); - auth_fifo_iter->char_id = RFIFOL(ms, 14); - auth_fifo_iter->login_id1 = RFIFOL(ms, 6); - auth_fifo_iter->login_id2 = RFIFOL(ms, 10); + Packet_Fixed<0x2b06> fixed_06; + fixed_06.account_id = fixed.account_id; + //fixed_06.error = fixed.login_id1; + //fixed_06.unknown = fixed.login_id2; + fixed_06.char_id = fixed.char_id; + fixed_06.map_name = fixed.map_name; + fixed_06.x = fixed.x; + fixed_06.y = fixed.y; + fixed_06.map_ip = fixed.map_ip; + fixed_06.map_port = fixed.map_port; + + auth_fifo_iter->account_id = fixed.account_id; + auth_fifo_iter->login_id1 = fixed.login_id1; + auth_fifo_iter->login_id2 = fixed.login_id2; + auth_fifo_iter->char_id = fixed.char_id; auth_fifo_iter->delflag = 0; - auth_fifo_iter->sex = static_cast<SEX>(RFIFOB(ms, 44)); + auth_fifo_iter->sex = fixed.sex; auth_fifo_iter->connect_until_time = TimeT(); // unlimited/unknown time by default (not display in map-server) - auth_fifo_iter->ip = RFIFOIP(ms, 45); + auth_fifo_iter->ip = fixed.client_ip; // default, if not found in the loop - WFIFOW(ms, 6) = 1; + fixed_06.error = 1; for (const CharPair& cd : char_keys) - if (cd.key.account_id == RFIFOL(ms, 2) && - cd.key.char_id == RFIFOL(ms, 14)) + { + AccountId aid = fixed.account_id; + CharId cid = fixed.char_id; + if (cd.key.account_id == aid && + cd.key.char_id == cid) { auth_fifo_iter++; - WFIFOL(ms, 6) = 0; + fixed_06.error = 0; break; } - WFIFOSET(ms, 44); - RFIFOSKIP(ms, 49); + } + send_fpacket<0x2b06, 44>(ms, fixed_06); break; + } // it is a request to become GM case 0x2b0a: - if (RFIFOREST(ms) < 4 || RFIFOREST(ms) < RFIFOW(ms, 2)) - return; { - int account_id = RFIFOL(ms, 4); + Packet_Head<0x2b0a> head; + AString repeat; + rv = recv_vpacket<0x2b0a, 8, 1>(ms, head, repeat); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = head.account_id; if (login_session) { // don't send request if no login-server - size_t len = RFIFOW(ms, 2); - RFIFO_WFIFO_CLONE(ms, login_session, len); - WFIFOW(login_session, 0) = 0x2720; - WFIFOSET(login_session, len); + Packet_Head<0x2720> head_20; + head_20.account_id = account_id; + AString& repeat_20 = repeat; + send_vpacket<0x2720, 8, 1>(login_session, head_20, repeat_20); } else { - WFIFOW(ms, 0) = 0x2b0b; - WFIFOL(ms, 2) = account_id; - WFIFOL(ms, 6) = 0; - WFIFOSET(ms, 10); + Packet_Fixed<0x2b0b> fixed_0b; + fixed_0b.account_id = account_id; + fixed_0b.gm_level = GmLevel(); + send_fpacket<0x2b0b, 10>(ms, fixed_0b); } - } - RFIFOSKIP(ms, RFIFOW(ms, 2)); break; + } // Map server send information to change an email of an account -> login-server case 0x2b0c: - if (RFIFOREST(ms) < 86) - return; + { + Packet_Fixed<0x2b0c> fixed; + rv = recv_fpacket<0x2b0c, 86>(ms, fixed); + if (rv != RecvResult::Complete) + break; + if (login_session) { // don't send request if no login-server - RFIFO_WFIFO_CLONE(ms, login_session, 86); // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B - WFIFOW(login_session, 0) = 0x2722; - WFIFOSET(login_session, 86); + Packet_Fixed<0x2722> fixed_22; + fixed_22.account_id = fixed.account_id; + fixed_22.old_email = fixed.old_email; + fixed_22.new_email = fixed.new_email; + send_fpacket<0x2722, 86>(login_session, fixed_22); } - RFIFOSKIP(ms, 86); break; + } // Map server ask char-server about a character name to do some operations (all operations are transmitted to login-server) case 0x2b0e: - if (RFIFOREST(ms) < 44) - return; + { + Packet_Fixed<0x2b0e> fixed; + rv = recv_fpacket<0x2b0e, 44>(ms, fixed); + if (rv != RecvResult::Complete) + break; + { - int acc = RFIFOL(ms, 2); // account_id of who ask (-1 if nobody) - CharName character_name = stringish<CharName>(RFIFO_STRING<24>(ms, 6)); - int operation = RFIFOW(ms, 30); + AccountId acc = fixed.account_id; + CharName character_name = fixed.char_name; + int operation = fixed.operation; // prepare answer - WFIFOW(ms, 0) = 0x2b0f; // answer - WFIFOL(ms, 2) = acc; // who want do operation - WFIFOW(ms, 30) = operation; // type of operation: 1-block, 2-ban, 3-unblock, 4-unban, 5-changesex + Packet_Fixed<0x2b0f> fixed_0f; + fixed_0f.account_id = acc; + fixed_0f.operation = operation; // search character const CharPair *cd = search_character(character_name); + // TODO invert the below logic to shrink this code + // Current logic: + // 1. if no character, return error 1 + // 2. else if gm level too low, return error 2 + // 3. else if login server offline, return error 3 + // 4. else return error 0 and maybe do other stuff if (cd) { const CharKey *ck = &cd->key; - WFIFO_STRING(ms, 6, ck->name.to__actual(), 24); // put correct name if found - WFIFOW(ms, 32) = 0; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline - switch (RFIFOW(ms, 30)) + fixed_0f.char_name = ck->name; + fixed_0f.error = 0; + switch (operation) { case 1: // block - if (acc == -1 - || isGM(acc) >= isGM(ck->account_id)) + { + if (!acc + || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2724; - WFIFOL(login_session, 2) = ck->account_id; // account value - WFIFOL(login_session, 6) = 5; // status of the account - WFIFOSET(login_session, 10); + Packet_Fixed<0x2724> fixed_24; + fixed_24.account_id = ck->account_id; + fixed_24.status = 5; + send_fpacket<0x2724, 10>(login_session, fixed_24); } else - WFIFOW(ms, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 3; } else - WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 2; break; + } case 2: // ban - if (acc == -1 - || isGM(acc) >= isGM(ck->account_id)) + { + if (!acc + || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2725; - WFIFOL(login_session, 2) = ck->account_id; // account value - HumanTimeDiff ban_change; - RFIFO_STRUCT(ms, 32, ban_change); - WFIFO_STRUCT(login_session, 6, ban_change); - WFIFOSET(login_session, 18); + Packet_Fixed<0x2725> fixed_25; + fixed_25.account_id = ck->account_id; + HumanTimeDiff ban_change = fixed.ban_add; + fixed_25.ban_add = ban_change; + send_fpacket<0x2725, 18>(login_session, fixed_25); } else - WFIFOW(ms, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 3; } else - WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 2; break; + } case 3: // unblock - if (acc == -1 - || isGM(acc) >= isGM(ck->account_id)) + { + if (!acc + || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2724; - WFIFOL(login_session, 2) = ck->account_id; // account value - WFIFOL(login_session, 6) = 0; // status of the account - WFIFOSET(login_session, 10); + Packet_Fixed<0x2724> fixed_24; + fixed_24.account_id = ck->account_id; + fixed_24.status = 0; + send_fpacket<0x2724, 10>(login_session, fixed_24); } else - WFIFOW(ms, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 3; } else - WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 2; break; + } case 4: // unban - if (acc == -1 - || isGM(acc) >= isGM(ck->account_id)) + { + if (!acc + || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x272a; - WFIFOL(login_session, 2) = ck->account_id; // account value - WFIFOSET(login_session, 6); + Packet_Fixed<0x272a> fixed_2a; + fixed_2a.account_id = ck->account_id; + send_fpacket<0x272a, 6>(login_session, fixed_2a); } else - WFIFOW(ms, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 3; } else - WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 2; break; + } case 5: // changesex - if (acc == -1 - || isGM(acc) >= isGM(ck->account_id)) + { + if (!acc + || isGM(acc).overwhelms(isGM(ck->account_id))) { if (login_session) { // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2727; - WFIFOL(login_session, 2) = ck->account_id; // account value - WFIFOSET(login_session, 6); + Packet_Fixed<0x2727> fixed_27; + fixed_27.account_id = ck->account_id; + send_fpacket<0x2727, 6>(login_session, fixed_27); } else - WFIFOW(ms, 32) = 3; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 3; } else - WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.error = 2; break; + } } } else { // character name not found - WFIFO_STRING(ms, 6, character_name.to__actual(), 24); - WFIFOW(ms, 32) = 1; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline + fixed_0f.char_name = character_name; + fixed_0f.error = 1; } // send answer if a player ask, not if the server ask - if (acc != -1) + if (acc) { - WFIFOSET(ms, 34); + send_fpacket<0x2b0f, 34>(ms, fixed_0f); } - RFIFOSKIP(ms, 44); break; } - -// case 0x2b0f: not more used (available for futur usage) + } // account_reg保存要求 case 0x2b10: - if (RFIFOREST(ms) < 4 || RFIFOREST(ms) < RFIFOW(ms, 2)) - return; + { + Packet_Head<0x2b10> head; + std::vector<Packet_Repeat<0x2b10>> repeat; + rv = recv_vpacket<0x2b10, 8, 36>(ms, head, repeat); + if (rv != RecvResult::Complete) + break; + { - Array<struct global_reg, ACCOUNT_REG2_NUM> reg; - int p, j; - int acc = RFIFOL(ms, 4); - for (p = 8, j = 0; - p < RFIFOW(ms, 2) && j < ACCOUNT_REG2_NUM; - p += 36, j++) + Array<GlobalReg, ACCOUNT_REG2_NUM> reg; + AccountId acc = head.account_id; + auto jlim = std::min(repeat.size(), ACCOUNT_REG2_NUM); + for (size_t j = 0; j < jlim; ++j) { - reg[j].str = stringish<VarName>(RFIFO_STRING<32>(ms, p)); - reg[j].value = RFIFOL(ms, p + 32); + reg[j].str = repeat[j].name; + reg[j].value = repeat[j].value; } - set_account_reg2(acc, Slice<struct global_reg>(reg.begin(), j)); + set_account_reg2(acc, Slice<GlobalReg>(reg.begin(), jlim)); // loginサーバーへ送る if (login_session) { // don't send request if no login-server - RFIFO_WFIFO_CLONE(ms, login_session, RFIFOW(ms, 2)); - WFIFOW(login_session, 0) = 0x2728; - WFIFOSET(login_session, WFIFOW(login_session, 2)); + Packet_Head<0x2728> head_28; + std::vector<Packet_Repeat<0x2728>> repeat_28(repeat.size()); + for (size_t j = 0; j < repeat.size(); ++j) + { + repeat_28[j].name = repeat[j].name; + repeat_28[j].value = repeat[j].value; + } + send_vpacket<0x2728, 8, 36>(login_session, head_28, repeat_28); } - RFIFOSKIP(ms, RFIFOW(ms, 2)); break; } + } // Map server is requesting a divorce case 0x2b16: - if (RFIFOREST(ms) < 4) - return; + { + Packet_Fixed<0x2b16> fixed; + rv = recv_fpacket<0x2b16, 6>(ms, fixed); + if (rv != RecvResult::Complete) + break; + { + CharId cid = fixed.char_id; for (CharPair& cd : char_keys) - if (cd.key.char_id == RFIFOL(ms, 2)) + { + if (cd.key.char_id == cid) { char_divorce(&cd); break; } + } - RFIFOSKIP(ms, 6); break; } + } default: // inter server処理に渡す { - int r = inter_parse_frommap(ms); - if (r == 1) // 処理できた + RecvResult r = inter_parse_frommap(ms, packet_id); + if (r == RecvResult::Complete) break; - if (r == 2) // パケット長が足りない + if (r == RecvResult::Incomplete) return; - } // inter server処理でもない場合は切断 - PRINTF("char: unknown packet 0x%04x (%zu bytes to read in buffer)! (from map).\n", - RFIFOW(ms, 0), RFIFOREST(ms)); + PRINTF("char: unknown packet 0x%04x (%zu bytes to read in buffer)! (from map).\n"_fmt, + packet_id, packet_avail(ms)); ms->set_eof(); return; + } } } + if (rv == RecvResult::Error) + ms->set_eof(); } static @@ -2104,8 +2336,8 @@ int lan_ip_check(IP4Address addr) { bool lancheck = lan_subnet.covers(addr); - PRINTF("LAN test (result): %s.\n", - (lancheck) ? SGR_BOLD SGR_CYAN "LAN source" SGR_RESET : SGR_BOLD SGR_GREEN "WAN source" SGR_RESET); + PRINTF("LAN test (result): %s.\n"_fmt, + (lancheck) ? SGR_BOLD SGR_CYAN "LAN source" SGR_RESET ""_s : SGR_BOLD SGR_GREEN "WAN source" SGR_RESET ""_s); return lancheck; } @@ -2127,9 +2359,9 @@ void handle_x0066(Session *s, struct char_session_data *sd, uint8_t rfifob_2, IP CharKey *ck = &cp->key; CharData *cd = cp->data.get(); - CHAR_LOG("Character Selected, Account ID: %d, Character Slot: %d, Character Name: %s [%s]\n", - sd->account_id, rfifob_2, - ck->name, ip); + CHAR_LOG("Character Selected, Account ID: %d, Character Slot: %d, Character Name: %s [%s]\n"_fmt, + sd->account_id, rfifob_2, + ck->name, ip); // searching map server int i = search_mapserver(cd->last_point.map_); // if map is not found, we check major cities @@ -2144,33 +2376,35 @@ void handle_x0066(Session *s, struct char_session_data *sd, uint8_t rfifob_2, IP { // change save point to one of map found on the server (the first) i = j; cd->last_point.map_ = server[j].maps[0]; - PRINTF("Map-server #%d found with a map: '%s'.\n", - j, server[j].maps[0]); + PRINTF("Map-server #%d found with a map: '%s'.\n"_fmt, + j, server[j].maps[0]); // coordonates are unknown break; } // if no map-server is connected, we send: server closed if (j == MAX_MAP_SERVERS) { - WFIFOW(s, 0) = 0x81; - WFIFOB(s, 2) = 1; // 01 = Server closed - WFIFOSET(s, 3); + Packet_Fixed<0x0081> fixed_81; + fixed_81.error_code = 1; + send_fpacket<0x0081, 3>(s, fixed_81); return; } } - WFIFOW(s, 0) = 0x71; - WFIFOL(s, 2) = ck->char_id; - WFIFO_STRING(s, 6, cd->last_point.map_, 16); - PRINTF("Character selection '%s' (account: %d, slot: %d) [%s]\n", - ck->name, - sd->account_id, ck->char_num, ip); - PRINTF("--Send IP of map-server. "); + + Packet_Fixed<0x0071> fixed_71; + fixed_71.char_id = ck->char_id; + fixed_71.map_name = cd->last_point.map_; + PRINTF("Character selection '%s' (account: %d, slot: %d) [%s]\n"_fmt, + ck->name, + sd->account_id, ck->char_num, ip); + PRINTF("--Send IP of map-server. "_fmt); if (lan_ip_check(ip)) - WFIFOIP(s, 22) = lan_map_ip; + fixed_71.ip = lan_map_ip; else - WFIFOIP(s, 22) = server[i].ip; - WFIFOW(s, 26) = server[i].port; - WFIFOSET(s, 28); + fixed_71.ip = server[i].ip; + fixed_71.port = server[i].port; + send_fpacket<0x0071, 28>(s, fixed_71); + if (auth_fifo_iter == auth_fifo.end()) auth_fifo_iter = auth_fifo.begin(); auth_fifo_iter->account_id = sd->account_id; @@ -2192,73 +2426,75 @@ void parse_char(Session *s) { IP4Address ip = s->client_ip; + assert (s != login_session); + if (!login_session) { s->set_eof(); - - // I sure *hope* this doesn't happen ... - if (s == login_session) - login_session = nullptr; return; } char_session_data *sd = static_cast<char_session_data *>(s->session_data.get()); - while (RFIFOREST(s) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id)) { -// if (RFIFOW(fd,0) < 30000) -// PRINTF("parse_char: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd)); - - switch (RFIFOW(s, 0)) + switch (packet_id) { - case 0x20b: //20040622暗号化ragexe対応 - if (RFIFOREST(s) < 19) - return; - RFIFOSKIP(s, 19); - break; - case 0x61: // change password request - if (RFIFOREST(s) < 50) - return; + { + Packet_Fixed<0x0061> fixed; + rv = recv_fpacket<0x0061, 50>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - WFIFOW(login_session, 0) = 0x2740; - WFIFOL(login_session, 2) = sd->account_id; - AccountPass old_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 2)); - WFIFO_STRING(login_session, 6, old_pass, 24); - AccountPass new_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 26)); - WFIFO_STRING(login_session, 30, new_pass, 24); - WFIFOSET(login_session, 54); + Packet_Fixed<0x2740> fixed_40; + fixed_40.account_id = sd->account_id; + AccountPass old_pass = fixed.old_pass; + fixed_40.old_pass = old_pass; + AccountPass new_pass = fixed.new_pass; + fixed_40.new_pass = new_pass; + send_fpacket<0x2740, 54>(login_session, fixed_40); } - RFIFOSKIP(s, 50); break; + } case 0x65: // 接続要求 - if (RFIFOREST(s) < 17) - return; + { + Packet_Fixed<0x0065> fixed; + rv = recv_fpacket<0x0065, 17>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - int account_id = RFIFOL(s, 2); - int GM_value = isGM(account_id); + AccountId account_id = fixed.account_id; + GmLevel GM_value = isGM(account_id); if (GM_value) - PRINTF("Account Logged On; Account ID: %d (GM level %d).\n", + PRINTF("Account Logged On; Account ID: %d (GM level %d).\n"_fmt, account_id, GM_value); else - PRINTF("Account Logged On; Account ID: %d.\n", + PRINTF("Account Logged On; Account ID: %d.\n"_fmt, account_id); - if (sd == NULL) + if (sd == nullptr) { s->session_data = make_unique<char_session_data, SessionDeleter>(); sd = static_cast<char_session_data *>(s->session_data.get()); - sd->email = stringish<AccountEmail>("no mail"); // put here a mail without '@' to refuse deletion if we don't receive the e-mail + sd->email = stringish<AccountEmail>("no mail"_s); // put here a mail without '@' to refuse deletion if we don't receive the e-mail sd->connect_until_time = TimeT(); // unknow or illimited (not displaying on map-server) } sd->account_id = account_id; - sd->login_id1 = RFIFOL(s, 6); - sd->login_id2 = RFIFOL(s, 10); - sd->packet_tmw_version = RFIFOW(s, 14); - sd->sex = static_cast<SEX>(RFIFOB(s, 16)); - // send back account_id - WFIFOL(s, 0) = account_id; - WFIFOSET(s, 4); + sd->login_id1 = fixed.login_id1; + sd->login_id2 = fixed.login_id2; + sd->packet_tmw_version = fixed.packet_tmw_version; + sd->sex = fixed.sex; + + // formerly: send back account_id + Packet_Payload<0x8000> special; + special.magic_packet_length = 4; + send_ppacket<0x8000>(s, special); + // search authentification for (AuthFifoEntry& afi : auth_fifo) { @@ -2273,12 +2509,12 @@ void parse_char(Session *s) if (max_connect_user == 0 || count_users() < max_connect_user) { - if (login_session) - { // don't send request if no login-server + { + // there is always a login server // request to login-server to obtain e-mail/time limit - WFIFOW(login_session, 0) = 0x2716; - WFIFOL(login_session, 2) = sd->account_id; - WFIFOSET(login_session, 6); + Packet_Fixed<0x2716> fixed_16; + fixed_16.account_id = sd->account_id; + send_fpacket<0x2716, 6>(login_session, fixed_16); } // Record client version afi.packet_tmw_version = @@ -2289,126 +2525,153 @@ void parse_char(Session *s) else { // refuse connection (over populated) - WFIFOW(s, 0) = 0x6c; - WFIFOB(s, 2) = 0; - WFIFOSET(s, 3); + Packet_Fixed<0x006c> fixed_6c; + fixed_6c.code = 0; + send_fpacket<0x006c, 3>(s, fixed_6c); } goto x65_out; } } // authentification not found { - if (login_session) { - // don't send request if no login-server - WFIFOW(login_session, 0) = 0x2712; // ask login-server to authentify an account - WFIFOL(login_session, 2) = sd->account_id; - WFIFOL(login_session, 6) = sd->login_id1; - WFIFOL(login_session, 10) = sd->login_id2; // relate to the versions higher than 18 - WFIFOB(login_session, 14) = static_cast<uint8_t>(sd->sex); - WFIFOIP(login_session, 15) = s->client_ip; - WFIFOSET(login_session, 19); - } - else - { // if no login-server, we must refuse connection - WFIFOW(s, 0) = 0x6c; - WFIFOB(s, 2) = 0; - WFIFOSET(s, 3); + // there is always a login-server + Packet_Fixed<0x2712> fixed_12; + fixed_12.account_id = sd->account_id; + fixed_12.login_id1 = sd->login_id1; + fixed_12.login_id2 = sd->login_id2; // relate to the versions higher than 18 + fixed_12.sex = sd->sex; + fixed_12.ip = s->client_ip; + send_fpacket<0x2712, 19>(login_session, fixed_12); } } } x65_out: - RFIFOSKIP(s, 17); break; + } case 0x66: // キャラ選択 - if (!sd || RFIFOREST(s) < 3) + { + Packet_Fixed<0x0066> fixed; + rv = recv_fpacket<0x0066, 3>(s, fixed); + if (rv != RecvResult::Complete) + break; + + if (!sd) + { + s->set_eof(); return; - handle_x0066(s, sd, RFIFOB(s, 2), ip); - RFIFOSKIP(s, 3); + } + handle_x0066(s, sd, fixed.code, ip); break; + } case 0x67: // 作成 - if (!sd || RFIFOREST(s) < 37) - return; { - CharName name = stringish<CharName>(RFIFO_STRING<24>(s, 2)); - uint8_t stats[6]; - for (int i = 0; i < 6; ++i) - stats[i] = RFIFOB(s, 26 + i); - uint8_t slot = RFIFOB(s, 32); - uint16_t hair_color = RFIFOW(s, 33); - uint16_t hair_style = RFIFOW(s, 35); + Packet_Fixed<0x0067> fixed; + rv = recv_fpacket<0x0067, 37>(s, fixed); + if (rv != RecvResult::Complete) + break; + + if (!sd) + { + s->set_eof(); + return; + } + CharName name = fixed.char_name; + Stats6 stats = fixed.stats; + uint8_t slot = fixed.slot; + uint16_t hair_color = fixed.hair_color; + uint16_t hair_style = fixed.hair_style; const CharPair *cp = make_new_char(s, name, stats, slot, hair_color, hair_style); if (!cp) { - WFIFOW(s, 0) = 0x6e; - WFIFOB(s, 2) = 0x00; - WFIFOSET(s, 3); - RFIFOSKIP(s, 37); + Packet_Fixed<0x006e> fixed_6e; + fixed_6e.code = 0x00; + send_fpacket<0x006e, 3>(s, fixed_6e); break; } const CharKey *ck = &cp->key; const CharData *cd = cp->data.get(); - WFIFOW(s, 0) = 0x6d; - WFIFO_ZERO(s, 2, 106); - - WFIFOL(s, 2) = ck->char_id; - WFIFOL(s, 2 + 4) = cd->base_exp; - WFIFOL(s, 2 + 8) = cd->zeny; - WFIFOL(s, 2 + 12) = cd->job_exp; - WFIFOL(s, 2 + 16) = cd->job_level; - - WFIFOL(s, 2 + 28) = cd->karma; - WFIFOL(s, 2 + 32) = cd->manner; - - WFIFOW(s, 2 + 40) = 0x30; - WFIFOW(s, 2 + 42) = min(cd->hp, 0x7fff); - WFIFOW(s, 2 + 44) = min(cd->max_hp, 0x7fff); - WFIFOW(s, 2 + 46) = min(cd->sp, 0x7fff); - WFIFOW(s, 2 + 48) = min(cd->max_sp, 0x7fff); - WFIFOW(s, 2 + 50) = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // cd->speed; - WFIFOW(s, 2 + 52) = cd->species; - WFIFOW(s, 2 + 54) = cd->hair; - - WFIFOW(s, 2 + 58) = cd->base_level; - WFIFOW(s, 2 + 60) = cd->skill_point; - - WFIFOW(s, 2 + 64) = cd->shield; - WFIFOW(s, 2 + 66) = cd->head_top; - WFIFOW(s, 2 + 68) = cd->head_mid; - WFIFOW(s, 2 + 70) = cd->hair_color; - - WFIFO_STRING(s, 2 + 74, ck->name.to__actual(), 24); - - WFIFOB(s, 2 + 98) = min(cd->attrs[ATTR::STR], 255); - WFIFOB(s, 2 + 99) = min(cd->attrs[ATTR::AGI], 255); - WFIFOB(s, 2 + 100) = min(cd->attrs[ATTR::VIT], 255); - WFIFOB(s, 2 + 101) = min(cd->attrs[ATTR::INT], 255); - WFIFOB(s, 2 + 102) = min(cd->attrs[ATTR::DEX], 255); - WFIFOB(s, 2 + 103) = min(cd->attrs[ATTR::LUK], 255); - WFIFOB(s, 2 + 104) = ck->char_num; - - WFIFOSET(s, 108); - } - RFIFOSKIP(s, 37); + Packet_Fixed<0x006d> fixed_6d; + + fixed_6d.char_select.char_id = ck->char_id; + fixed_6d.char_select.base_exp = cd->base_exp; + fixed_6d.char_select.zeny = cd->zeny; + fixed_6d.char_select.job_exp = cd->job_exp; + fixed_6d.char_select.job_level = cd->job_level; + + fixed_6d.char_select.shoes = ItemNameId(); + fixed_6d.char_select.gloves = ItemNameId(); + fixed_6d.char_select.cape = ItemNameId(); + fixed_6d.char_select.misc1 = ItemNameId(); + fixed_6d.char_select.option = Option(); + fixed_6d.char_select.unused = 0; + + // this was buggy until the protocol became generated + // but the client ignores it anyway + fixed_6d.char_select.karma = cd->karma; + fixed_6d.char_select.manner = cd->manner; + + fixed_6d.char_select.status_point = 0x30; + fixed_6d.char_select.hp = saturate<int16_t>(cd->hp); + fixed_6d.char_select.max_hp = saturate<int16_t>(cd->max_hp); + fixed_6d.char_select.sp = saturate<int16_t>(cd->sp); + fixed_6d.char_select.max_sp = saturate<int16_t>(cd->max_sp); + fixed_6d.char_select.speed = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // cd->speed; + fixed_6d.char_select.species = cd->species; + fixed_6d.char_select.hair_style = cd->hair; + fixed_6d.char_select.weapon = 0; + + fixed_6d.char_select.base_level = cd->base_level; + fixed_6d.char_select.skill_point = cd->skill_point; + + fixed_6d.char_select.head_bottom = ItemNameId(); + fixed_6d.char_select.shield = cd->shield; + fixed_6d.char_select.head_top = cd->head_top; + fixed_6d.char_select.head_mid = cd->head_mid; + fixed_6d.char_select.hair_color = cd->hair_color; + fixed_6d.char_select.misc2 = ItemNameId(); + + fixed_6d.char_select.char_name = ck->name; + + fixed_6d.char_select.stats.str = saturate<uint8_t>(cd->attrs[ATTR::STR]); + fixed_6d.char_select.stats.agi = saturate<uint8_t>(cd->attrs[ATTR::AGI]); + fixed_6d.char_select.stats.vit = saturate<uint8_t>(cd->attrs[ATTR::VIT]); + fixed_6d.char_select.stats.int_ = saturate<uint8_t>(cd->attrs[ATTR::INT]); + fixed_6d.char_select.stats.dex = saturate<uint8_t>(cd->attrs[ATTR::DEX]); + fixed_6d.char_select.stats.luk = saturate<uint8_t>(cd->attrs[ATTR::LUK]); + fixed_6d.char_select.char_num = ck->char_num; + fixed_6d.char_select.unused2 = 0; + + send_fpacket<0x006d, 108>(s, fixed_6d); break; + } case 0x68: // delete char //Yor's Fix - if (!sd || RFIFOREST(s) < 46) - return; { - AccountEmail email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 6)); + Packet_Fixed<0x0068> fixed; + rv = recv_fpacket<0x0068, 46>(s, fixed); + if (rv != RecvResult::Complete) + break; + + if (!sd) + { + s->set_eof(); + return; + } + AccountEmail email = fixed.email; if (!e_mail_check(email)) email = DEFAULT_EMAIL; { { + CharId cid = fixed.char_id; CharPair *cs = nullptr; for (CharPair& cd : char_keys) { - if (cd.key.char_id == RFIFOL(s, 2)) + if (cd.key.char_id == cid) { if (cd.key.account_id == sd->account_id) cs = &cd; @@ -2426,176 +2689,129 @@ void parse_char(Session *s) } char_keys.pop_back(); - WFIFOW(s, 0) = 0x6f; - WFIFOSET(s, 2); + Packet_Fixed<0x006f> fixed_6f; + send_fpacket<0x006f, 2>(s, fixed_6f); goto x68_out; } } { - WFIFOW(s, 0) = 0x70; - WFIFOB(s, 2) = 0; - WFIFOSET(s, 3); + Packet_Fixed<0x0070> fixed_70; + fixed_70.code = 0; + send_fpacket<0x0070, 3>(s, fixed_70); } } - } x68_out: - RFIFOSKIP(s, 46); break; + } case 0x2af8: // マップサーバーログイン - if (RFIFOREST(s) < 60) - return; { + Packet_Fixed<0x2af8> fixed; + rv = recv_fpacket<0x2af8, 60>(s, fixed); + if (rv != RecvResult::Complete) + break; + int i; - WFIFOW(s, 0) = 0x2af9; + Packet_Fixed<0x2af9> fixed_f9; for (i = 0; i < MAX_MAP_SERVERS; i++) { if (!server_session[i]) break; } - AccountName userid_ = stringish<AccountName>(RFIFO_STRING<24>(s, 2)); - AccountPass passwd_ = stringish<AccountPass>(RFIFO_STRING<24>(s, 26)); + AccountName userid_ = fixed.account_name; + AccountPass passwd_ = fixed.account_pass; if (i == MAX_MAP_SERVERS || userid_ != userid || passwd_ != passwd) { - WFIFOB(s, 2) = 3; - WFIFOSET(s, 3); - RFIFOSKIP(s, 60); + fixed_f9.code = 3; + send_fpacket<0x2af9, 3>(s, fixed_f9); } else { - int len; - WFIFOB(s, 2) = 0; - s->set_parsers(SessionParsers{func_parse: parse_frommap, func_delete: delete_frommap}); + fixed_f9.code = 0; + s->set_parsers(SessionParsers{.func_parse= parse_frommap, .func_delete= delete_frommap}); server_session[i] = s; if (anti_freeze_enable) server_freezeflag[i] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed - // ignore RFIFOL(fd, 50) - server[i].ip = RFIFOIP(s, 54); - server[i].port = RFIFOW(s, 58); + // ignore fixed.unknown + server[i].ip = fixed.ip; + server[i].port = fixed.port; server[i].users = 0; for (MapName& mapi : server[i].maps) mapi = MapName(); - WFIFOSET(s, 3); - RFIFOSKIP(s, 60); + send_fpacket<0x2af9, 3>(s, fixed_f9); realloc_fifo(s, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); // send gm acccounts level to map-servers - len = 4; - WFIFOW(s, 0) = 0x2b15; + std::vector<Packet_Repeat<0x2b15>> repeat_15(gm_accounts.size()); + auto it = repeat_15.begin(); for (const GM_Account& gma : gm_accounts) { - WFIFOL(s, len) = gma.account_id; - WFIFOB(s, len + 4) = gma.level; - len += 5; + it->account_id = gma.account_id; + it->gm_level = gma.level; + ++it; } - WFIFOW(s, 2) = len; - WFIFOSET(s, len); + send_packet_repeatonly<0x2b15, 4, 5>(s, repeat_15); + // justification: we switched the session parsers + parse_frommap(s); return; } - } - break; - - case 0x187: // Alive信号? - if (RFIFOREST(s) < 6) - return; - RFIFOSKIP(s, 6); break; + } case 0x7530: // Athena情報所得 - WFIFOW(s, 0) = 0x7531; - WFIFO_STRUCT(s, 2, CURRENT_CHAR_SERVER_VERSION); - WFIFOSET(s, 10); - RFIFOSKIP(s, 2); - return; + { + Packet_Fixed<0x7530> fixed; + rv = recv_fpacket<0x7530, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x7531> fixed_31; + fixed_31.version = CURRENT_CHAR_SERVER_VERSION; + send_fpacket<0x7531, 10>(s, fixed_31); + break; + } case 0x7532: // 接続の切断(defaultと処理は一緒だが明示的にするため) + { + Packet_Fixed<0x7532> fixed; + rv = recv_fpacket<0x7532, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + s->set_eof(); return; + } default: s->set_eof(); return; } } -} - -// 全てのMAPサーバーにデータ送信(送信したmap鯖の数を返す) -int mapif_sendall(const uint8_t *buf, unsigned int len) -{ - int i, c; - - c = 0; - for (i = 0; i < MAX_MAP_SERVERS; i++) - { - Session *s = server_session[i]; - if (s) - { - WFIFO_BUF_CLONE(s, buf, len); - WFIFOSET(s, len); - c++; - } - } - return c; -} - -// 自分以外の全てのMAPサーバーにデータ送信(送信したmap鯖の数を返す) -int mapif_sendallwos(Session *ss, const uint8_t *buf, unsigned int len) -{ - int i, c; - - c = 0; - for (i = 0; i < MAX_MAP_SERVERS; i++) - { - Session *s = server_session[i]; - if (s && s != ss) - { - WFIFO_BUF_CLONE(s, buf, len); - WFIFOSET(s, len); - c++; - } - } - return c; -} - -// MAPサーバーにデータ送信(map鯖生存確認有り) -int mapif_send(Session *s, const uint8_t *buf, unsigned int len) -{ - int i; - - if (s) - { - for (i = 0; i < MAX_MAP_SERVERS; i++) - { - if (s == server_session[i]) - { - WFIFO_BUF_CLONE(s, buf, len); - WFIFOSET(s, len); - return 1; - } - } - } - return 0; + if (rv == RecvResult::Error) + s->set_eof(); } static void send_users_tologin(TimerData *, tick_t) { int users = count_users(); - uint8_t buf[16]; if (login_session) { // send number of user to login server - WFIFOW(login_session, 0) = 0x2714; - WFIFOL(login_session, 2) = users; - WFIFOSET(login_session, 6); + Packet_Fixed<0x2714> fixed_14; + fixed_14.users = users; + send_fpacket<0x2714, 6>(login_session, fixed_14); } // send number of players to all map-servers - WBUFW(buf, 0) = 0x2b00; - WBUFL(buf, 2) = users; - mapif_sendall(buf, 6); + Packet_Fixed<0x2b00> fixed_00; + fixed_00.users = users; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x2b00, 6>(ss, fixed_00); + } } static @@ -2603,24 +2819,24 @@ void check_connect_login_server(TimerData *, tick_t) { if (!login_session) { - PRINTF("Attempt to connect to login-server...\n"); + PRINTF("Attempt to connect to login-server...\n"_fmt); login_session = make_connection(login_ip, login_port, - SessionParsers{func_parse: parse_tologin, func_delete: delete_tologin}); + SessionParsers{.func_parse= parse_tologin, .func_delete= delete_tologin}); if (!login_session) return; realloc_fifo(login_session, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); - WFIFOW(login_session, 0) = 0x2710; - WFIFO_ZERO(login_session, 2, 24); - WFIFO_STRING(login_session, 2, userid, 24); - WFIFO_STRING(login_session, 26, passwd, 24); - WFIFOL(login_session, 50) = 0; - WFIFOIP(login_session, 54) = char_ip; - WFIFOL(login_session, 58) = char_port; - WFIFO_STRING(login_session, 60, server_name, 20); - WFIFOW(login_session, 80) = 0; - WFIFOW(login_session, 82) = 0; //char_maintenance; - WFIFOW(login_session, 84) = 0; //char_new; - WFIFOSET(login_session, 86); + + Packet_Fixed<0x2710> fixed_10; + fixed_10.account_name = userid; + fixed_10.account_pass = passwd; + fixed_10.unknown = 0; + fixed_10.ip = char_ip; + fixed_10.port = char_port; + fixed_10.server_name = server_name; + fixed_10.unknown2 = 0; + fixed_10.maintenance = 0; + fixed_10.is_new = 0; + send_fpacket<0x2710, 86>(login_session, fixed_10); } } @@ -2630,14 +2846,14 @@ void check_connect_login_server(TimerData *, tick_t) static bool char_lan_config(XString w1, ZString w2) { - struct hostent *h = NULL; + struct hostent *h = nullptr; { - if (w1 == "lan_map_ip") + if (w1 == "lan_map_ip"_s) { // Read map-server Lan IP Address h = gethostbyname(w2.c_str()); - if (h != NULL) + if (h != nullptr) { lan_map_ip = IP4Address({ static_cast<uint8_t>(h->h_addr[0]), @@ -2648,20 +2864,20 @@ bool char_lan_config(XString w1, ZString w2) } else { - PRINTF("Bad IP value: %s\n", w2); + PRINTF("Bad IP value: %s\n"_fmt, w2); return false; } - PRINTF("LAN IP of map-server: %s.\n", lan_map_ip); + PRINTF("LAN IP of map-server: %s.\n"_fmt, lan_map_ip); } - else if (w1 == "subnet" /*backward compatibility*/ - || w1 == "lan_subnet") + else if (w1 == "subnet"_s /*backward compatibility*/ + || w1 == "lan_subnet"_s) { if (!extract(w2, &lan_subnet)) { - PRINTF("Bad IP mask: %s\n", w2); + PRINTF("Bad IP mask: %s\n"_fmt, w2); return false; } - PRINTF("Sub-network of the map-server: %s.\n", + PRINTF("Sub-network of the map-server: %s.\n"_fmt, lan_subnet); } else @@ -2677,10 +2893,10 @@ bool lan_check() { // sub-network check of the map-server { - PRINTF("LAN test of LAN IP of the map-server: "); + PRINTF("LAN test of LAN IP of the map-server: "_fmt); if (!lan_ip_check(lan_map_ip)) { - PRINTF(SGR_BOLD SGR_RED "***ERROR: LAN IP of the map-server doesn't belong to the specified Sub-network." SGR_RESET "\n"); + PRINTF(SGR_BOLD SGR_RED "***ERROR: LAN IP of the map-server doesn't belong to the specified Sub-network." SGR_RESET "\n"_fmt); return false; } } @@ -2691,27 +2907,27 @@ bool lan_check() static bool char_config(XString w1, ZString w2) { - struct hostent *h = NULL; + struct hostent *h = nullptr; { - if (w1 == "userid") + if (w1 == "userid"_s) userid = stringish<AccountName>(w2); - else if (w1 == "passwd") + else if (w1 == "passwd"_s) passwd = stringish<AccountPass>(w2); - else if (w1 == "server_name") + else if (w1 == "server_name"_s) { server_name = stringish<ServerName>(w2); - PRINTF("%s server has been intialized\n", w2); + PRINTF("%s server has been intialized\n"_fmt, w2); } - else if (w1 == "wisp_server_name") + else if (w1 == "wisp_server_name"_s) { if (w2.size() >= 4) wisp_server_name = stringish<CharName>(w2); } - else if (w1 == "login_ip") + else if (w1 == "login_ip"_s) { h = gethostbyname(w2.c_str()); - if (h != NULL) + if (h != nullptr) { login_ip = IP4Address({ static_cast<uint8_t>(h->h_addr[0]), @@ -2719,23 +2935,23 @@ bool char_config(XString w1, ZString w2) static_cast<uint8_t>(h->h_addr[2]), static_cast<uint8_t>(h->h_addr[3]), }); - PRINTF("Login server IP address : %s -> %s\n", + PRINTF("Login server IP address : %s -> %s\n"_fmt, w2, login_ip); } else { - PRINTF("Bad IP value: %s\n", w2); + PRINTF("Bad IP value: %s\n"_fmt, w2); return false; } } - else if (w1 == "login_port") + else if (w1 == "login_port"_s) { login_port = atoi(w2.c_str()); } - else if (w1 == "char_ip") + else if (w1 == "char_ip"_s) { h = gethostbyname(w2.c_str()); - if (h != NULL) + if (h != nullptr) { char_ip = IP4Address({ static_cast<uint8_t>(h->h_addr[0]), @@ -2743,56 +2959,56 @@ bool char_config(XString w1, ZString w2) static_cast<uint8_t>(h->h_addr[2]), static_cast<uint8_t>(h->h_addr[3]), }); - PRINTF("Character server IP address : %s -> %s\n", + PRINTF("Character server IP address : %s -> %s\n"_fmt, w2, char_ip); } else { - PRINTF("Bad IP value: %s\n", w2); + PRINTF("Bad IP value: %s\n"_fmt, w2); return false; } } - else if (w1 == "char_port") + else if (w1 == "char_port"_s) { char_port = atoi(w2.c_str()); } - else if (w1 == "char_txt") + else if (w1 == "char_txt"_s) { char_txt = w2; } - else if (w1 == "max_connect_user") + else if (w1 == "max_connect_user"_s) { max_connect_user = atoi(w2.c_str()); if (max_connect_user < 0) max_connect_user = 0; // unlimited online players } - else if (w1 == "check_ip_flag") + else if (w1 == "check_ip_flag"_s) { check_ip_flag = config_switch(w2); } - else if (w1 == "autosave_time") + else if (w1 == "autosave_time"_s) { autosave_time = std::chrono::seconds(atoi(w2.c_str())); if (autosave_time <= std::chrono::seconds::zero()) autosave_time = DEFAULT_AUTOSAVE_INTERVAL; } - else if (w1 == "start_point") + else if (w1 == "start_point"_s) { extract(w2, &start_point); } - else if (w1 == "unknown_char_name") + else if (w1 == "unknown_char_name"_s) { unknown_char_name = stringish<CharName>(w2); } - else if (w1 == "char_log_filename") + else if (w1 == "char_log_filename"_s) { char_log_filename = w2; } - else if (w1 == "char_name_option") + else if (w1 == "char_name_option"_s) { char_name_option = atoi(w2.c_str()); } - else if (w1 == "char_name_letters") + else if (w1 == "char_name_letters"_s) { if (!w2) char_name_letters.reset(); @@ -2800,39 +3016,38 @@ bool char_config(XString w1, ZString w2) for (uint8_t c : w2) char_name_letters[c] = true; } - else if (w1 == "online_txt_filename") + else if (w1 == "online_txt_filename"_s) { online_txt_filename = w2; } - else if (w1 == "online_html_filename") + else if (w1 == "online_html_filename"_s) { online_html_filename = w2; } - else if (w1 == "online_sorting_option") + else if (w1 == "online_sorting_option"_s) { online_sorting_option = atoi(w2.c_str()); } - else if (w1 == "online_gm_display_min_level") - { // minimum GM level to display 'GM' when we want to display it - online_gm_display_min_level = atoi(w2.c_str()); - if (online_gm_display_min_level < 5) // send online file every 5 seconds to player is enough - online_gm_display_min_level = 5; + else if (w1 == "online_gm_display_min_level"_s) + { + // minimum GM level to display 'GM' when we want to display it + return extract(w2, &online_gm_display_min_level); } - else if (w1 == "online_refresh_html") + else if (w1 == "online_refresh_html"_s) { online_refresh_html = atoi(w2.c_str()); if (online_refresh_html < 1) online_refresh_html = 1; } - else if (w1 == "anti_freeze_enable") + else if (w1 == "anti_freeze_enable"_s) { anti_freeze_enable = config_switch(w2); } - else if (w1 == "anti_freeze_interval") + else if (w1 == "anti_freeze_interval"_s) { anti_freeze_interval = std::max( std::chrono::seconds(atoi(w2.c_str())), - std::chrono::seconds(5)); + 5_s); } else { @@ -2859,7 +3074,7 @@ void term_func(void) delete_session(login_session); delete_session(char_session); - CHAR_LOG("----End of char-server (normal end with closing of all files).\n"); + CHAR_LOG("----End of char-server (normal end with closing of all files).\n"_fmt); } static @@ -2884,20 +3099,20 @@ int do_init(Slice<ZString> argv) ZString argvi = argv.pop_front(); if (argvi.startswith('-')) { - if (argvi == "--help") + if (argvi == "--help"_s) { - PRINTF("Usage: %s [--help] [--version] [files...]\n", + PRINTF("Usage: %s [--help] [--version] [files...]\n"_fmt, argv0); exit(0); } - else if (argvi == "--version") + else if (argvi == "--version"_s) { - PRINTF("%s\n", CURRENT_VERSION_STRING); + PRINTF("%s\n"_fmt, CURRENT_VERSION_STRING); exit(0); } else { - FPRINTF(stderr, "Unknown argument: %s\n", argvi); + FPRINTF(stderr, "Unknown argument: %s\n"_fmt, argvi); runflag = false; } } @@ -2909,11 +3124,11 @@ int do_init(Slice<ZString> argv) } if (!loaded_config_yet) - runflag &= load_config_file("conf/tmwa-char.conf", char_confs); + runflag &= load_config_file("conf/tmwa-char.conf"_s, char_confs); // a newline in the log... - CHAR_LOG(""); - CHAR_LOG("The char-server starting...\n"); + CHAR_LOG(""_fmt); + CHAR_LOG("The char-server starting...\n"_fmt); runflag &= lan_check(); @@ -2925,13 +3140,13 @@ int do_init(Slice<ZString> argv) char_session = make_listen_port(char_port, SessionParsers{parse_char, delete_char}); - Timer(gettick() + std::chrono::seconds(1), + Timer(gettick() + 1_s, check_connect_login_server, - std::chrono::seconds(10) + 10_s ).detach(); - Timer(gettick() + std::chrono::seconds(1), + Timer(gettick() + 1_s, send_users_tologin, - std::chrono::seconds(5) + 5_s ).detach(); Timer(gettick() + autosave_time, mmo_char_sync_timer, @@ -2940,17 +3155,18 @@ int do_init(Slice<ZString> argv) if (anti_freeze_enable > 0) { - Timer(gettick() + std::chrono::seconds(1), + Timer(gettick() + 1_s, map_anti_freeze_system, anti_freeze_interval ).detach(); } - CHAR_LOG("The char-server is ready (Server is listening on the port %d).\n", - char_port); + CHAR_LOG("The char-server is ready (Server is listening on the port %d).\n"_fmt, + char_port); - PRINTF("The char-server is " SGR_BOLD SGR_GREEN "ready" SGR_RESET " (Server is listening on the port %d).\n\n", - char_port); + PRINTF("The char-server is " SGR_BOLD SGR_GREEN "ready" SGR_RESET " (Server is listening on the port %d).\n\n"_fmt, + char_port); return 0; } +} // namespace tmwa diff --git a/src/char/char.hpp b/src/char/char.hpp index 4c11073..a9c786f 100644 --- a/src/char/char.hpp +++ b/src/char/char.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_CHAR_CHAR_HPP -#define TMWA_CHAR_CHAR_HPP +#pragma once // char.hpp - Character server. // // Copyright © ????-2004 Athena Dev Teams @@ -21,15 +20,19 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "../mmo/ip.hpp" -# include "../mmo/mmo.hpp" +#include "../generic/array.hpp" -struct Session; +#include "../net/ip.hpp" +#include "../mmo/mmo.hpp" + + +namespace tmwa +{ constexpr int MAX_MAP_SERVERS = 30; struct mmo_map_server @@ -41,16 +44,13 @@ struct mmo_map_server }; const CharPair *search_character(CharName character_name); -const CharPair *search_character_id(int char_id); +const CharPair *search_character_id(CharId char_id); Session *server_for(const CharPair *mcs); -int mapif_sendall(const uint8_t *buf, unsigned int len); -int mapif_sendallwos(Session *s, const uint8_t *buf, unsigned int len); -int mapif_send(Session *s, const uint8_t *buf, unsigned int len); +auto iter_map_sessions() -> decltype(filter_iterator<Session *>(std::declval<Array<Session *, MAX_MAP_SERVERS> *>())); void char_log(XString line); -# define CHAR_LOG(fmt, ...) \ +#define CHAR_LOG(fmt, ...) \ char_log(STRPRINTF(fmt, ## __VA_ARGS__)) - -#endif // TMWA_CHAR_CHAR_HPP +} // namespace tmwa diff --git a/src/char/fwd.hpp b/src/char/fwd.hpp new file mode 100644 index 0000000..31cd1ba --- /dev/null +++ b/src/char/fwd.hpp @@ -0,0 +1,27 @@ +#pragma once +// char/fwd.hpp - list of type names for char server +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +// meh, add more when I feel like it +} // namespace tmwa diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp index c9965dc..c9ab5a4 100644 --- a/src/char/int_party.cpp +++ b/src/char/int_party.cpp @@ -20,8 +20,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <cstdlib> -#include <cstring> +#include "../ints/udl.hpp" #include "../strings/mstring.hpp" #include "../strings/astring.hpp" @@ -32,50 +31,58 @@ #include "../io/cxxstdio.hpp" #include "../io/lock.hpp" #include "../io/read.hpp" +#include "../io/write.hpp" + +#include "../net/packets.hpp" + +#include "../proto2/char-map.hpp" #include "../mmo/extract.hpp" +#include "../mmo/ids.hpp" #include "../mmo/mmo.hpp" -#include "../mmo/socket.hpp" #include "char.hpp" #include "inter.hpp" #include "../poison.hpp" -AString party_txt = "save/party.txt"; + +namespace tmwa +{ +AString party_txt = "save/party.txt"_s; static -Map<int, struct party> party_db; +Map<PartyId, PartyMost> party_db; static -int party_newid = 100; +PartyId party_newid = wrap<PartyId>(100_u32); static -void mapif_party_broken(int party_id, int flag); +void mapif_party_broken(PartyId party_id, int flag); static -int party_check_empty(struct party *p); +int party_check_empty(PartyPair p); static -void mapif_parse_PartyLeave(Session *s, int party_id, int account_id); +void mapif_parse_PartyLeave(Session *s, PartyId party_id, AccountId account_id); // パーティデータの文字列への変換 static -AString inter_party_tostr(struct party *p) +AString inter_party_tostr(PartyPair p) { MString str; str += STRPRINTF( "%d\t" "%s\t" - "%d,%d\t", - p->party_id, + "%d,%d\t"_fmt, + p.party_id, p->name, p->exp, p->item); for (int i = 0; i < MAX_PARTY; i++) { - struct party_member *m = &p->member[i]; + PartyMember *m = &p->member[i]; if (!m->account_id) continue; str += STRPRINTF( "%d,%d\t" - "%s\t", + "%s\t"_fmt, m->account_id, m->leader, m->name); } @@ -84,9 +91,9 @@ AString inter_party_tostr(struct party *p) } static -bool extract(XString str, party *p) +bool extract(XString str, PartyPair *pp) { - *p = party(); + PartyPair& p = *pp; // not compatible with the normal extract()ors since it has // a variable-size element that uses the same separator @@ -95,7 +102,7 @@ bool extract(XString str, party *p) return false; auto begin = bits.begin(); auto end = bits.end(); - if (begin == end || !extract(*begin, &p->party_id)) + if (begin == end || !extract(*begin, &p.party_id)) return false; ++begin; if (begin == end || !extract(*begin, &p->name)) @@ -107,7 +114,7 @@ bool extract(XString str, party *p) for (int i = 0; begin != end && i < MAX_PARTY; ++i) { - struct party_member *m = &p->member[i]; + PartyMember *m = &p->member[i]; if (begin == end || !extract(*begin, record<','>(&m->account_id, &m->leader))) return false; @@ -123,7 +130,7 @@ bool extract(XString str, party *p) } static -void party_check_deleted_init(struct party *p) +void party_check_deleted_init(PartyPair p) { for (int i = 0; i < MAX_PARTY; i++) { @@ -132,13 +139,13 @@ void party_check_deleted_init(struct party *p) const CharPair *c = search_character(p->member[i].name); if (!c || c->key.account_id != p->member[i].account_id) { - CHAR_LOG("WARNING: deleting obsolete party member %d %s of %d %s\n", + CHAR_LOG("WARNING: deleting obsolete party member %d %s of %d %s\n"_fmt, p->member[i].account_id, p->member[i].name, - p->party_id, p->name); - PRINTF("WARNING: deleting obsolete party member %d %s of %d %s\n", + p.party_id, p->name); + PRINTF("WARNING: deleting obsolete party member %d %s of %d %s\n"_fmt, p->member[i].account_id, p->member[i].name, - p->party_id, p->name); - p->member[i] = party_member{}; + p.party_id, p->name); + p->member[i] = PartyMember{}; } } } @@ -150,31 +157,33 @@ void inter_party_init(void) if (!in.is_open()) return; - // TODO: convert to use char_id, and change to extract() + // TODO: convert to use char_id AString line; int c = 0; while (in.getline(line)) { - int i, j = 0; - if (SSCANF(line, "%d\t%%newid%%\n%n", &i, &j) == 1 && j > 0 - && party_newid <= i) + PartyId i; + if (extract(line, record<'\t'>(&i, "%newid%"_s)) + && party_newid < i) { party_newid = i; continue; } - struct party p {}; - if (extract(line, &p) && p.party_id > 0) + PartyMost pm; + PartyPair pp; + pp.party_most = ± + if (extract(line, &pp) && pp.party_id) { - if (p.party_id >= party_newid) - party_newid = p.party_id + 1; - party_check_deleted_init(&p); - party_db.insert(p.party_id, p); - party_check_empty(&p); + if (party_newid < next(pp.party_id)) + party_newid = next(pp.party_id); + party_check_deleted_init(pp); + party_db.insert(pp.party_id, pm); + party_check_empty(pp); } else { - PRINTF("int_party: broken data [%s] line %d\n", party_txt, + PRINTF("int_party: broken data [%s] line %d\n"_fmt, party_txt, c + 1); } c++; @@ -183,7 +192,7 @@ void inter_party_init(void) // パーティーデータのセーブ用 static -void inter_party_save_sub(struct party *data, io::WriteFile& fp) +void inter_party_save_sub(PartyPair data, io::WriteFile& fp) { AString line = inter_party_tostr(data); fp.put_line(line); @@ -195,19 +204,24 @@ int inter_party_save(void) io::WriteLock fp(party_txt); if (!fp.is_open()) { - PRINTF("int_party: cant write [%s] !!! data is lost !!!\n", + PRINTF("int_party: cant write [%s] !!! data is lost !!!\n"_fmt, party_txt); return 1; } for (auto& pair : party_db) - inter_party_save_sub(&pair.second, fp); + { + PartyPair tmp; + tmp.party_id = pair.first; + tmp.party_most = &pair.second; + inter_party_save_sub(tmp, fp); + } return 0; } // パーティ名検索用 static -void search_partyname_sub(struct party *p, PartyName str, struct party **dst) +void search_partyname_sub(PartyPair p, PartyName str, PartyPair *dst) { if (p->name == str) *dst = p; @@ -215,18 +229,23 @@ void search_partyname_sub(struct party *p, PartyName str, struct party **dst) // パーティ名検索 static -struct party *search_partyname(PartyName str) +PartyPair search_partyname(PartyName str) { - struct party *p = NULL; + PartyPair p; for (auto& pair : party_db) - search_partyname_sub(&pair.second, str, &p); + { + PartyPair tmp; + tmp.party_id = pair.first; + tmp.party_most = &pair.second; + search_partyname_sub(tmp, str, &p); + } return p; } // EXP公平分配できるかチェック static -int party_check_exp_share(struct party *p) +int party_check_exp_share(PartyPair p) { int i; int maxlv = 0, minlv = 0x7fffffff; @@ -247,34 +266,32 @@ int party_check_exp_share(struct party *p) } // パーティが空かどうかチェック -int party_check_empty(struct party *p) +int party_check_empty(PartyPair p) { int i; -// PRINTF("party check empty %08X\n", (int)p); for (i = 0; i < MAX_PARTY; i++) { -// PRINTF("%d acc=%d\n", i, p->member[i].account_id); - if (p->member[i].account_id > 0) + if (p->member[i].account_id) { return 0; } } // 誰もいないので解散 - mapif_party_broken(p->party_id, 0); - party_db.erase(p->party_id); + mapif_party_broken(p.party_id, 0); + party_db.erase(p.party_id); return 1; } // キャラの競合がないかチェック用 static -void party_check_conflict_sub(struct party *p, - int party_id, int account_id, CharName nick) +void party_check_conflict_sub(PartyPair p, + PartyId party_id, AccountId account_id, CharName nick) { int i; - if (p->party_id == party_id) // 本来の所属なので問題なし + if (p.party_id == party_id) // 本来の所属なので問題なし return; for (i = 0; i < MAX_PARTY; i++) @@ -283,20 +300,25 @@ void party_check_conflict_sub(struct party *p, && p->member[i].name == nick) { // 別のパーティに偽の所属データがあるので脱退 - PRINTF("int_party: party conflict! %d %d %d\n", account_id, - party_id, p->party_id); - mapif_parse_PartyLeave(nullptr, p->party_id, account_id); + PRINTF("int_party: party conflict! %d %d %d\n"_fmt, account_id, + party_id, p.party_id); + mapif_parse_PartyLeave(nullptr, p.party_id, account_id); } } } // キャラの競合がないかチェック static -void party_check_conflict(int party_id, int account_id, CharName nick) +void party_check_conflict(PartyId party_id, AccountId account_id, CharName nick) { for (auto& pair : party_db) - party_check_conflict_sub(&pair.second, + { + PartyPair tmp; + tmp.party_id = pair.first; + tmp.party_most = &pair.second; + party_check_conflict_sub(tmp, party_id, account_id, nick); + } } //------------------------------------------------------------------- @@ -304,140 +326,156 @@ void party_check_conflict(int party_id, int account_id, CharName nick) // パーティ作成可否 static -void mapif_party_created(Session *s, int account_id, struct party *p) +void mapif_party_created(Session *s, AccountId account_id, PartyPair p) { - WFIFOW(s, 0) = 0x3820; - WFIFOL(s, 2) = account_id; - if (p != NULL) + Packet_Fixed<0x3820> fixed_20; + fixed_20.account_id = account_id; + if (p) { - WFIFOB(s, 6) = 0; - WFIFOL(s, 7) = p->party_id; - WFIFO_STRING(s, 11, p->name, 24); - PRINTF("int_party: created! %d %s\n", p->party_id, p->name); + fixed_20.error = 0; + fixed_20.party_id = p.party_id; + fixed_20.party_name = p->name; + PRINTF("int_party: created! %d %s\n"_fmt, p.party_id, p->name); } else { - WFIFOB(s, 6) = 1; - WFIFOL(s, 7) = 0; - WFIFO_STRING(s, 11, "error", 24); + fixed_20.error = 1; + fixed_20.party_id = PartyId(); + fixed_20.party_name = stringish<PartyName>("error"_s); } - WFIFOSET(s, 35); + send_fpacket<0x3820, 35>(s, fixed_20); } // パーティ情報見つからず static -void mapif_party_noinfo(Session *s, int party_id) +void mapif_party_noinfo(Session *s, PartyId party_id) { - WFIFOW(s, 0) = 0x3821; - WFIFOW(s, 2) = 8; - WFIFOL(s, 4) = party_id; - WFIFOSET(s, 8); - PRINTF("int_party: info not found %d\n", party_id); + Packet_Head<0x3821> head_21; + Packet_Option<0x3821> option_21; + head_21.party_id = party_id; + send_opacket<0x3821, 8, sizeof(NetPacket_Option<0x3821>)>(s, head_21, false, option_21); + PRINTF("int_party: info not found %d\n"_fmt, party_id); } // パーティ情報まとめ送り static -void mapif_party_info(Session *s, struct party *p) +void mapif_party_info(Session *s, PartyPair p) { - unsigned char buf[4 + sizeof(struct party)]; - - WBUFW(buf, 0) = 0x3821; - WBUF_STRUCT(buf, 4, *p); - WBUFW(buf, 2) = 4 + sizeof(struct party); + Packet_Head<0x3821> head_21; + head_21.party_id = p.party_id; + Packet_Option<0x3821> option_21; + option_21.party_most = *p.party_most; if (!s) - mapif_sendall(buf, WBUFW(buf, 2)); + { + for (Session *ss : iter_map_sessions()) + { + send_opacket<0x3821, 8, sizeof(NetPacket_Option<0x3821>)>(ss, head_21, true, option_21); + } + } else - mapif_send(s, buf, WBUFW(buf, 2)); -// PRINTF("int_party: info %d %s\n", p->party_id, p->name); + { + send_opacket<0x3821, 8, sizeof(NetPacket_Option<0x3821>)>(s, head_21, true, option_21); + } } // パーティメンバ追加可否 static -void mapif_party_memberadded(Session *s, int party_id, int account_id, int flag) +void mapif_party_memberadded(Session *s, PartyId party_id, AccountId account_id, int flag) { - WFIFOW(s, 0) = 0x3822; - WFIFOL(s, 2) = party_id; - WFIFOL(s, 6) = account_id; - WFIFOB(s, 10) = flag; - WFIFOSET(s, 11); + Packet_Fixed<0x3822> fixed_22; + fixed_22.party_id = party_id; + fixed_22.account_id = account_id; + fixed_22.flag = flag; + send_fpacket<0x3822, 11>(s, fixed_22); } // パーティ設定変更通知 static -void mapif_party_optionchanged(Session *s, struct party *p, int account_id, +void mapif_party_optionchanged(Session *s, PartyPair p, AccountId account_id, int flag) { - unsigned char buf[15]; - - WBUFW(buf, 0) = 0x3823; - WBUFL(buf, 2) = p->party_id; - WBUFL(buf, 6) = account_id; - WBUFW(buf, 10) = p->exp; - WBUFW(buf, 12) = p->item; - WBUFB(buf, 14) = flag; + Packet_Fixed<0x3823> fixed_23; + fixed_23.party_id = p.party_id; + fixed_23.account_id = account_id; + fixed_23.exp = p->exp; + fixed_23.item = p->item; + fixed_23.flag = flag; if (flag == 0) - mapif_sendall(buf, 15); + { + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x3823, 15>(ss, fixed_23); + } + } else - mapif_send(s, buf, 15); - PRINTF("int_party: option changed %d %d %d %d %d\n", p->party_id, + { + send_fpacket<0x3823, 15>(s, fixed_23); + } + PRINTF("int_party: option changed %d %d %d %d %d\n"_fmt, p.party_id, account_id, p->exp, p->item, flag); } // パーティ脱退通知 static -void mapif_party_leaved(int party_id, int account_id, CharName name) +void mapif_party_leaved(PartyId party_id, AccountId account_id, CharName name) { - unsigned char buf[34]; + Packet_Fixed<0x3824> fixed_24; + fixed_24.party_id = party_id; + fixed_24.account_id = account_id; + fixed_24.char_name = name; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x3824, 34>(ss, fixed_24); + } - WBUFW(buf, 0) = 0x3824; - WBUFL(buf, 2) = party_id; - WBUFL(buf, 6) = account_id; - WBUF_STRING(buf, 10, name.to__actual(), 24); - mapif_sendall(buf, 34); - PRINTF("int_party: party leaved %d %d %s\n", party_id, account_id, name); + PRINTF("int_party: party leaved %d %d %s\n"_fmt, party_id, account_id, name); } // パーティマップ更新通知 static -void mapif_party_membermoved(struct party *p, int idx) +void mapif_party_membermoved(PartyPair p, int idx) { assert (idx < MAX_PARTY); - unsigned char buf[29]; - - WBUFW(buf, 0) = 0x3825; - WBUFL(buf, 2) = p->party_id; - WBUFL(buf, 6) = p->member[idx].account_id; - WBUF_STRING(buf, 10, p->member[idx].map, 16); - WBUFB(buf, 26) = p->member[idx].online; - WBUFW(buf, 27) = p->member[idx].lv; - mapif_sendall(buf, 29); + + Packet_Fixed<0x3825> fixed_25; + fixed_25.party_id = p.party_id; + fixed_25.account_id = p->member[idx].account_id; + fixed_25.map_name = p->member[idx].map; + fixed_25.online = p->member[idx].online; + fixed_25.level = p->member[idx].lv; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x3825, 29>(ss, fixed_25); + } } // パーティ解散通知 -void mapif_party_broken(int party_id, int flag) -{ - unsigned char buf[7]; - WBUFW(buf, 0) = 0x3826; - WBUFL(buf, 2) = party_id; - WBUFB(buf, 6) = flag; - mapif_sendall(buf, 7); - PRINTF("int_party: broken %d\n", party_id); - CHAR_LOG("int_party: broken %d\n", party_id); +void mapif_party_broken(PartyId party_id, int flag) +{ + Packet_Fixed<0x3826> fixed_26; + fixed_26.party_id = party_id; + fixed_26.flag = flag; + for (Session *ss : iter_map_sessions()) + { + send_fpacket<0x3826, 7>(ss, fixed_26); + } + + PRINTF("int_party: broken %d\n"_fmt, party_id); + CHAR_LOG("int_party: broken %d\n"_fmt, party_id); } // パーティ内発言 static -void mapif_party_message(int party_id, int account_id, XString mes) +void mapif_party_message(PartyId party_id, AccountId account_id, XString mes) { - size_t len = mes.size() + 1; - unsigned char buf[len + 12]; - - WBUFW(buf, 0) = 0x3827; - WBUFW(buf, 2) = len + 12; - WBUFL(buf, 4) = party_id; - WBUFL(buf, 8) = account_id; - WBUF_STRING(buf, 12, mes, len); - mapif_sendall(buf, len + 12); + Packet_Head<0x3827> head_27; + XString repeat_27 = mes; + head_27.party_id = party_id; + head_27.account_id = account_id; + for (Session *ss : iter_map_sessions()) + { + send_vpacket<0x3827, 12, 1>(ss, head_27, repeat_27); + } } //------------------------------------------------------------------- @@ -445,26 +483,29 @@ void mapif_party_message(int party_id, int account_id, XString mes) // パーティ static -void mapif_parse_CreateParty(Session *s, int account_id, PartyName name, CharName nick, +void mapif_parse_CreateParty(Session *s, AccountId account_id, PartyName name, CharName nick, MapName map, int lv) { { if (!name.is_print()) { - PRINTF("int_party: illegal party name [%s]\n", name); - mapif_party_created(s, account_id, NULL); + PRINTF("int_party: illegal party name [%s]\n"_fmt, name); + mapif_party_created(s, account_id, PartyPair()); return; } } - if (search_partyname(name) != NULL) + if (search_partyname(name)) { - PRINTF("int_party: same name party exists [%s]\n", name); - mapif_party_created(s, account_id, NULL); + PRINTF("int_party: same name party exists [%s]\n"_fmt, name); + mapif_party_created(s, account_id, PartyPair()); return; } - struct party p {}; - p.party_id = party_newid++; + PartyMost p {}; + PartyPair pp; + pp.party_most = &p; + party_newid = next(party_newid); + pp.party_id = party_newid; p.name = name; p.exp = 0; p.item = 0; @@ -475,18 +516,19 @@ void mapif_parse_CreateParty(Session *s, int account_id, PartyName name, CharNam p.member[0].online = 1; p.member[0].lv = lv; - party_db.insert(p.party_id, p); + party_db.insert(pp.party_id, p); - mapif_party_created(s, account_id, &p); - mapif_party_info(s, &p); + mapif_party_created(s, account_id, pp); + mapif_party_info(s, pp); } // パーティ情報要求 static -void mapif_parse_PartyInfo(Session *s, int party_id) +void mapif_parse_PartyInfo(Session *s, PartyId party_id) { - struct party *p = party_db.search(party_id); - if (p != NULL) + PartyPair p; + p.party_most = party_db.search(party_id); + if (p) mapif_party_info(s, p); else mapif_party_noinfo(s, party_id); @@ -494,11 +536,12 @@ void mapif_parse_PartyInfo(Session *s, int party_id) // パーティ追加要求 static -void mapif_parse_PartyAddMember(Session *s, int party_id, int account_id, +void mapif_parse_PartyAddMember(Session *s, PartyId party_id, AccountId account_id, CharName nick, MapName map, int lv) { - struct party *p = party_db.search(party_id); - if (p == NULL) + PartyPair p; + p.party_most = party_db.search(party_id); + if (!p) { mapif_party_memberadded(s, party_id, account_id, 1); return; @@ -506,7 +549,7 @@ void mapif_parse_PartyAddMember(Session *s, int party_id, int account_id, for (int i = 0; i < MAX_PARTY; i++) { - if (p->member[i].account_id == 0) + if (!p->member[i].account_id) { int flag = 0; @@ -525,7 +568,7 @@ void mapif_parse_PartyAddMember(Session *s, int party_id, int account_id, flag = 0x01; } if (flag) - mapif_party_optionchanged(s, p, 0, 0); + mapif_party_optionchanged(s, p, AccountId(), 0); return; } } @@ -534,11 +577,12 @@ void mapif_parse_PartyAddMember(Session *s, int party_id, int account_id, // パーティー設定変更要求 static -void mapif_parse_PartyChangeOption(Session *s, int party_id, int account_id, +void mapif_parse_PartyChangeOption(Session *s, PartyId party_id, AccountId account_id, int exp, int item) { - struct party *p = party_db.search(party_id); - if (p == NULL) + PartyPair p; + p.party_most = party_db.search(party_id); + if (!p) return; p->exp = exp; @@ -555,9 +599,10 @@ void mapif_parse_PartyChangeOption(Session *s, int party_id, int account_id, } // パーティ脱退要求 -void mapif_parse_PartyLeave(Session *, int party_id, int account_id) +void mapif_parse_PartyLeave(Session *, PartyId party_id, AccountId account_id) { - struct party *p = party_db.search(party_id); + PartyPair p; + p.party_most = party_db.search(party_id); if (!p) return; for (int i = 0; i < MAX_PARTY; i++) @@ -566,7 +611,7 @@ void mapif_parse_PartyLeave(Session *, int party_id, int account_id) continue; mapif_party_leaved(party_id, account_id, p->member[i].name); - p->member[i] = party_member{}; + p->member[i] = PartyMember{}; if (party_check_empty(p) == 0) mapif_party_info(nullptr, p); // まだ人がいるのでデータ送信 return; @@ -575,11 +620,12 @@ void mapif_parse_PartyLeave(Session *, int party_id, int account_id) // パーティマップ更新要求 static -void mapif_parse_PartyChangeMap(Session *s, int party_id, int account_id, +void mapif_parse_PartyChangeMap(Session *s, PartyId party_id, AccountId account_id, MapName map, int online, int lv) { - struct party *p = party_db.search(party_id); - if (p == NULL) + PartyPair p; + p.party_most = party_db.search(party_id); + if (!p) return; for (int i = 0; i < MAX_PARTY; i++) @@ -599,33 +645,21 @@ void mapif_parse_PartyChangeMap(Session *s, int party_id, int account_id, flag = 1; } if (flag) - mapif_party_optionchanged(s, p, 0, 0); + mapif_party_optionchanged(s, p, AccountId(), 0); return; } } -// パーティ解散要求 -static -void mapif_parse_BreakParty(Session *, int party_id) -{ - struct party *p = party_db.search(party_id); - if (p == NULL) - return; - - party_db.erase(party_id); - mapif_party_broken(party_id, 0 /*unknown*/); -} - // パーティメッセージ送信 static -void mapif_parse_PartyMessage(Session *, int party_id, int account_id, XString mes) +void mapif_parse_PartyMessage(Session *, PartyId party_id, AccountId account_id, XString mes) { mapif_party_message(party_id, account_id, mes); } // パーティチェック要求 static -void mapif_parse_PartyCheck(Session *, int party_id, int account_id, CharName nick) +void mapif_parse_PartyCheck(Session *, PartyId party_id, AccountId account_id, CharName nick) { party_check_conflict(party_id, account_id, nick); } @@ -635,121 +669,157 @@ void mapif_parse_PartyCheck(Session *, int party_id, int account_id, CharName ni // ・パケット長データはinter.cにセットしておくこと // ・パケット長チェックや、RFIFOSKIPは呼び出し元で行われるので行ってはならない // ・エラーなら0(false)、そうでないなら1(true)をかえさなければならない -int inter_party_parse_frommap(Session *ms) +RecvResult inter_party_parse_frommap(Session *ms, uint16_t packet_id) { - switch (RFIFOW(ms, 0)) + RecvResult rv = RecvResult::Error; + switch (packet_id) { case 0x3020: { - int account = RFIFOL(ms, 2); - PartyName name = stringish<PartyName>(RFIFO_STRING<24>(ms, 6)); - CharName nick = stringish<CharName>(RFIFO_STRING<24>(ms, 30)); - MapName map = RFIFO_STRING<16>(ms, 54); - uint16_t lv = RFIFOW(ms, 70); + Packet_Fixed<0x3020> fixed; + rv = recv_fpacket<0x3020, 72>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account = fixed.account_id; + PartyName name = fixed.party_name; + CharName nick = fixed.char_name; + MapName map = fixed.map_name; + uint16_t lv = fixed.level; mapif_parse_CreateParty(ms, account, name, nick, map, lv); - } break; + } case 0x3021: { - int party_id = RFIFOL(ms, 2); + Packet_Fixed<0x3021> fixed; + rv = recv_fpacket<0x3021, 6>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; mapif_parse_PartyInfo(ms, party_id); - } break; + } case 0x3022: { - int party_id = RFIFOL(ms, 2); - int account_id = RFIFOL(ms, 6); - CharName nick = stringish<CharName>(RFIFO_STRING<24>(ms, 10)); - MapName map = RFIFO_STRING<16>(ms, 34); - uint16_t lv = RFIFOW(ms, 50); + Packet_Fixed<0x3022> fixed; + rv = recv_fpacket<0x3022, 52>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + CharName nick = fixed.char_name; + MapName map = fixed.map_name; + uint16_t lv = fixed.level; mapif_parse_PartyAddMember(ms, party_id, account_id, nick, map, lv); - } break; + } case 0x3023: { - int party_id = RFIFOL(ms, 2); - int account_id = RFIFOL(ms, 6); - uint16_t exp = RFIFOW(ms, 10); - uint16_t item = RFIFOW(ms, 12); + Packet_Fixed<0x3023> fixed; + rv = recv_fpacket<0x3023, 14>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + uint16_t exp = fixed.exp; + uint16_t item = fixed.item; mapif_parse_PartyChangeOption(ms, party_id, account_id, exp, item); - } break; + } case 0x3024: { - int party_id = RFIFOL(ms, 2); - int account_id = RFIFOL(ms, 6); + Packet_Fixed<0x3024> fixed; + rv = recv_fpacket<0x3024, 10>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; mapif_parse_PartyLeave(ms, party_id, account_id); - } break; + } case 0x3025: { - int party_id = RFIFOL(ms, 2); - int account_id = RFIFOL(ms, 6); - MapName map = RFIFO_STRING<16>(ms, 10); - uint8_t online = RFIFOB(ms, 26); - uint16_t lv = RFIFOW(ms, 27); + Packet_Fixed<0x3025> fixed; + rv = recv_fpacket<0x3025, 29>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + MapName map = fixed.map_name; + uint8_t online = fixed.online; + uint16_t lv = fixed.level; mapif_parse_PartyChangeMap(ms, party_id, account_id, map, online, lv); - } break; - case 0x3026: - { - int party_id = RFIFOL(ms, 2); - mapif_parse_BreakParty(ms, party_id); } - break; case 0x3027: { - size_t len = RFIFOW(ms, 2) - 12; - int party_id = RFIFOL(ms, 4); - int account_id = RFIFOL(ms, 8); - AString mes = RFIFO_STRING(ms, 12, len); + Packet_Head<0x3027> head; + AString repeat; + rv = recv_vpacket<0x3027, 12, 1>(ms, head, repeat); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = head.party_id; + AccountId account_id = head.account_id; + AString& mes = repeat; mapif_parse_PartyMessage(ms, party_id, account_id, mes); - } break; + } case 0x3028: { - int party_id = RFIFOL(ms, 2); - int account_id = RFIFOL(ms, 6); - CharName nick = stringish<CharName>(RFIFO_STRING<24>(ms, 10)); + Packet_Fixed<0x3028> fixed; + rv = recv_fpacket<0x3028, 34>(ms, fixed); + if (rv != RecvResult::Complete) + break; + + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + CharName nick = fixed.char_name; mapif_parse_PartyCheck(ms, party_id, account_id, nick); - } break; + } default: - return 0; + return RecvResult::Error; } - return 1; + return rv; } // サーバーから脱退要求(キャラ削除用) -void inter_party_leave(int party_id, int account_id) +void inter_party_leave(PartyId party_id, AccountId account_id) { mapif_parse_PartyLeave(nullptr, party_id, account_id); } +} // namespace tmwa diff --git a/src/char/int_party.hpp b/src/char/int_party.hpp index 1608c37..f33fc0d 100644 --- a/src/char/int_party.hpp +++ b/src/char/int_party.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_CHAR_INT_PARTY_HPP -#define TMWA_CHAR_INT_PARTY_HPP +#pragma once // int_party.hpp - Internal party handling. // // Copyright © ????-2004 Athena Dev Teams @@ -21,19 +20,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -struct Session; +#include "../net/fwd.hpp" +#include "../mmo/fwd.hpp" + + +namespace tmwa +{ void inter_party_init(void); int inter_party_save(void); -int inter_party_parse_frommap(Session *ms); +RecvResult inter_party_parse_frommap(Session *ms, uint16_t); -void inter_party_leave(int party_id, int account_id); +void inter_party_leave(PartyId party_id, AccountId account_id); extern AString party_txt; - -#endif // TMWA_CHAR_INT_PARTY_HPP +} // namespace tmwa diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp index c7c1343..01665ec 100644 --- a/src/char/int_storage.cpp +++ b/src/char/int_storage.cpp @@ -20,50 +20,54 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <cstdlib> -#include <cstring> - -#include <functional> - #include "../strings/mstring.hpp" #include "../strings/astring.hpp" #include "../strings/xstring.hpp" +#include "../strings/literal.hpp" #include "../generic/db.hpp" #include "../io/cxxstdio.hpp" #include "../io/lock.hpp" #include "../io/read.hpp" +#include "../io/write.hpp" + +#include "../net/packets.hpp" + +#include "../proto2/char-map.hpp" #include "../mmo/extract.hpp" #include "../mmo/mmo.hpp" -#include "../mmo/socket.hpp" #include "../poison.hpp" + +namespace tmwa +{ // ファイル名のデフォルト // inter_config_read()で再設定される -AString storage_txt = "save/storage.txt"; +AString storage_txt = "save/storage.txt"_s; static -Map<int, struct storage> storage_db; +Map<AccountId, Storage> storage_db; // 倉庫データを文字列に変換 static -AString storage_tostr(struct storage *p) +AString storage_tostr(Storage *p) { MString str; str += STRPRINTF( - "%d,%d\t", + "%d,%d\t"_fmt, p->account_id, p->storage_amount); int f = 0; - for (int i = 0; i < MAX_STORAGE; i++) + for (SOff0 i : SOff0::iter()) + { if (p->storage_[i].nameid && p->storage_[i].amount) { str += STRPRINTF( - "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d ", - p->storage_[i].id, + "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d "_fmt, + 0 /*id*/, p->storage_[i].nameid, p->storage_[i].amount, p->storage_[i].equip, @@ -77,6 +81,7 @@ AString storage_tostr(struct storage *p) // shouldn't that include 'broken' also? Oh, well ... f++; } + } str += '\t'; @@ -87,9 +92,9 @@ AString storage_tostr(struct storage *p) // 文字列を倉庫データに変換 static -bool extract(XString str, struct storage *p) +bool extract(XString str, Storage *p) { - std::vector<struct item> storage_items; + std::vector<Item> storage_items; if (!extract(str, record<'\t'>( record<','>( @@ -98,7 +103,7 @@ bool extract(XString str, struct storage *p) vrec<' '>(&storage_items)))) return false; - if (p->account_id <= 0) + if (!p->account_id) return false; if (storage_items.size() > MAX_STORAGE) @@ -106,15 +111,15 @@ bool extract(XString str, struct storage *p) std::copy(storage_items.begin(), storage_items.end(), p->storage_.begin()); if (p->storage_amount != storage_items.size()) - PRINTF("WARNING: storage desync for %d\n", p->account_id); + PRINTF("WARNING: storage desync for %d\n"_fmt, p->account_id); return true; } // アカウントから倉庫データインデックスを得る(新規倉庫追加可能) -struct storage *account2storage(int account_id) +Storage *account2storage(AccountId account_id) { - struct storage *s = storage_db.search(account_id); - if (s == NULL) + Storage *s = storage_db.search(account_id); + if (s == nullptr) { s = storage_db.init(account_id); s->account_id = account_id; @@ -131,21 +136,21 @@ void inter_storage_init(void) io::ReadFile in(storage_txt); if (!in.is_open()) { - PRINTF("cant't read : %s\n", storage_txt); + PRINTF("cant't read : %s\n"_fmt, storage_txt); return; } AString line; while (in.getline(line)) { - struct storage s {}; + Storage s {}; if (extract(line, &s)) { storage_db.insert(s.account_id, s); } else { - PRINTF("int_storage: broken data [%s] line %d\n", + PRINTF("int_storage: broken data [%s] line %d\n"_fmt, storage_txt, c); } c++; @@ -153,7 +158,7 @@ void inter_storage_init(void) } static -void inter_storage_save_sub(struct storage *data, io::WriteFile& fp) +void inter_storage_save_sub(Storage *data, io::WriteFile& fp) { AString line = storage_tostr(data); if (line) @@ -168,7 +173,7 @@ int inter_storage_save(void) if (!fp.is_open()) { - PRINTF("int_storage: cant write [%s] !!! data is lost !!!\n", + PRINTF("int_storage: cant write [%s] !!! data is lost !!!\n"_fmt, storage_txt); return 1; } @@ -178,7 +183,7 @@ int inter_storage_save(void) } // 倉庫データ削除 -void inter_storage_delete(int account_id) +void inter_storage_delete(AccountId account_id) { storage_db.erase(account_id); } @@ -188,54 +193,62 @@ void inter_storage_delete(int account_id) // 倉庫データの送信 static -void mapif_load_storage(Session *ss, int account_id) +void mapif_load_storage(Session *ss, AccountId account_id) { - struct storage *st = account2storage(account_id); - WFIFOW(ss, 0) = 0x3810; - WFIFOW(ss, 2) = sizeof(struct storage) + 8; - WFIFOL(ss, 4) = account_id; - WFIFO_STRUCT(ss, 8, *st); - WFIFOSET(ss, WFIFOW(ss, 2)); + Storage *st = account2storage(account_id); + Packet_Payload<0x3810> payload_10; + payload_10.account_id = account_id; + payload_10.storage = *st; + send_ppacket<0x3810>(ss, payload_10); } // 倉庫データ保存完了送信 static -void mapif_save_storage_ack(Session *ss, int account_id) +void mapif_save_storage_ack(Session *ss, AccountId account_id) { - WFIFOW(ss, 0) = 0x3811; - WFIFOL(ss, 2) = account_id; - WFIFOB(ss, 6) = 0; - WFIFOSET(ss, 7); + Packet_Fixed<0x3811> fixed_11; + fixed_11.account_id = account_id; + fixed_11.unknown = 0; + send_fpacket<0x3811, 7>(ss, fixed_11); } //--------------------------------------------------------- // map serverからの通信 // 倉庫データ要求受信 -static -void mapif_parse_LoadStorage(Session *ss) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_LoadStorage(Session *ss) { - mapif_load_storage(ss, RFIFOL(ss, 2)); + Packet_Fixed<0x3010> fixed; + RecvResult rv = recv_fpacket<0x3010, 6>(ss, fixed); + if (rv != RecvResult::Complete) + return rv; + + AccountId account_id = fixed.account_id; + mapif_load_storage(ss, account_id); + + return rv; } // 倉庫データ受信&保存 -static -void mapif_parse_SaveStorage(Session *ss) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_SaveStorage(Session *ss) { - struct storage *st; - int account_id = RFIFOL(ss, 4); - int len = RFIFOW(ss, 2); - if (sizeof(struct storage) != len - 8) - { - PRINTF("inter storage: data size error %zu %d\n", - sizeof(struct storage), len - 8); - } - else + Packet_Payload<0x3011> payload; + RecvResult rv = recv_ppacket<0x3011>(ss, payload); + if (rv != RecvResult::Complete) + return rv; + + Storage *st; + AccountId account_id = payload.account_id; + { st = account2storage(account_id); - RFIFO_STRUCT(ss, 8, *st); + *st = payload.storage; mapif_save_storage_ack(ss, account_id); } + + return rv; } // map server からの通信 @@ -243,18 +256,20 @@ void mapif_parse_SaveStorage(Session *ss) // ・パケット長データはinter.cにセットしておくこと // ・パケット長チェックや、RFIFOSKIPは呼び出し元で行われるので行ってはならない // ・エラーなら0(false)、そうでないなら1(true)をかえさなければならない -int inter_storage_parse_frommap(Session *ms) +RecvResult inter_storage_parse_frommap(Session *ms, uint16_t packet_id) { - switch (RFIFOW(ms, 0)) + RecvResult rv; + switch (packet_id) { case 0x3010: - mapif_parse_LoadStorage(ms); + rv = mapif_parse_LoadStorage(ms); break; case 0x3011: - mapif_parse_SaveStorage(ms); + rv = mapif_parse_SaveStorage(ms); break; default: - return 0; + return RecvResult::Error; } - return 1; + return rv; } +} // namespace tmwa diff --git a/src/char/int_storage.hpp b/src/char/int_storage.hpp index 7f6deb5..b8ec9db 100644 --- a/src/char/int_storage.hpp +++ b/src/char/int_storage.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_CHAR_INT_STORAGE_HPP -#define TMWA_CHAR_INT_STORAGE_HPP +#pragma once // int_storage.hpp - Internal storage handling. // // Copyright © ????-2004 Athena Dev Teams @@ -21,19 +20,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -struct Session; +#include "../net/fwd.hpp" +#include "../mmo/fwd.hpp" + + +namespace tmwa +{ void inter_storage_init(void); int inter_storage_save(void); -void inter_storage_delete(int account_id); -struct storage *account2storage(int account_id); +void inter_storage_delete(AccountId account_id); +Storage *account2storage(AccountId account_id); -int inter_storage_parse_frommap(Session *ms); +RecvResult inter_storage_parse_frommap(Session *ms, uint16_t); extern AString storage_txt; - -#endif // TMWA_CHAR_INT_STORAGE_HPP +} // namespace tmwa diff --git a/src/char/inter.cpp b/src/char/inter.cpp index 204a0e2..1cf41ff 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -21,8 +21,6 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include <cassert> -#include <cstdlib> -#include <cstring> #include <vector> @@ -30,18 +28,22 @@ #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" +#include "../strings/literal.hpp" +#include "../generic/array.hpp" #include "../generic/db.hpp" #include "../io/cxxstdio.hpp" #include "../io/lock.hpp" #include "../io/read.hpp" +#include "../io/write.hpp" + +#include "../net/packets.hpp" + +#include "../proto2/char-map.hpp" -#include "../mmo/config_parse.hpp" #include "../mmo/extract.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" -#include "../mmo/utils.hpp" +#include "../mmo/mmo.hpp" #include "char.hpp" #include "int_party.hpp" @@ -49,34 +51,23 @@ #include "../poison.hpp" + +namespace tmwa +{ static -AString accreg_txt = "save/accreg.txt"; +AString accreg_txt = "save/accreg.txt"_s; struct accreg { - int account_id, reg_num; - Array<struct global_reg, ACCOUNT_REG_NUM> reg; + AccountId account_id; + int reg_num; + Array<GlobalReg, ACCOUNT_REG_NUM> reg; }; static -Map<int, struct accreg> accreg_db; +Map<AccountId, struct accreg> accreg_db; int party_share_level = 10; -// 受信パケット長リスト -static -int inter_recv_packet_length[] = -{ - -1, -1, 7, -1, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6, -1, 0, 0, 0, 0, 0, 0, 10, -1, 0, 0, 0, 0, 0, 0, - 72, 6, 52, 14, 10, 29, 6, -1, 34, 0, 0, 0, 0, 0, 0, 0, - -1, 6, -1, 0, 55, 19, 6, -1, 14, -1, -1, -1, 14, 19, 186, -1, - 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 14, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - //-------------------------------------------------------- // アカウント変数を文字列へ変換 @@ -85,9 +76,9 @@ AString inter_accreg_tostr(struct accreg *reg) { assert(reg->reg_num < ACCOUNT_REG_NUM); MString str; - str += STRPRINTF("%d\t", reg->account_id); + str += STRPRINTF("%d\t"_fmt, reg->account_id); for (int j = 0; j < reg->reg_num; j++) - str += STRPRINTF("%s,%d ", reg->reg[j].str, reg->reg[j].value); + str += STRPRINTF("%s,%d "_fmt, reg->reg[j].str, reg->reg[j].value); return AString(str); } @@ -95,13 +86,13 @@ AString inter_accreg_tostr(struct accreg *reg) static bool extract(XString str, struct accreg *reg) { - std::vector<struct global_reg> vars; + std::vector<GlobalReg> vars; if (!extract(str, record<'\t'>( ®->account_id, vrec<' '>(&vars)))) return false; - if (reg->account_id <= 0) + if (!reg->account_id) return false; if (vars.size() > ACCOUNT_REG_NUM) @@ -130,7 +121,7 @@ void inter_accreg_init(void) } else { - PRINTF("inter: accreg: broken data [%s] line %d\n", accreg_txt, + PRINTF("inter: accreg: broken data [%s] line %d\n"_fmt, accreg_txt, c); } c++; @@ -155,7 +146,7 @@ int inter_accreg_save(void) io::WriteLock fp(accreg_txt); if (!fp.is_open()) { - PRINTF("int_accreg: cant write [%s] !!! data is lost !!!\n", + PRINTF("int_accreg: cant write [%s] !!! data is lost !!!\n"_fmt, accreg_txt); return 1; } @@ -168,19 +159,19 @@ int inter_accreg_save(void) bool inter_config(XString w1, ZString w2) { { - if (w1 == "storage_txt") + if (w1 == "storage_txt"_s) { storage_txt = w2; } - else if (w1 == "party_txt") + else if (w1 == "party_txt"_s) { party_txt = w2; } - else if (w1 == "accreg_txt") + else if (w1 == "accreg_txt"_s) { accreg_txt = w2; } - else if (w1 == "party_share_level") + else if (w1 == "party_share_level"_s) { party_share_level = atoi(w2.c_str()); if (party_share_level < 0) @@ -218,14 +209,10 @@ void inter_init2() static void mapif_GMmessage(XString mes) { - size_t str_len = mes.size() + 1; - size_t msg_len = str_len + 4; - uint8_t buf[msg_len]; - - WBUFW(buf, 0) = 0x3800; - WBUFW(buf, 2) = msg_len; - WBUF_STRING(buf, 4, mes, str_len); - mapif_sendall(buf, msg_len); + for (Session *ss : iter_map_sessions()) + { + send_packet_repeatonly<0x3800, 4, 1>(ss, mes); + } } // Wisp/page transmission to correct map-server @@ -235,103 +222,105 @@ void mapif_wis_message(Session *tms, CharName src, CharName dst, XString msg) const CharPair *mcs = search_character(src); assert (mcs); - size_t str_size = msg.size() + 1; - uint8_t buf[56 + str_size]; - - WBUFW(buf, 0) = 0x3801; - WBUFW(buf, 2) = 56 + str_size; - WBUFL(buf, 4) = mcs->key.char_id; // formerly, whisper ID - WBUF_STRING(buf, 8, src.to__actual(), 24); - WBUF_STRING(buf, 32, dst.to__actual(), 24); - WBUF_STRING(buf, 56, msg, str_size); - mapif_send(tms, buf, WBUFW(buf, 2)); + Packet_Head<0x3801> head_01; + head_01.whisper_id = mcs->key.char_id; + head_01.src_char_name = src; + head_01.dst_char_name = dst; + send_vpacket<0x3801, 56, 1>(tms, head_01, msg); } // Wisp/page transmission result to map-server static void mapif_wis_end(Session *sms, CharName sender, int flag) { - uint8_t buf[27]; - - WBUFW(buf, 0) = 0x3802; - WBUF_STRING(buf, 2, sender.to__actual(), 24); - WBUFB(buf, 26) = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - mapif_send(sms, buf, 27); + Packet_Fixed<0x3802> fixed_02; + fixed_02.sender_char_name = sender; + fixed_02.flag = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + send_fpacket<0x3802, 27>(sms, fixed_02); } // アカウント変数送信 static -void mapif_account_reg(Session *s) +void mapif_account_reg(Session *s, AccountId account_id, const std::vector<Packet_Repeat<0x3004>>& repeat) { - size_t len = RFIFOW(s, 2); - uint8_t buf[len]; - RFIFO_BUF_CLONE(s, buf, len); - WBUFW(buf, 0) = 0x3804; - mapif_sendallwos(s, buf, WBUFW(buf, 2)); + Packet_Head<0x3804> head_04; + head_04.account_id = account_id; + std::vector<Packet_Repeat<0x3804>> repeat_04(repeat.size()); + for (size_t i = 0; i < repeat.size(); ++i) + { + repeat_04[i].name = repeat[i].name; + repeat_04[i].value = repeat[i].value; + } + + for (Session *ss : iter_map_sessions()) + { + if (ss == s) + continue; + send_vpacket<0x3804, 8, 36>(ss, head_04, repeat_04); + } } // アカウント変数要求返信 static -void mapif_account_reg_reply(Session *s, int account_id) +void mapif_account_reg_reply(Session *s, AccountId account_id) { struct accreg *reg = accreg_db.search(account_id); - WFIFOW(s, 0) = 0x3804; - WFIFOL(s, 4) = account_id; - if (reg == NULL) - { - WFIFOW(s, 2) = 8; - } - else + Packet_Head<0x3804> head_04; + head_04.account_id = account_id; + std::vector<Packet_Repeat<0x3804>> repeat_04; + if (reg) { + repeat_04.resize(reg->reg_num); assert (reg->reg_num < ACCOUNT_REG_NUM); - int j, p; - for (j = 0, p = 8; j < reg->reg_num; j++, p += 36) + for (size_t j = 0; j < reg->reg_num; ++j) { - WFIFO_STRING(s, p, reg->reg[j].str, 32); - WFIFOL(s, p + 32) = reg->reg[j].value; + repeat_04[j].name = reg->reg[j].str; + repeat_04[j].value = reg->reg[j].value; } - WFIFOW(s, 2) = p; } - WFIFOSET(s, WFIFOW(s, 2)); + send_vpacket<0x3804, 8, 36>(s, head_04, repeat_04); } //-------------------------------------------------------- // received packets from map-server // GMメッセージ送信 -static -void mapif_parse_GMmessage(Session *s) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_GMmessage(Session *s) { - size_t msg_len = RFIFOW(s, 2); - size_t str_len = msg_len - 4; - AString buf = RFIFO_STRING(s, 4, str_len); + AString repeat; + RecvResult rv = recv_packet_repeatonly<0x3000, 4, 1>(s, repeat); + if (rv != RecvResult::Complete) + return rv; + AString& buf = repeat; mapif_GMmessage(buf); + + return rv; } // Wisp/page request to send -static -void mapif_parse_WisRequest(Session *sms) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_WisRequest(Session *sms) { - if (RFIFOW(sms, 2) - 52 <= 0) - { // normaly, impossible, but who knows... - PRINTF("inter: Wis message doesn't exist.\n"); - return; - } + Packet_Head<0x3001> head; + AString repeat; + RecvResult rv = recv_vpacket<0x3001, 52, 1>(sms, head, repeat); + if (rv != RecvResult::Complete) + return rv; - CharName from = stringish<CharName>(RFIFO_STRING<24>(sms, 4)); - CharName to = stringish<CharName>(RFIFO_STRING<24>(sms, 28)); + CharName from = head.from_char_name; + CharName to = head.to_char_name; // search if character exists before to ask all map-servers const CharPair *mcs = search_character(to); if (!mcs) { - uint8_t buf[27]; - WBUFW(buf, 0) = 0x3802; - WBUF_STRING(buf, 2, from.to__actual(), 24); - WBUFB(buf, 26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - mapif_send(sms, buf, 27); + Packet_Fixed<0x3802> fixed_02; + fixed_02.sender_char_name = from; + fixed_02.flag = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + send_fpacket<0x3802, 27>(sms, fixed_02); // Character exists. So, ask all map-servers } else @@ -341,17 +330,15 @@ void mapif_parse_WisRequest(Session *sms) // if source is destination, don't ask other servers. if (from == to) { - uint8_t buf[27]; - WBUFW(buf, 0) = 0x3802; - WBUF_STRING(buf, 2, from.to__actual(), 24); - WBUFB(buf, 26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - mapif_send(sms, buf, 27); + Packet_Fixed<0x3802> fixed_02; + fixed_02.sender_char_name = from; + fixed_02.flag = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + send_fpacket<0x3802, 27>(sms, fixed_02); } else { - size_t len = RFIFOW(sms, 2) - 52; Session *tms = server_for(mcs); // for to - AString msg = RFIFO_STRING(sms, 52, len); + AString& msg = repeat; if (tms) { mapif_wis_message(tms, from, to, msg); @@ -362,68 +349,99 @@ void mapif_parse_WisRequest(Session *sms) } } } + + return rv; } // Wisp/page transmission result -static -int mapif_parse_WisReply(Session *tms) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_WisReply(Session *tms) { - int id = RFIFOL(tms, 2), flag = RFIFOB(tms, 6); + Packet_Fixed<0x3002> fixed; + RecvResult rv = recv_fpacket<0x3002, 7>(tms, fixed); + if (rv != RecvResult::Complete) + return rv; + + CharId id = fixed.char_id; + uint8_t flag = fixed.flag; const CharPair *smcs = search_character_id(id); CharName from = smcs->key.name; Session *sms = server_for(smcs); + { mapif_wis_end(sms, from, flag); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target } - return 0; + return rv; } // Received wisp message from map-server for ALL gm (just copy the message and resends it to ALL map-servers) -static -void mapif_parse_WisToGM(Session *s) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_WisToGM(Session *s) { - size_t len = RFIFOW(s, 2); - uint8_t buf[len]; - // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B + Packet_Head<0x3003> head; + AString repeat; + RecvResult rv = recv_vpacket<0x3003, 30, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + Packet_Head<0x3803> head_03; + head_03.char_name = head.char_name; + head_03.min_gm_level = head.min_gm_level; + for (Session *ss : iter_map_sessions()) + { + send_vpacket<0x3803, 30, 1>(ss, head_03, repeat); + } - RFIFO_BUF_CLONE(s, buf, len); - WBUFW(buf, 0) = 0x3803; - mapif_sendall(buf, len); + return rv; } // アカウント変数保存要求 -static -void mapif_parse_AccReg(Session *s) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_AccReg(Session *s) { - int j, p; - struct accreg *reg = accreg_db.search(RFIFOL(s, 4)); + Packet_Head<0x3004> head; + std::vector<Packet_Repeat<0x3004>> repeat; + RecvResult rv = recv_vpacket<0x3004, 8, 36>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + struct accreg *reg = accreg_db.search(head.account_id); - if (reg == NULL) + if (reg == nullptr) { - int account_id = RFIFOL(s, 4); + AccountId account_id = head.account_id; reg = accreg_db.init(account_id); reg->account_id = account_id; } - for (j = 0, p = 8; j < ACCOUNT_REG_NUM && p < RFIFOW(s, 2); - j++, p += 36) + size_t jlim = std::min(repeat.size(), ACCOUNT_REG_NUM); + for (size_t j = 0; j < jlim; ++j) { - reg->reg[j].str = stringish<VarName>(RFIFO_STRING<32>(s, p)); - reg->reg[j].value = RFIFOL(s, p + 32); + reg->reg[j].str = repeat[j].name; + reg->reg[j].value = repeat[j].value; } - reg->reg_num = j; + reg->reg_num = jlim; // 他のMAPサーバーに送信 - mapif_account_reg(s); + mapif_account_reg(s, head.account_id, repeat); + + return rv; } // アカウント変数送信要求 -static -void mapif_parse_AccRegRequest(Session *s) +static __attribute__((warn_unused_result)) +RecvResult mapif_parse_AccRegRequest(Session *s) { - mapif_account_reg_reply(s, RFIFOL(s, 2)); + Packet_Fixed<0x3005> fixed; + RecvResult rv = recv_fpacket<0x3005, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + mapif_account_reg_reply(s, fixed.account_id); + + return rv; } //-------------------------------------------------------- @@ -431,70 +449,42 @@ void mapif_parse_AccRegRequest(Session *s) // map server からの通信(1パケットのみ解析すること) // エラーなら0(false)、処理できたなら1、 // パケット長が足りなければ2をかえさなければならない -int inter_parse_frommap(Session *ms) +RecvResult inter_parse_frommap(Session *ms, uint16_t packet_id) { - int cmd = RFIFOW(ms, 0); - int len = 0; - - // inter鯖管轄かを調べる - if (cmd < 0x3000 - || cmd >= - 0x3000 + - (sizeof(inter_recv_packet_length) / - sizeof(inter_recv_packet_length[0]))) - return 0; - - // パケット長を調べる - if ((len = - inter_check_length(ms, - inter_recv_packet_length[cmd - 0x3000])) == 0) - return 2; + int cmd = packet_id; + + RecvResult rv; switch (cmd) { case 0x3000: - mapif_parse_GMmessage(ms); + rv = mapif_parse_GMmessage(ms); break; case 0x3001: - mapif_parse_WisRequest(ms); + rv = mapif_parse_WisRequest(ms); break; case 0x3002: - mapif_parse_WisReply(ms); + rv = mapif_parse_WisReply(ms); break; case 0x3003: - mapif_parse_WisToGM(ms); + rv = mapif_parse_WisToGM(ms); break; case 0x3004: - mapif_parse_AccReg(ms); + rv = mapif_parse_AccReg(ms); break; case 0x3005: - mapif_parse_AccRegRequest(ms); + rv = mapif_parse_AccRegRequest(ms); break; default: - if (inter_party_parse_frommap(ms)) - break; - if (inter_storage_parse_frommap(ms)) - break; - return 0; + rv = inter_party_parse_frommap(ms, packet_id); + if (rv != RecvResult::Error) + return rv; + rv = inter_storage_parse_frommap(ms, packet_id); + if (rv != RecvResult::Error) + return rv; + return RecvResult::Error; } - RFIFOSKIP(ms, len); - - return 1; -} - -// RFIFOのパケット長確認 -// 必要パケット長があればパケット長、まだ足りなければ0 -int inter_check_length(Session *s, int length) -{ - if (length == -1) - { // 可変パケット長 - if (RFIFOREST(s) < 4) // パケット長が未着 - return 0; - length = RFIFOW(s, 2); - } - - if (RFIFOREST(s) < length) // パケットが未着 - return 0; - return length; + return rv; } +} // namespace tmwa diff --git a/src/char/inter.hpp b/src/char/inter.hpp index 7d1a38b..19900f9 100644 --- a/src/char/inter.hpp +++ b/src/char/inter.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_CHAR_INTER_HPP -#define TMWA_CHAR_INTER_HPP +#pragma once // inter.hpp - Internal server. // // Copyright © ????-2004 Athena Dev Teams @@ -21,19 +20,19 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -struct Session; +#include "../net/fwd.hpp" + +namespace tmwa +{ bool inter_config(XString key, ZString value); void inter_init2(); void inter_save(void); -int inter_parse_frommap(Session *ms); - -int inter_check_length(Session *ms, int length); +RecvResult inter_parse_frommap(Session *ms, uint16_t packet_id); extern int party_share_level; - -#endif // TMWA_CHAR_INTER_HPP +} // namespace tmwa diff --git a/src/char/main.cpp b/src/char/main.cpp index 6814574..6636196 100644 --- a/src/char/main.cpp +++ b/src/char/main.cpp @@ -1,4 +1,3 @@ -#include "char.hpp" // char/main.cpp - dummy file to make Make dependencies work // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -18,4 +17,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include "char.hpp" + #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/compat/attr.hpp b/src/compat/attr.hpp index ea7ba86..238a5d5 100644 --- a/src/compat/attr.hpp +++ b/src/compat/attr.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_COMPAT_ATTR_HPP -#define TMWA_COMPAT_ATTR_HPP +#pragma once // attr.hpp - Attributes. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,13 +18,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# ifdef __clang__ -# define FALLTHROUGH [[clang::fallthrough]] -# else -# define FALLTHROUGH /* fallthrough */ -# endif - -#endif // TMWA_COMPAT_ATTR_HPP +namespace tmwa +{ +#ifdef __clang__ +# define FALLTHROUGH [[clang::fallthrough]] +#else +# define FALLTHROUGH /* fallthrough */ +#endif +} // namespace tmwa diff --git a/src/compat/cast.cpp b/src/compat/cast.cpp index 43c0b53..482529d 100644 --- a/src/compat/cast.cpp +++ b/src/compat/cast.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/compat/cast.hpp b/src/compat/cast.hpp index 8db486f..35dbc62 100644 --- a/src/compat/cast.hpp +++ b/src/compat/cast.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_COMPAT_CAST_HPP -#define TMWA_COMPAT_CAST_HPP +#pragma once // cast.hpp - Change the type of a variable. // // Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,12 +18,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <utility> -# include <type_traits> +#include <utility> +#include <type_traits> +namespace tmwa +{ template<class T> const T& const_(T& t) { @@ -68,5 +69,4 @@ typename std::remove_pointer<T>::type *sign_cast(U *u) static_assert(sizeof(T_) == sizeof(U), "sign cast must be same size"); return reinterpret_cast<T_ *>(u); } - -#endif // TMWA_COMPAT_CAST_HPP +} // namespace tmwa diff --git a/src/compat/fun.hpp b/src/compat/fun.hpp index 005f2c5..8073fe7 100644 --- a/src/compat/fun.hpp +++ b/src/compat/fun.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_COMPAT_FUN_HPP -#define TMWA_COMPAT_FUN_HPP +#pragma once // fun.hpp - Functional placeholders. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,13 +18,12 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <functional> - -# include "../sanity.hpp" +#include <functional> +namespace tmwa +{ namespace ph = std::placeholders; - -#endif // TMWA_COMPAT_FUN_HPP +} // namespace tmwa diff --git a/src/compat/fwd.hpp b/src/compat/fwd.hpp new file mode 100644 index 0000000..45f3c24 --- /dev/null +++ b/src/compat/fwd.hpp @@ -0,0 +1,27 @@ +#pragma once +// compat/fwd.hpp - list of type names for compat libs +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +// meh, add more when I feel like it +} // namespace tmwa diff --git a/src/compat/iter.cpp b/src/compat/iter.cpp index f0ab0af..b6d6b63 100644 --- a/src/compat/iter.cpp +++ b/src/compat/iter.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/compat/iter.hpp b/src/compat/iter.hpp index 7793d90..ff146a0 100644 --- a/src/compat/iter.hpp +++ b/src/compat/iter.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_COMPAT_ITER_HPP -#define TMWA_COMPAT_ITER_HPP +#pragma once // iter.hpp - tools for dealing with iterators // // Copyright © 2012-2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,11 +18,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <iterator> +#include <iterator> +namespace tmwa +{ /// Simple class to use a pair of iterators with foreach template<class It> class IteratorPair @@ -94,4 +95,59 @@ IteratorPair<ValueIterator<T>> value_range(T b, T e) return {b, e}; } -#endif // TMWA_COMPAT_ITER_HPP + +template<class T, class F, class C> +class FilterIterator +{ + F filter; + C *container; + + using InnerIterator = decltype(std::begin(*container)); + InnerIterator impl; +public: + void post_adv() + { + while (impl != std::end(*container)) + { + if (filter(*impl)) + break; + ++impl; + } + } + + FilterIterator(C *c, F f) + : filter(f), container(c), impl(std::begin(*c)) + { + post_adv(); + } + + void operator ++() + { + ++impl; + post_adv(); + } + + T operator *() + { + return *impl; + } + + friend + bool operator != (FilterIterator l, FilterIterator) + { + return l.impl != std::end(*l.container); + } +}; + +template<class T> +bool is_truthy(T v) +{ + return v; +} + +template<class T, class F=decltype(is_truthy<T>)*, class C> +IteratorPair<FilterIterator<T, F, C>> filter_iterator(C *c, F f=is_truthy<T>) +{ + return {FilterIterator<T, F, C>(c, f), FilterIterator<T, F, C>(c, f)}; +} +} // namespace tmwa diff --git a/src/compat/iter_test.cpp b/src/compat/iter_test.cpp index a07cb0f..6732c47 100644 --- a/src/compat/iter_test.cpp +++ b/src/compat/iter_test.cpp @@ -20,10 +20,15 @@ #include <gtest/gtest.h> -#include "../strings/xstring.hpp" +#include <algorithm> + +#include "../ints/udl.hpp" #include "../poison.hpp" + +namespace tmwa +{ TEST(iterpair, strings) { IteratorPair<ValueIterator<char>> pair = value_range('0', ':'); @@ -33,7 +38,7 @@ TEST(iterpair, strings) TEST(iterpair, signed8) { - IteratorPair<ValueIterator<int8_t>> pair = value_range(int8_t(-128), int8_t(127)); + IteratorPair<ValueIterator<int8_t>> pair = value_range(-128_n8, +127_p8); int8_t arr[255] = { -128, -127, -126, -125, -124, -123, -122, -121, -120, @@ -68,7 +73,7 @@ TEST(iterpair, signed8) TEST(iterpair, unsigned8) { - IteratorPair<ValueIterator<uint8_t>> pair = value_range(uint8_t(0), uint8_t(255)); + IteratorPair<ValueIterator<uint8_t>> pair = value_range(0_u8, 255_u8); uint8_t arr[255] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, @@ -100,3 +105,57 @@ TEST(iterpair, unsigned8) }; EXPECT_TRUE(std::equal(pair.begin(), pair.end(), arr)); } + +static +bool is_odd_ref(int& i) +{ + return i % 2; +} + +TEST(iterpair, filter1) +{ + int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; + + int expected_arr[] = {1, 3, 5, 7}; + int *expected_it = expected_arr; + int *expected_end = expected_arr + 4; + + for (int& i : filter_iterator<int&>(&arr, is_odd_ref)) + { + EXPECT_EQ(i, *expected_it); + ++expected_it; + } + EXPECT_EQ(expected_it, expected_end); +} + +TEST(iterpair, filter2) +{ + std::vector<int> vals = {0, 1, 0, 2, 0, 3, 0}; + + int sum = 0, count = 0; + for (int i : filter_iterator<int>(&vals)) + { + sum += i; + count++; + } + EXPECT_EQ(sum, 6); + EXPECT_EQ(count, 3); +} + +TEST(iterpair, filter3) +{ + int one = 1; + int two = 2; + int three = 3; + std::vector<int *> vals = {nullptr, &one, nullptr, &two, nullptr, &three, nullptr}; + + int sum = 0, count = 0; + for (int *i : filter_iterator<int *>(&vals)) + { + sum += *i; + count++; + } + EXPECT_EQ(sum, 6); + EXPECT_EQ(count, 3); +} +} // namespace tmwa diff --git a/src/compat/memory.cpp b/src/compat/memory.cpp index 5db23b2..f9f2c22 100644 --- a/src/compat/memory.cpp +++ b/src/compat/memory.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/compat/memory.hpp b/src/compat/memory.hpp index 2c0f742..566cc8b 100644 --- a/src/compat/memory.hpp +++ b/src/compat/memory.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_COMPAT_MEMORY_HPP -#define TMWA_COMPAT_MEMORY_HPP +#pragma once // memory.hpp - I forget ... // // Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,11 +18,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <memory> +#include <memory> +#include <type_traits> +namespace tmwa +{ template<class T> struct is_array_of_unknown_bound : std::is_same<T, typename std::remove_extent<T>::type[]> @@ -41,5 +43,4 @@ typename std::enable_if<is_array_of_unknown_bound<T>::value, std::unique_ptr<T, typedef typename std::remove_extent<T>::type E; return std::unique_ptr<E[], D>(new E[sz]()); } - -#endif // TMWA_COMPAT_MEMORY_HPP +} // namespace tmwa diff --git a/src/compat/nullpo.cpp b/src/compat/nullpo.cpp index a31cc34..bb80b27 100644 --- a/src/compat/nullpo.cpp +++ b/src/compat/nullpo.cpp @@ -24,6 +24,9 @@ #include "../poison.hpp" + +namespace tmwa +{ /// Actual output function static void nullpo_info(const char *file, int line, const char *func) @@ -46,3 +49,4 @@ bool nullpo_chk(const char *file, int line, const char *func, nullpo_info(file, line, func); return 1; } +} // namespace tmwa diff --git a/src/compat/nullpo.hpp b/src/compat/nullpo.hpp index 75f8110..5be674a 100644 --- a/src/compat/nullpo.hpp +++ b/src/compat/nullpo.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_COMPAT_NULLPO_HPP -#define TMWA_COMPAT_NULLPO_HPP +#pragma once // nullpo.hpp - Non-fatal pointer assertions. // // Copyright © ????-2004 Athena Dev Teams @@ -26,23 +25,28 @@ //# define BUG_FREE /// All functions print to standard error (was: standard output) -/// nullpo_ret(cond) - return 0 if given pointer is NULL +/// nullpo_retn(cond) - return nullptr if given pointer is nullptr +/// nullpo_retz(cond) - return 0 if given pointer is nullptr /// nullpo_retv(cond) - just return (function returns void) /// nullpo_retr(rv, cond) - return given value instead -# ifndef BUG_FREE -# define nullpo_retr(ret, t) \ +#ifndef BUG_FREE +# define nullpo_retr(ret, t) \ if (nullpo_chk(__FILE__, __LINE__, __PRETTY_FUNCTION__, t)) \ return ret; -# else // BUG_FREE -# define nullpo_retr(ret, t) /*t*/ -# endif // BUG_FREE +#else // BUG_FREE +# define nullpo_retr(ret, t) /*t*/ +#endif // BUG_FREE -# define nullpo_ret(t) nullpo_retr(0, t) -# define nullpo_retv(t) nullpo_retr(, t) +#define nullpo_retn(t) nullpo_retr(nullptr, t) +#define nullpo_retz(t) nullpo_retr(0, t) +#define nullpo_retv(t) nullpo_retr(, t) -# include "../sanity.hpp" +#include "fwd.hpp" + +namespace tmwa +{ /// Used by macros in this header bool nullpo_chk(const char *file, int line, const char *func, const void *target); @@ -57,5 +61,4 @@ bool nullpo_chk(const char *file, int line, const char *func, T *target) { return nullpo_chk(file, line, func, static_cast<const void *>(target)); } - -#endif // TMWA_COMPAT_NULLPO_HPP +} // namespace tmwa diff --git a/src/compat/rawmem.cpp b/src/compat/rawmem.cpp index 74fdc0b..d322437 100644 --- a/src/compat/rawmem.cpp +++ b/src/compat/rawmem.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/compat/rawmem.hpp b/src/compat/rawmem.hpp index bbe917c..c271a56 100644 --- a/src/compat/rawmem.hpp +++ b/src/compat/rawmem.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_COMPAT_RAWMEM_HPP -#define TMWA_COMPAT_RAWMEM_HPP +#pragma once // rawmem.hpp - Ignore poisoning and really frob this memory unsafely. // // Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,12 +18,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include <cstddef> -# include <cstdint> -# include <cstring> +#include <cstddef> +#include <cstdint> +#include <cstring> -# include "../sanity.hpp" +#include "fwd.hpp" + +namespace tmwa +{ inline void really_memcpy(uint8_t *dest, const uint8_t *src, size_t n) { @@ -47,5 +49,4 @@ void really_memset0(uint8_t *dest, size_t n) { memset(dest, '\0', n); } - -#endif // TMWA_COMPAT_RAWMEM_HPP +} // namespace tmwa diff --git a/src/compat/time_t.cpp b/src/compat/time_t.cpp new file mode 100644 index 0000000..ee0bbde --- /dev/null +++ b/src/compat/time_t.cpp @@ -0,0 +1,26 @@ +#include "time_t.hpp" +// time_t.cpp - time_t with a reliable representation +// +// Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/compat/time_t.hpp b/src/compat/time_t.hpp new file mode 100644 index 0000000..9e7cf25 --- /dev/null +++ b/src/compat/time_t.hpp @@ -0,0 +1,29 @@ +#pragma once +// time_t.hpp - time_t with a reliable representation +// +// Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +// TODO fix this ordering violation by promoting TimeT here +#include "../mmo/utils.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/conf/install.hpp b/src/conf/install.hpp new file mode 100644 index 0000000..42fd125 --- /dev/null +++ b/src/conf/install.hpp @@ -0,0 +1,30 @@ +#pragma once +// conf/install.hpp - Import configuration variables related to install. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// just mention "fwd.hpp" to make formatter happy + +#include "conf-raw/str-PACKAGESYSCONFDIR.h" +#include "conf-raw/str-PACKAGELOCALSTATEDIR.h" +#include "conf-raw/str-PACKAGEDATADIR.h" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/conf/version.hpp b/src/conf/version.hpp index ea394e6..df8a8b6 100644 --- a/src/conf/version.hpp +++ b/src/conf/version.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_CONF_VERSION_HPP -#define TMWA_CONF_VERSION_HPP +#pragma once // conf/version.hpp - Import configuration variables related to version. // // Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,20 +18,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +// just mention "fwd.hpp" to make formatter happy -# include "conf-raw/str-VERSION_FULL.h" -# include "conf-raw/str-VERSION_HASH.h" +#include "conf-raw/str-VERSION_FULL.h" +#include "conf-raw/str-VERSION_HASH.h" -# include "conf-raw/int-VERSION_MAJOR.h" -# include "conf-raw/int-VERSION_MINOR.h" -# include "conf-raw/int-VERSION_PATCH.h" -# include "conf-raw/int-VERSION_DEVEL.h" +#include "conf-raw/int-VERSION_MAJOR.h" +#include "conf-raw/int-VERSION_MINOR.h" +#include "conf-raw/int-VERSION_PATCH.h" +#include "conf-raw/int-VERSION_DEVEL.h" -# include "conf-raw/str-VENDOR_NAME.h" -# include "conf-raw/int-VENDOR_POINT.h" -# include "conf-raw/str-VENDOR_SOURCE.h" +#include "conf-raw/str-VENDOR_NAME.h" +#include "conf-raw/int-VENDOR_POINT.h" +#include "conf-raw/str-VENDOR_SOURCE.h" -# include "conf-raw/str-VERSION_STRING.h" +#include "conf-raw/str-VERSION_STRING.h" -#endif // TMWA_CONF_VERSION_HPP + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/diagnostics.hpp b/src/diagnostics.hpp new file mode 100644 index 0000000..31596dc --- /dev/null +++ b/src/diagnostics.hpp @@ -0,0 +1,1251 @@ +#pragma once +// diagnostics.hpp - List of useful warnings and macros to control them. +// +// Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// just mention "fwd.hpp" to make formatter happy + + +namespace tmwa +{ +// Notes about reading this file: +// * Currently only implemented for C++, but could work in C +// * the HAS_DIAG_ is subject to an additional check for clang +// * because token dispatching, it can't be #define HAS_XXX (GCC >= yyy) +// * gcc 4.6 is required for function scope pragmas +// * when upgrading compiler, diff 'gcc --help=warnings' +// * clang-specific warning support is incomplete + +// List of warnings that require arguments, +// and thus cannot reliably be activated: +// gcc 4.6: +// -Wlarger-than=<1024> +// -Wnormalized=<id|nfc|nfd> +// -Wsuggest-attribute=<noreturn,const,pure,format> +// gcc 4.7: +// -Wstack-usage=<8192> +// ???: +// -Wstrict-aliasing=<1> +// -Wstrict-overflow=<1> + +#ifdef __GNUC__ +# ifdef __clang__ +# define GCC (0) +# define CLANG (1) // clang's versions are vendor-specific - stupid apple +# else +# define GCC (__GNUC__ * 100 + __GNUC_MINOR__) +# define CLANG (0) +# endif +#endif + +#if GCC >= 406 || CLANG +# define PRAGMA(x) _Pragma(#x) static_assert(1, "I like my semicolons") +#else +# define PRAGMA(x) static_assert(1, "pragmas not available, can't do: " #x) +#endif + +#define DIAG_E(tag) DO_DIAG_IF(HAS_DIAG_##tag)(error, DIAG_##tag) +#define DIAG_W(tag) DO_DIAG_IF(HAS_DIAG_##tag)(warning, DIAG_##tag) +#define DIAG_I(tag) DO_DIAG_IF(HAS_DIAG_##tag)(ignored, DIAG_##tag) +#define DIAG_X(tag) DO_DIAG_IF(HAS_DIAG_##tag)(ignored, DIAG_##tag) + +#define DO_DIAG_IF(c) JOIN_PLEASE(PRAGMA_IF_,c) +#define JOIN_PLEASE(a, b) a##b +#define PRAGMA_IF_0(lvl, str) static_assert(1, "warning " #str " not enabled for this compiler version, sorry") +#if CLANG +# define PRAGMA_IF_1(lvl, str) DO_DIAG_IF2(__has_warning(str))(lvl, str) +# define DO_DIAG_IF2(s) JOIN_PLEASE(PRAGMA_IF2_, s) +# define PRAGMA_IF2_0(lvl, str) static_assert(1, "warning " #str " not available in this compiler version, sorry") +# define PRAGMA_IF2_1(lvl, str) PRAGMA(GCC diagnostic lvl str) +#else +# define PRAGMA_IF_1(lvl, str) PRAGMA(GCC diagnostic lvl str) +#endif + +#define DIAG_PUSH() PRAGMA(GCC diagnostic push) +#define DIAG_POP() PRAGMA(GCC diagnostic pop) + + +/// Warn about things that will change when compiling +/// with an ABI-compliant compiler +// see note about -fabi-version=6 in the makefile +#define DIAG_abi "-Wabi" +#if 1 +# define HAS_DIAG_abi 1 +#else +# define HAS_DIAG_abi 0 +#endif + +/// Warn if a subobject has an abi_tag attribute that +/// the complete object type does not have +#define DIAG_abi_tag "-Wabi-tag" +#if GCC >= 408 +# define HAS_DIAG_abi_tag 1 +#else +# define HAS_DIAG_abi_tag 0 +#endif + +/// Warn about suspicious uses of memory addresses +#define DIAG_address "-Waddress" +#if 1 +# define HAS_DIAG_address 1 +#else +# define HAS_DIAG_address 0 +#endif + +/// Warn about returning structures, unions or arrays +#define DIAG_aggregate_return "-Waggregate-return" +#if 1 +# define HAS_DIAG_aggregate_return 1 +#else +# define HAS_DIAG_aggregate_return 0 +#endif + +/// Warn if an array is accessed out of bounds +#define DIAG_array_bounds "-Warray-bounds" +#if 1 +# define HAS_DIAG_array_bounds 1 +#else +# define HAS_DIAG_array_bounds 0 +#endif + +/// Warn about inappropriate attribute usage +#define DIAG_attributes "-Wattributes" +#if 1 +# define HAS_DIAG_attributes 1 +#else +# define HAS_DIAG_attributes 0 +#endif + +/// Warn when a built-in preprocessor macro is +// undefined or redefined +#define DIAG_builtin_macro_redefined "-Wbuiltin-macro-redefined" +#if 1 +# define HAS_DIAG_builtin_macro_redefined 1 +#else +# define HAS_DIAG_builtin_macro_redefined 0 +#endif + +/// Warn about C++ constructs whose meaning differs +/// between ISO C++ 1998 and ISO C++ 2011 +#if CLANG || GCC >= 407 +# define DIAG_cxx0x_compat "-Wc++11-compat" +# define DIAG_cxx11_compat "-Wc++11-compat" +#else +# define DIAG_cxx0x_compat "-Wc++0x-compat" +# define DIAG_cxx11_compat "-Wc++0x-compat" +#endif +#if 1 +# define HAS_DIAG_cxx0x_compat 1 +# define HAS_DIAG_cxx11_compat 1 +#else +# define HAS_DIAG_cxx0x_compat 0 +# define HAS_DIAG_cxx11_compat 0 +#endif + +// I care about whether my code compiles with the standard as implemented +// by certain compilers, not whether it matches with an *exact* standard. +#define DIAG_cxx1y_extensions "-Wc++1y-extensions" +#if CLANG +# define HAS_DIAG_cxx1y_extensions 1 +#else +# define HAS_DIAG_cxx1y_extensions 0 +#endif + +/// Warn about pointer casts which increase alignment +#define DIAG_cast_align "-Wcast-align" +#if 1 +# define HAS_DIAG_cast_align 1 +#else +# define HAS_DIAG_cast_align 0 +#endif + +/// Warn about casts which discard qualifiers +#define DIAG_cast_qual "-Wcast-qual" +#if 1 +# define HAS_DIAG_cast_qual 1 +#else +# define HAS_DIAG_cast_qual 0 +#endif + +/// Warn about subscripts whose type is "char" +#define DIAG_char_subscripts "-Wchar-subscripts" +#if 1 +# define HAS_DIAG_char_subscripts 1 +#else +# define HAS_DIAG_char_subscripts 0 +#endif + +/// Warn about variables that might be changed by +/// "longjmp" or "vfork" +#define DIAG_clobbered "-Wclobbered" +#if GCC +# define HAS_DIAG_clobbered 1 +#else +# define HAS_DIAG_clobbered 0 +#endif + +/// Warn about possibly nested block comments, and +/// C++ comments spanning more than one physical line +#define DIAG_comment "-Wcomment" +#if 1 +# define HAS_DIAG_comment 1 +#else +# define HAS_DIAG_comment 0 +#endif + +/// Warn for conditionally-supported constructs +#define DIAG_conditionally_supported "-Wconditionally-supported" +#if GCC >= 409 +# define HAS_DIAG_conditionally_supported 1 +#else +# define HAS_DIAG_conditionally_supported 0 +#endif + +// A fixable difference between c++11 and c++14 +#define DIAG_constexpr_not_const "-Wconstexpr-not-const" +#if CLANG +# define HAS_DIAG_constexpr_not_const 1 +#else +# define HAS_DIAG_constexpr_not_const 0 +#endif + +/// Warn for implicit type conversions that may +/// change a value +#define DIAG_conversion "-Wconversion" +#if 1 +# define HAS_DIAG_conversion 1 +#else +# define HAS_DIAG_conversion 0 +#endif + +/// Warn for converting NULL from/to a non-pointer +/// type +#define DIAG_conversion_null "-Wconversion-null" +#if 1 +# define HAS_DIAG_conversion_null 1 +#else +# define HAS_DIAG_conversion_null 0 +#endif + +/// Warn in case profiles in -fprofile-use do not +/// match +#define DIAG_coverage_mismatch "-Wcoverage-mismatch" +#if GCC +# define HAS_DIAG_coverage_mismatch 1 +#else +# define HAS_DIAG_coverage_mismatch 0 +#endif + +/// +#define DIAG_covered_switch_default "-Wcovered-switch-default" +#if CLANG +# define HAS_DIAG_covered_switch_default 1 +#else +# define HAS_DIAG_covered_switch_default 0 +#endif + +/// Warn when a #warning directive is encountered +#define DIAG_cpp "-Wcpp" +#if GCC +# define HAS_DIAG_cpp 1 +#else +# define HAS_DIAG_cpp 0 +#endif + +/// Warn when all constructors and destructors are +/// private +#define DIAG_ctor_dtor_privacy "-Wctor-dtor-privacy" +#if 1 +# define HAS_DIAG_ctor_dtor_privacy 1 +#else +# define HAS_DIAG_ctor_dtor_privacy 0 +#endif + +/// Warn about __TIME__, __DATE__ and __TIMESTAMP__ +/// usage +#define DIAG_date_time "-Wdate-time" +#if GCC >= 409 +# define HAS_DIAG_date_time 1 +#else +# define HAS_DIAG_date_time 0 +#endif + +/// Warn when deleting a pointer to incomplete type +#define DIAG_delete_incomplete "-Wdelete-incomplete" +#if GCC >= 409 +# define HAS_DIAG_delete_incomplete 1 +#else +# define HAS_DIAG_delete_incomplete 0 +#endif + +/// Warn about deleting polymorphic objects with non- +/// virtual destructors +#define DIAG_delete_non_virtual_dtor "-Wdelete-non-virtual-dtor" +#if GCC >= 407 +# define HAS_DIAG_delete_non_virtual_dtor 1 +#else +# define HAS_DIAG_delete_non_virtual_dtor 0 +#endif + +/// Warn if a deprecated compiler feature, class, +/// method, or field is used +#define DIAG_deprecated "-Wdeprecated" +#if 1 +# define HAS_DIAG_deprecated 1 +#else +# define HAS_DIAG_deprecated 0 +#endif + +/// Warn about uses of __attribute__((deprecated)") +/// declarations +#define DIAG_deprecated_declarations "-Wdeprecated-declarations" +#if 1 +# define HAS_DIAG_deprecated_declarations 1 +#else +# define HAS_DIAG_deprecated_declarations 0 +#endif + +/// Warn when an optimization pass is disabled +#define DIAG_disabled_optimization "-Wdisabled-optimization" +#if 1 +# define HAS_DIAG_disabled_optimization 1 +#else +# define HAS_DIAG_disabled_optimization 0 +#endif + +/// Warn about compile-time integer division by zero +#define DIAG_div_by_zero "-Wdiv-by-zero" +#if 1 +# define HAS_DIAG_div_by_zero 1 +#else +# define HAS_DIAG_div_by_zero 0 +#endif + +/// +#define DIAG_documentation "-Wdocumentation" +#if CLANG +# define HAS_DIAG_documentation 1 +#else +# define HAS_DIAG_documentation 0 +#endif + +/// Warn about implicit conversions from "float" to +/// "double" +#define DIAG_double_promotion "-Wdouble-promotion" +#if GCC +# define HAS_DIAG_double_promotion 1 +#else +# define HAS_DIAG_double_promotion 0 +#endif + +/// Warn about violations of Effective C++ style rules +#define DIAG_effcxx "-Weffc++" +#if 1 +# define HAS_DIAG_effcxx 1 +#else +# define HAS_DIAG_effcxx 0 +#endif + +/// Warn about an empty body in an if or else +/// statement +#define DIAG_empty_body "-Wempty-body" +#if 1 +# define HAS_DIAG_empty_body 1 +#else +# define HAS_DIAG_empty_body 0 +#endif + +/// Warn about stray tokens after #elif and #endif +#define DIAG_endif_labels "-Wendif-labels" +#if 1 +# define HAS_DIAG_endif_labels 1 +#else +# define HAS_DIAG_endif_labels 0 +#endif + +/// Warn about comparison of different enum types +#define DIAG_enum_compare "-Wenum-compare" +#if 1 +# define HAS_DIAG_enum_compare 1 +#else +# define HAS_DIAG_enum_compare 0 +#endif + +/// +#define DIAG_extra_semi "-Wextra-semi" +#if CLANG +# define HAS_DIAG_extra_semi 1 +#else +# define HAS_DIAG_extra_semi 0 +#endif + +/// Warn if testing floating point numbers for +/// equality +#define DIAG_float_equal "-Wfloat-equal" +#if 1 +# define HAS_DIAG_float_equal 1 +#else +# define HAS_DIAG_float_equal 0 +#endif + +/// Warn about printf/scanf/strftime/strfmon format +/// string anomalies +// see below +#define DIAG_format "-Wformat" +#if GCC +# define HAS_DIAG_format 1 +#else +# define HAS_DIAG_format 0 +#endif +// but gcc 4.8 warns on %ms, since we enabled -Wpedantic. +//WG48("-Wformat") + +/// Warn about format strings that contain NUL bytes +#define DIAG_format_contains_nul "-Wformat-contains-nul" +#if GCC +# define HAS_DIAG_format_contains_nul 1 +#else +# define HAS_DIAG_format_contains_nul 0 +#endif + +/// Warn if passing too many arguments to a function +/// for its format string +#define DIAG_format_extra_args "-Wformat-extra-args" +#if 1 +# define HAS_DIAG_format_extra_args 1 +#else +# define HAS_DIAG_format_extra_args 0 +#endif + +/// Warn about format strings that are not literals +// Available in clang, but not smart enough to handle constexpr. +#define DIAG_format_nonliteral "-Wformat-nonliteral" +#if GCC || (CLANG && 1) +# define HAS_DIAG_format_nonliteral 1 +#else +# define HAS_DIAG_format_nonliteral 0 +#endif + +/// Warn about possible security problems with format +/// functions +// Same. +#define DIAG_format_security "-Wformat-security" +#if GCC || (CLANG && 1) +# define HAS_DIAG_format_security 1 +#else +# define HAS_DIAG_format_security 0 +#endif + +/// Warn about strftime formats yielding 2-digit years +#define DIAG_format_y2k "-Wformat-y2k" +#if 1 +# define HAS_DIAG_format_y2k 1 +#else +# define HAS_DIAG_format_y2k 0 +#endif + +/// Warn about zero-length formats +#define DIAG_format_zero_length "-Wformat-zero-length" +#if 1 +# define HAS_DIAG_format_zero_length 1 +#else +# define HAS_DIAG_format_zero_length 0 +#endif + +/// Warn when attempting to free a non-heap object +#define DIAG_free_nonheap_object "-Wfree-nonheap-object" +#if GCC >= 407 +# define HAS_DIAG_free_nonheap_object 1 +#else +# define HAS_DIAG_free_nonheap_object 0 +#endif + +// -Wgnu is a clang alias for -Wpedantic + +// Foo{x: y} +#define DIAG_gnu_designator "-Wgnu-designator" +#if CLANG +# define HAS_DIAG_gnu_designator 1 +#else +# define HAS_DIAG_gnu_designator 0 +#endif + + +/// Warn whenever type qualifiers are ignored. +#define DIAG_ignored_qualifiers "-Wignored-qualifiers" +#if 1 +# define HAS_DIAG_ignored_qualifiers 1 +#else +# define HAS_DIAG_ignored_qualifiers 0 +#endif + +/// +#define DIAG_implicit_fallthrough "-Wimplicit-fallthrough" +#if CLANG +# define HAS_DIAG_implicit_fallthrough 1 +#else +# define HAS_DIAG_implicit_fallthrough 0 +#endif + +/// Warn about C++11 inheriting constructors when the +/// base has a variadic constructor +#define DIAG_inherited_variadic_ctor "-Winherited-variadic-ctor" +#if GCC >= 408 +# define HAS_DIAG_inherited_variadic_ctor 1 +#else +# define HAS_DIAG_inherited_variadic_ctor 0 +#endif + +/// Warn about variables which are initialized to +/// themselves +#define DIAG_init_self "-Winit-self" +#if 1 +# define HAS_DIAG_init_self 1 +#else +# define HAS_DIAG_init_self 0 +#endif + +/// Warn when an inlined function cannot be inlined +#define DIAG_inline "-Winline" +#if 1 +# define HAS_DIAG_inline 1 +#else +# define HAS_DIAG_inline 0 +#endif + +/// Warn when there is a cast to a pointer from an +/// integer of a different size +#define DIAG_int_to_pointer_cast "-Wint-to-pointer-cast" +#if 1 +# define HAS_DIAG_int_to_pointer_cast 1 +#else +# define HAS_DIAG_int_to_pointer_cast 0 +#endif + +/// Warn when an atomic memory model parameter is +/// known to be outside the valid range. +#define DIAG_invalid_memory_model "-Winvalid-memory-model" +#if GCC >= 407 +# define HAS_DIAG_invalid_memory_model 1 +#else +# define HAS_DIAG_invalid_memory_model 0 +#endif + +/// Warn about invalid uses of the "offsetof" macro +#define DIAG_invalid_offsetof "-Winvalid-offsetof" +#if 1 +# define HAS_DIAG_invalid_offsetof 1 +#else +# define HAS_DIAG_invalid_offsetof 0 +#endif + +/// Warn about PCH files that are found but not used +#define DIAG_invalid_pch "-Winvalid-pch" +#if 1 +# define HAS_DIAG_invalid_pch 1 +#else +# define HAS_DIAG_invalid_pch 0 +#endif + +/// Warn when a string or character literal is +/// followed by a ud-suffix which does not begin with +/// an underscore. +#define DIAG_literal_suffix "-Wliteral-suffix" +#if GCC >= 408 +# define HAS_DIAG_literal_suffix 1 +#else +# define HAS_DIAG_literal_suffix 0 +#endif + +/// Warn when a logical operator is suspiciously +/// always evaluating to true or false +#define DIAG_logical_op "-Wlogical-op" +#if GCC +# define HAS_DIAG_logical_op 1 +#else +# define HAS_DIAG_logical_op 0 +#endif + +/// Do not warn about using "long long" when -pedantic +#define DIAG_long_long "-Wlong-long" +#if 1 +# define HAS_DIAG_long_long 1 +#else +# define HAS_DIAG_long_long 0 +#endif + +/// Warn about suspicious declarations of "main" +#define DIAG_main "-Wmain" +#if 1 +# define HAS_DIAG_main 1 +#else +# define HAS_DIAG_main 0 +#endif + +/// Warn about maybe uninitialized automatic variables +#define DIAG_maybe_uninitialized "-Wmaybe-uninitialized" +#if GCC >= 407 +# define HAS_DIAG_maybe_uninitialized 1 +#else +# define HAS_DIAG_maybe_uninitialized 0 +#endif + +// bitch about 'struct Foo' vs 'class Foo' +#define DIAG_mismatched_tags "-Wmismatched-tags" +#if CLANG +# define HAS_DIAG_mismatched_tags 1 +#else +# define HAS_DIAG_mismatched_tags 0 +#endif + +/// Warn about possibly missing braces around +/// initializers +// beware of things like std::array! +#define DIAG_missing_braces "-Wmissing-braces" +#if 1 +# define HAS_DIAG_missing_braces 1 +#else +# define HAS_DIAG_missing_braces 0 +#endif + +/// Warn about global functions without previous +/// declarations +// This doesn't work for clang, it wants -Wmissing-prototypes instead. +#define DIAG_missing_declarations "-Wmissing-declarations" +#if 1 +# define HAS_DIAG_missing_declarations 1 +#else +# define HAS_DIAG_missing_declarations 0 +#endif + +/// Warn about missing fields in struct initializers +// Actually supported by GCC, but gives warnings when I don't want, e.g.: +// Foo foo = {}; +#define DIAG_missing_field_initializers "-Wmissing-field-initializers" +#if CLANG || (GCC && 1) +# define HAS_DIAG_missing_field_initializers 1 +#else +# define HAS_DIAG_missing_field_initializers 0 +#endif + +/// Warn about functions which might be candidates +/// for format attributes +#define DIAG_missing_format_attribute "-Wmissing-format-attribute" +#if 1 +# define HAS_DIAG_missing_format_attribute 1 +#else +# define HAS_DIAG_missing_format_attribute 0 +#endif + +/// Warn about user-specified include directories +/// that do not exist +#define DIAG_missing_include_dirs "-Wmissing-include-dirs" +#if 1 +# define HAS_DIAG_missing_include_dirs 1 +#else +# define HAS_DIAG_missing_include_dirs 0 +#endif + +/// Warn about functions which might be candidates +/// for __attribute__((noreturn)") +#define DIAG_missing_noreturn "-Wmissing-noreturn" +#if 1 +# define HAS_DIAG_missing_noreturn 1 +#else +# define HAS_DIAG_missing_noreturn 0 +#endif + +// clang uses this instead of -Wmissing-declarations +#define DIAG_missing_prototypes "-Wmissing-prototypes" +#if CLANG +# define HAS_DIAG_missing_prototypes 1 +#else +# define HAS_DIAG_missing_prototypes 0 +#endif + +/// +// like -Wmissing-declarations but for variables instead of functions +#define DIAG_missing_variable_declarations "-Wmissing-variable-declarations" +#if CLANG +# define HAS_DIAG_missing_variable_declarations 1 +#else +# define HAS_DIAG_missing_variable_declarations 0 +#endif + +/// Warn about constructs not instrumented by +/// -fmudflap +#define DIAG_mudflap "-Wmudflap" +#if GCC +# define HAS_DIAG_mudflap 1 +#else +# define HAS_DIAG_mudflap 0 +#endif + +/// Warn about use of multi-character character +/// constants +#define DIAG_multichar "-Wmultichar" +#if 1 +# define HAS_DIAG_multichar 1 +#else +# define HAS_DIAG_multichar 0 +#endif + +/// Warn about narrowing conversions within { } that +/// are ill-formed in C++11 +#define DIAG_narrowing "-Wnarrowing" +#if GCC >= 407 +# define HAS_DIAG_narrowing 1 +#else +# define HAS_DIAG_narrowing 0 +#endif + +/// Warn when a noexcept expression evaluates to +/// false even though the expression can't actually +/// throw +#define DIAG_noexcept "-Wnoexcept" +#if GCC +# define HAS_DIAG_noexcept 1 +#else +# define HAS_DIAG_noexcept 0 +#endif + +/// Warn when non-templatized friend functions are +/// declared within a template +#define DIAG_non_template_friend "-Wnon-template-friend" +#if GCC +# define HAS_DIAG_non_template_friend 1 +#else +# define HAS_DIAG_non_template_friend 0 +#endif + +/// Warn about non-virtual destructors +#define DIAG_non_virtual_dtor "-Wnon-virtual-dtor" +#if 1 +# define HAS_DIAG_non_virtual_dtor 1 +#else +# define HAS_DIAG_non_virtual_dtor 0 +#endif + +/// Warn about NULL being passed to argument slots +/// marked as requiring non-NULL +#define DIAG_nonnull "-Wnonnull" +#if 1 +# define HAS_DIAG_nonnull 1 +#else +# define HAS_DIAG_nonnull 0 +#endif + +/// +#define DIAG_null_conversion "-Wnull-conversion" +#if CLANG +# define HAS_DIAG_null_conversion 1 +#else +# define HAS_DIAG_null_conversion 0 +#endif + +/// Warn if a C-style cast is used in a program +#define DIAG_old_style_cast "-Wold-style-cast" +#if 1 +# define HAS_DIAG_old_style_cast 1 +#else +# define HAS_DIAG_old_style_cast 0 +#endif + +/// Warn about overflow in arithmetic expressions +#define DIAG_overflow "-Woverflow" +#if 1 +# define HAS_DIAG_overflow 1 +#else +# define HAS_DIAG_overflow 0 +#endif + +/// Warn if a simd directive is overridden by the +/// vectorizer cost model +#define DIAG_openmp_simd "-Wopenmp-simd" +#if GCC >= 409 +# define HAS_DIAG_openmp_simd 1 +#else +# define HAS_DIAG_openmp_simd 0 +#endif + +/// Warn if a string is longer than the maximum +/// portable length specified by the standard +//X("-Woverlength-strings") + +/// Warn about overloaded virtual function names +#define DIAG_overloaded_virtual "-Woverloaded-virtual" +#if 1 +# define HAS_DIAG_overloaded_virtual 1 +#else +# define HAS_DIAG_overloaded_virtual 0 +#endif + +/// Warn when the packed attribute has no effect on +/// struct layout +#define DIAG_packed "-Wpacked" +#if 1 +# define HAS_DIAG_packed 1 +#else +# define HAS_DIAG_packed 0 +#endif + +/// Warn about packed bit-fields whose offset changed +/// in GCC 4.4 +#define DIAG_packed_bitfield_compat "-Wpacked-bitfield-compat" +#if GCC +# define HAS_DIAG_packed_bitfield_compat 1 +#else +# define HAS_DIAG_packed_bitfield_compat 0 +#endif + +/// Warn when padding is required to align structure +/// members +#define DIAG_padded "-Wpadded" +#if 1 +# define HAS_DIAG_padded 1 +#else +# define HAS_DIAG_padded 0 +#endif + +/// Warn about possibly missing parentheses +#define DIAG_parentheses "-Wparentheses" +#if 1 +# define HAS_DIAG_parentheses 1 +#else +# define HAS_DIAG_parentheses 0 +#endif + +/// Issue warnings needed for strict compliance to +/// the standard +// a bit too noisy +//EG48("-Wpedantic") +// lots of minor extensions are used +#define DIAG_pedantic "-Wpedantic" +#if GCC >= 408 || CLANG +# define HAS_DIAG_pedantic 1 +#else +# define HAS_DIAG_pedantic 0 +#endif + +/// Warn when converting the type of pointers to +/// member functions +#define DIAG_pmf_conversions "-Wpmf-conversions" +#if GCC +# define HAS_DIAG_pmf_conversions 1 +#else +# define HAS_DIAG_pmf_conversions 0 +#endif + +/// Warn about function pointer arithmetic +#define DIAG_pointer_arith "-Wpointer-arith" +#if 1 +# define HAS_DIAG_pointer_arith 1 +#else +# define HAS_DIAG_pointer_arith 0 +#endif + +/// Warn about misuses of pragmas +#define DIAG_pragmas "-Wpragmas" +#if GCC +# define HAS_DIAG_pragmas 1 +#else +# define HAS_DIAG_pragmas 0 +#endif + +/// Warn about multiple declarations of the same +/// object +#define DIAG_redundant_decls "-Wredundant-decls" +#if 1 +# define HAS_DIAG_redundant_decls 1 +#else +# define HAS_DIAG_redundant_decls 0 +#endif + +/// Warn when the compiler reorders code +#define DIAG_reorder "-Wreorder" +#if 1 +# define HAS_DIAG_reorder 1 +#else +# define HAS_DIAG_reorder 0 +#endif + +/// Warn about returning a pointer/reference to a +/// local or temporary variable. +#define DIAG_return_local_addr "-Wreturn-local-addr" +#if GCC >= 408 +# define HAS_DIAG_return_local_addr 1 +#else +# define HAS_DIAG_return_local_addr 0 +#endif + +/// Warn whenever a function's return type defaults +/// to "int" (C), or about inconsistent return types +/// (C++") +#define DIAG_return_type "-Wreturn-type" +#if 1 +# define HAS_DIAG_return_type 1 +#else +# define HAS_DIAG_return_type 0 +#endif + +/// Warn about possible violations of sequence point +/// rules +#define DIAG_sequence_point "-Wsequence-point" +#if 1 +# define HAS_DIAG_sequence_point 1 +#else +# define HAS_DIAG_sequence_point 0 +#endif + +/// Warn when one local variable shadows another +#define DIAG_shadow "-Wshadow" +#if 1 +# define HAS_DIAG_shadow 1 +#else +# define HAS_DIAG_shadow 0 +#endif + +/// Warn about signed-unsigned comparisons +#define DIAG_sign_compare "-Wsign-compare" +#if 1 +# define HAS_DIAG_sign_compare 1 +#else +# define HAS_DIAG_sign_compare 0 +#endif + +/// Warn when overload promotes from unsigned to +/// signed +#define DIAG_sign_promo "-Wsign-promo" +#if 1 +# define HAS_DIAG_sign_promo 1 +#else +# define HAS_DIAG_sign_promo 0 +#endif + +/// This switch lacks documentation +#define DIAG_sizeof_pointer_memaccess "-Wsizeof-pointer-memaccess" +#if GCC >= 408 +# define HAS_DIAG_sizeof_pointer_memaccess 1 +#else +# define HAS_DIAG_sizeof_pointer_memaccess 0 +#endif + +/// Warn when not issuing stack smashing protection +/// for some reason +#define DIAG_stack_protector "-Wstack-protector" +#if 1 +# define HAS_DIAG_stack_protector 1 +#else +# define HAS_DIAG_stack_protector 0 +#endif + +/// Warn about code which might break strict aliasing +/// rules +#define DIAG_strict_aliasing "-Wstrict-aliasing" +#if 1 +# define HAS_DIAG_strict_aliasing 1 +#else +# define HAS_DIAG_strict_aliasing 0 +#endif + +/// Warn about uncasted NULL used as sentinel +#define DIAG_strict_null_sentinel "-Wstrict-null-sentinel" +#if GCC +# define HAS_DIAG_strict_null_sentinel 1 +#else +# define HAS_DIAG_strict_null_sentinel 0 +#endif + +/// Warn about optimizations that assume that signed +/// overflow is undefined +#define DIAG_strict_overflow "-Wstrict-overflow" +#if 1 +# define HAS_DIAG_strict_overflow 1 +#else +# define HAS_DIAG_strict_overflow 0 +#endif + +/// Warn about enumerated switches, with no default, +/// missing a case +#define DIAG_switch "-Wswitch" +#if 1 +# define HAS_DIAG_switch 1 +#else +# define HAS_DIAG_switch 0 +#endif + +/// Warn about enumerated switches missing a +/// "default:" statement +#define DIAG_switch_default "-Wswitch-default" +#if 1 +# define HAS_DIAG_switch_default 1 +#else +# define HAS_DIAG_switch_default 0 +#endif + +/// Warn about all enumerated switches missing a +/// specific case +#define DIAG_switch_enum "-Wswitch-enum" +#if 1 +# define HAS_DIAG_switch_enum 1 +#else +# define HAS_DIAG_switch_enum 0 +#endif + +/// Warn when __sync_fetch_and_nand and +/// __sync_nand_and_fetch built-in functions are used +#define DIAG_sync_nand "-Wsync-nand" +#if GCC +# define HAS_DIAG_sync_nand 1 +#else +# define HAS_DIAG_sync_nand 0 +#endif + +/// Warn whenever a trampoline is generated +#define DIAG_trampolines "-Wtrampolines" +#if GCC +# define HAS_DIAG_trampolines 1 +#else +# define HAS_DIAG_trampolines 0 +#endif + +/// Warn if trigraphs are encountered that might +/// affect the meaning of the program +#define DIAG_trigraphs "-Wtrigraphs" +#if 1 +# define HAS_DIAG_trigraphs 1 +#else +# define HAS_DIAG_trigraphs 0 +#endif + +/// Warn if a comparison is always true or always +/// false due to the limited range of the data type +#define DIAG_type_limits "-Wtype-limits" +#if 1 +# define HAS_DIAG_type_limits 1 +#else +# define HAS_DIAG_type_limits 0 +#endif + +/// Warn if an undefined macro is used in an #if +/// directive +#define DIAG_undef "-Wundef" +#if 1 +# define HAS_DIAG_undef 1 +#else +# define HAS_DIAG_undef 0 +#endif + +/// Warn about uninitialized automatic variables +#define DIAG_uninitialized "-Wuninitialized" +#if 1 +# define HAS_DIAG_uninitialized 1 +#else +# define HAS_DIAG_uninitialized 0 +#endif + +/// Warn about unrecognized pragmas +#define DIAG_unknown_pragmas "-Wunknown-pragmas" +#if 1 +# define HAS_DIAG_unknown_pragmas 1 +#else +# define HAS_DIAG_unknown_pragmas 0 +#endif + +/// +// Not an error because of some remaining enum+default +#define DIAG_unreachable_code "-Wunreachable-code" +#if CLANG +# define HAS_DIAG_unreachable_code 1 +#else +# define HAS_DIAG_unreachable_code 0 +#endif + +/// Warn if the loop cannot be optimized due to +/// nontrivial assumptions. +#define DIAG_unsafe_loop_optimizations "-Wunsafe-loop-optimizations" +#if GCC +# define HAS_DIAG_unsafe_loop_optimizations 1 +#else +# define HAS_DIAG_unsafe_loop_optimizations 0 +#endif + +/// Warn when a function parameter is only set, +/// otherwise unused +#define DIAG_unused_but_set_parameter "-Wunused-but-set-parameter" +#if GCC +# define HAS_DIAG_unused_but_set_parameter 1 +#else +# define HAS_DIAG_unused_but_set_parameter 0 +#endif + +/// Warn when a variable is only set, otherwise unused +#define DIAG_unused_but_set_variable "-Wunused-but-set-variable" +#if GCC +# define HAS_DIAG_unused_but_set_variable 1 +#else +# define HAS_DIAG_unused_but_set_variable 0 +#endif + +/// Warn when a function is unused +#define DIAG_unused_function "-Wunused-function" +#if 1 +# define HAS_DIAG_unused_function 1 +#else +# define HAS_DIAG_unused_function 0 +#endif + +/// Warn when a label is unused +#define DIAG_unused_label "-Wunused-label" +#if 1 +# define HAS_DIAG_unused_label 1 +#else +# define HAS_DIAG_unused_label 0 +#endif + +/// Warn when typedefs locally defined in a function +/// are not used +#define DIAG_unused_local_typedefs "-Wunused-local-typedefs" +#if GCC >= 407 +# define HAS_DIAG_unused_local_typedefs 1 +#else +# define HAS_DIAG_unused_local_typedefs 0 +#endif + +/// Warn about macros defined in the main file that +/// are not used +#define DIAG_unused_macros "-Wunused-macros" +#if 1 +# define HAS_DIAG_unused_macros 1 +#else +# define HAS_DIAG_unused_macros 0 +#endif + +/// Warn when a function parameter is unused +#define DIAG_unused_parameter "-Wunused-parameter" +#if 1 +# define HAS_DIAG_unused_parameter 1 +#else +# define HAS_DIAG_unused_parameter 0 +#endif + +/// Warn if a caller of a function, marked with +/// attribute warn_unused_result, does not use its +/// return value +#define DIAG_unused_result "-Wunused-result" +#if 1 +# define HAS_DIAG_unused_result 1 +#else +# define HAS_DIAG_unused_result 0 +#endif + +/// Warn when an expression value is unused +#define DIAG_unused_value "-Wunused-value" +#if 1 +# define HAS_DIAG_unused_value 1 +#else +# define HAS_DIAG_unused_value 0 +#endif + +/// Warn when a variable is unused +#define DIAG_unused_variable "-Wunused-variable" +#if 1 +# define HAS_DIAG_unused_variable 1 +#else +# define HAS_DIAG_unused_variable 0 +#endif + +/// Warn about useless casts +#define DIAG_useless_cast "-Wuseless-cast" +#if GCC >= 408 +# define HAS_DIAG_useless_cast 1 +#else +# define HAS_DIAG_useless_cast 0 +#endif + +/// Warn about questionable usage of the macros used +/// to retrieve variable arguments +#define DIAG_varargs "-Wvarargs" +#if GCC >= 408 +# define HAS_DIAG_varargs 1 +#else +# define HAS_DIAG_varargs 0 +#endif + +/// Warn about using variadic macros +#define DIAG_variadic_macros "-Wvariadic-macros" +#if 1 +# define HAS_DIAG_variadic_macros 1 +#else +# define HAS_DIAG_variadic_macros 0 +#endif + +/// Warn when a vector operation is compiled +/// outside the SIMD +#define DIAG_vector_operation_performance "-Wvector-operation-performance" +#if GCC >= 407 +# define HAS_DIAG_vector_operation_performance 1 +#else +# define HAS_DIAG_vector_operation_performance 0 +#endif + +/// Warn if a virtual base has a non-trivial move +/// assignment operator +#define DIAG_virtual_move_assign "-Wvirtual-move-assign" +#if GCC >= 408 +# define HAS_DIAG_virtual_move_assign 1 +#else +# define HAS_DIAG_virtual_move_assign 0 +#endif + +/// Warn if a variable length array is used +#define DIAG_vla "-Wvla" +#if 1 +# define HAS_DIAG_vla 1 +#else +# define HAS_DIAG_vla 0 +#endif + +/// Warn when a register variable is declared volatile +#define DIAG_volatile_register_var "-Wvolatile-register-var" +#if 1 +# define HAS_DIAG_volatile_register_var 1 +#else +# define HAS_DIAG_volatile_register_var 0 +#endif + +/// In C++, nonzero means warn about deprecated +/// conversion from string literals to 'char *'. In +/// C, similar warning, except that the conversion is +/// of course not deprecated by the ISO C standard. +#define DIAG_write_strings "-Wwrite-strings" +#if 1 +# define HAS_DIAG_write_strings 1 +#else +# define HAS_DIAG_write_strings 0 +#endif + +/// Warn when a literal '0' is used as null +/// pointer +#define DIAG_zero_as_null_pointer_constant "-Wzero-as-null-pointer-constant" +#if GCC >= 407 +# define HAS_DIAG_zero_as_null_pointer_constant 1 +#else +# define HAS_DIAG_zero_as_null_pointer_constant 0 +#endif +} // namespace tmwa diff --git a/src/spell-convert/main.cpp b/src/generic/array.cpp index 0c0d04e..3063569 100644 --- a/src/spell-convert/main.cpp +++ b/src/generic/array.cpp @@ -1,4 +1,5 @@ -// spell-convert/main.cpp - Hacky magic conversion driver. +#include "array.hpp" +// array.cpp - A simple bounds-checked array. // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> // @@ -17,12 +18,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include "lexer.hpp" -#include "parser.hpp" - #include "../poison.hpp" -int main() + +namespace tmwa { - spell_converterparse(); -} +} // namespace tmwa diff --git a/src/generic/array.hpp b/src/generic/array.hpp new file mode 100644 index 0000000..dccb91e --- /dev/null +++ b/src/generic/array.hpp @@ -0,0 +1,118 @@ +#pragma once +// array.hpp - A simple bounds-checked array. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include <cassert> +#include <cstddef> + +#include "oops.hpp" + + +namespace tmwa +{ +template<class I, I be, I en> +struct ExclusiveIndexing +{ + using index_type = I; + constexpr static size_t index_to_offset(index_type idx) + { return static_cast<size_t>(idx) - static_cast<size_t>(be); } + constexpr static index_type offset_to_index(size_t off) + { return static_cast<I>(off + static_cast<size_t>(be)); } + constexpr static size_t alloc_size = index_to_offset(en) - index_to_offset(be); +}; + +template<size_t n> +using SimpleIndexing = ExclusiveIndexing<size_t, 0, n>; + +template<class I, I lo, I hi> +struct InclusiveIndexing +{ + using index_type = I; + constexpr static size_t index_to_offset(index_type idx) + { return static_cast<size_t>(idx) - static_cast<size_t>(lo); } + constexpr static index_type offset_to_index(size_t off) + { return static_cast<I>(off + static_cast<size_t>(lo)); } + constexpr static size_t alloc_size = index_to_offset(hi) - index_to_offset(lo) + 1; +}; + +template<class E, E n=E::COUNT> +struct EnumIndexing : ExclusiveIndexing<E, static_cast<E>(0), n> +{ +}; + +template<class I, size_t limit> +struct InventoryIndexing +{ + using index_type = I; + constexpr static size_t index_to_offset(index_type idx) + { return idx.get0(); } + constexpr static index_type offset_to_index(size_t off) + { return I::from(off); } + constexpr static size_t alloc_size = limit; +}; + +template<class T, class I> +struct GenericArray +{ + T data[I::alloc_size]; +public: + T *begin() + { return data + 0; } + T *end() + { return data + I::alloc_size; } + const T *begin() const + { return data + 0; } + const T *end() const + { return data + I::alloc_size; } + size_t size() const + { return I::alloc_size; } + + T& operator [](typename I::index_type i_) + { + size_t i = I::index_to_offset(i_); + ALLEGE ("index in bounds", i < size()); + return data[i]; + } + const T& operator [](typename I::index_type i_) const + { + size_t i = I::index_to_offset(i_); + ALLEGE ("index in bounds", i < size()); + return data[i]; + } + + friend bool operator == (GenericArray& lhs, GenericArray& rhs) + { + for (size_t i = 0; i < I::alloc_size; ++i) + { + if (lhs.data[i] != rhs.data[i]) + return false; + } + return true; + } + friend bool operator != (GenericArray& lhs, GenericArray& rhs) + { + return !(lhs == rhs); + } +}; + +template<class T, size_t n> +using Array = GenericArray<T, SimpleIndexing<n>>; +} // namespace tmwa diff --git a/src/generic/array_test.cpp b/src/generic/array_test.cpp new file mode 100644 index 0000000..aff47ee --- /dev/null +++ b/src/generic/array_test.cpp @@ -0,0 +1,162 @@ +#include "array.hpp" +// array_test.cpp - Testsuite for a simple bounds-checked array. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <gtest/gtest.h> + +#include "../poison.hpp" + + +namespace tmwa +{ +TEST(Array, simple) +{ + GenericArray<int, SimpleIndexing<3>> a; + try + { + a[0]; + a[1]; + a[2]; + SUCCEED(); + } + catch (const AssertionError&) + { + FAIL(); + } + try + { + a[3]; + FAIL(); + } + catch (const AssertionError&) + { + SUCCEED(); + } +} + +TEST(Array, inclusive1) +{ + GenericArray<int, InclusiveIndexing<int, 1, 3>> a; + try + { + a[0]; + FAIL(); + } + catch (const AssertionError&) + { + SUCCEED(); + } + try + { + a[1]; + a[2]; + a[3]; + SUCCEED(); + } + catch (const AssertionError&) + { + FAIL(); + } + try + { + a[4]; + FAIL(); + } + catch (const AssertionError&) + { + SUCCEED(); + } +} + +TEST(Array, negative) +{ + GenericArray<int, InclusiveIndexing<int, -1, 1>> a; + try + { + a[-2]; + FAIL(); + } + catch (const AssertionError&) + { + SUCCEED(); + } + try + { + a[-1]; + a[0]; + a[1]; + SUCCEED(); + } + catch (const AssertionError&) + { + FAIL(); + } + try + { + a[2]; + FAIL(); + } + catch (const AssertionError&) + { + SUCCEED(); + } +} + +TEST(Array, enum) +{ + enum class Blah + { + FOO, + BAR, + BAZ, + COUNT, + }; + + GenericArray<int, EnumIndexing<Blah>> a; + try + { + a[static_cast<Blah>(-1)]; + FAIL(); + } + catch (const AssertionError&) + { + SUCCEED(); + } + try + { + a[Blah::FOO]; + a[Blah::BAR]; + a[Blah::BAZ]; + SUCCEED(); + } + catch (const AssertionError&) + { + FAIL(); + } + try + { + a[Blah::COUNT]; + FAIL(); + } + catch (const AssertionError&) + { + SUCCEED(); + } +} +} // namespace tmwa diff --git a/src/generic/db.cpp b/src/generic/db.cpp index b953ff0..458068c 100644 --- a/src/generic/db.cpp +++ b/src/generic/db.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/generic/db.hpp b/src/generic/db.hpp index 314c449..90c4f92 100644 --- a/src/generic/db.hpp +++ b/src/generic/db.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_GENERIC_DB_HPP -#define TMWA_GENERIC_DB_HPP +#pragma once // db.hpp - convenience wrappers over std::map<K, V> // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,11 +18,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <map> -# include <memory> +#include <map> +#include <memory> + +namespace tmwa +{ template<class K, class V> class Map { @@ -176,5 +178,4 @@ public: return impl.size(); } }; - -#endif // TMWA_GENERIC_DB_HPP +} // namespace tmwa diff --git a/src/mmo/dumb_ptr.cpp b/src/generic/dumb_ptr.cpp index 77e3080..e690f7d 100644 --- a/src/mmo/dumb_ptr.cpp +++ b/src/generic/dumb_ptr.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/mmo/dumb_ptr.hpp b/src/generic/dumb_ptr.hpp index 9632945..a9d6893 100644 --- a/src/mmo/dumb_ptr.hpp +++ b/src/generic/dumb_ptr.hpp @@ -1,6 +1,5 @@ -#ifndef TMWA_MMO_DUMB_PTR_HPP -#define TMWA_MMO_DUMB_PTR_HPP -// ptr.hpp - temporary new/delete wrappers +#pragma once +// dumb_ptr.hpp - temporary new/delete wrappers // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> // @@ -19,16 +18,20 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstring> +#include <cstring> -# include <algorithm> +#include <algorithm> +#include <utility> -# include "../strings/astring.hpp" -# include "../strings/zstring.hpp" -# include "../strings/xstring.hpp" +#include "../strings/astring.hpp" +#include "../strings/zstring.hpp" +#include "../strings/xstring.hpp" + +namespace tmwa +{ // unmanaged new/delete-able pointer // should be replaced by std::unique_ptr<T> template<class T> @@ -199,18 +202,14 @@ struct dumb_string std::copy(b, e, &rv.impl[0]); return rv; } - static dumb_string copy(const char *sz) - { - return dumb_string::copy(sz, sz + strlen(sz)); - } static dumb_string copys(XString s) { return dumb_string::copy(&*s.begin(), &*s.end()); } static -# ifndef __clang__ +#ifndef __clang__ __attribute__((warning("shouldn't use this - slice instead"))) -# endif +#endif dumb_string copyn(const char *sn, size_t n) { return dumb_string::copy(sn, sn + strnlen(sn, n)); @@ -227,7 +226,7 @@ struct dumb_string dumb_string dup() const { - return dumb_string::copy(&impl[0]); + return dumb_string::copy(&impl[0], &impl[0] + impl.size()); } void delete_() { @@ -270,5 +269,4 @@ const char *convert_for_printf(dumb_string ds) { return ds.c_str(); } - -#endif // TMWA_MMO_DUMB_PTR_HPP +} // namespace tmwa diff --git a/src/generic/enum.cpp b/src/generic/enum.cpp index 8c54aba..49402e9 100644 --- a/src/generic/enum.cpp +++ b/src/generic/enum.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/generic/enum.hpp b/src/generic/enum.hpp index 8b3509f..81c9b12 100644 --- a/src/generic/enum.hpp +++ b/src/generic/enum.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_GENERIC_ENUM_HPP -#define TMWA_GENERIC_ENUM_HPP +#pragma once // enum.hpp - Safe building blocks for enumerated types. // // Copyright © 2012-2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,70 +18,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cassert> +#include <cassert> +#include <cstddef> -# include <type_traits> +#include <algorithm> +#include <type_traits> -# include "../compat/iter.hpp" +#include "../compat/iter.hpp" -template<class T, class E, E max> -struct earray -{ - constexpr static - size_t size() - { - return static_cast<size_t>(max); - } - - // no ctor/dtor and one public member variable for easy initialization - T _data[size()]; - - T& operator[](E v) - { - auto i = static_cast<size_t>(v); - assert (i < size()); - return _data[i]; - } - - const T& operator[](E v) const - { - auto i = static_cast<size_t>(v); - assert (i < size()); - return _data[i]; - } - - T *begin() - { - return _data; - } +#include "array.hpp" - T *end() - { - return _data + size(); - } - const T *begin() const - { - return _data; - } - - const T *end() const - { - return _data + size(); - } - - friend bool operator == (const earray& l, const earray& r) - { - return std::equal(l.begin(), l.end(), r.begin()); - } - - friend bool operator != (const earray& l, const earray& r) - { - return !(l == r); - } -}; +namespace tmwa +{ +template<class T, class E, E max> +using earray = GenericArray<T, EnumIndexing<E, max>>; template<class T, class E, E max> class eptr @@ -100,7 +52,7 @@ public: {} eptr(earray<T, E, max>& arr) - : _data(arr._data) + : _data(arr.data) {} T& operator [](E v) const @@ -123,6 +75,7 @@ public: // std::underlying_type isn't supported until gcc 4.7 // this is a poor man's emulation +// TODO I'm depending on GCC 4.7 now, this can go away template<class E> struct underlying_type { @@ -148,7 +101,7 @@ struct remove_enum<E, true> // This really should just go in a namespace // that's how I use it anyway ... -# define ENUM_BITWISE_OPERATORS(E) \ +#define ENUM_BITWISE_OPERATORS(E) \ inline \ E operator & (E l, E r) \ { \ @@ -196,7 +149,7 @@ public: static E inced(E v) { - return E(U(v) + 1); + return static_cast<E>(static_cast<U>(v) + 1); } }; @@ -205,5 +158,4 @@ IteratorPair<ValueIterator<E, EnumMath<E>>> erange(E b, E e) { return {b, e}; } - -#endif // TMWA_GENERIC_ENUM_HPP +} // namespace tmwa diff --git a/src/generic/fwd.hpp b/src/generic/fwd.hpp new file mode 100644 index 0000000..81c4e26 --- /dev/null +++ b/src/generic/fwd.hpp @@ -0,0 +1,30 @@ +#pragma once +// generic/fwd.hpp - list of type names for generic lib +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +// meh, add more when I feel like it +template<class T> +class dumb_ptr; +class dumb_string; +} // namespace tmwa diff --git a/src/generic/intern-pool.cpp b/src/generic/intern-pool.cpp index f6df5a6..f45b098 100644 --- a/src/generic/intern-pool.cpp +++ b/src/generic/intern-pool.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/generic/intern-pool.hpp b/src/generic/intern-pool.hpp index 0ffddd2..030aa38 100644 --- a/src/generic/intern-pool.hpp +++ b/src/generic/intern-pool.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_GENERIC_INTERN_POOL_HPP -#define TMWA_GENERIC_INTERN_POOL_HPP +#pragma once // intern-pool.hpp - Cached integer/string lookups. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,17 +18,21 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cassert> +#include <cassert> +#include <cstddef> -# include <map> -# include <vector> +#include <map> +#include <vector> -# include "../strings/rstring.hpp" -# include "../strings/zstring.hpp" -# include "../strings/xstring.hpp" +#include "../strings/rstring.hpp" +#include "../strings/zstring.hpp" +#include "../strings/xstring.hpp" + +namespace tmwa +{ class InternPool { std::map<RString, size_t> known; @@ -58,5 +61,4 @@ public: return known.size(); } }; - -#endif // TMWA_GENERIC_INTERN_POOL_HPP +} // namespace tmwa diff --git a/src/generic/intern-pool_test.cpp b/src/generic/intern-pool_test.cpp index b72ab04..c91be91 100644 --- a/src/generic/intern-pool_test.cpp +++ b/src/generic/intern-pool_test.cpp @@ -1,5 +1,5 @@ #include "intern-pool.hpp" -// intern-pool.hpp - Testsuite for cached integer/string lookups. +// intern-pool_test.cpp - Testsuite for cached integer/string lookups. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> // @@ -20,21 +20,25 @@ #include <gtest/gtest.h> -#include "../strings/base.hpp" +#include "../strings/literal.hpp" #include "../poison.hpp" + +namespace tmwa +{ TEST(InternPool, whydoesthisalwaysneedasecondname) { InternPool p; EXPECT_EQ(0, p.size()); - EXPECT_EQ(0, p.intern("hello")); - EXPECT_EQ(0, p.intern("hello")); + EXPECT_EQ(0, p.intern("hello"_s)); + EXPECT_EQ(0, p.intern("hello"_s)); EXPECT_EQ(1, p.size()); - EXPECT_EQ(1, p.intern("world")); - EXPECT_EQ(0, p.intern("hello")); - EXPECT_EQ(1, p.intern("world")); + EXPECT_EQ(1, p.intern("world"_s)); + EXPECT_EQ(0, p.intern("hello"_s)); + EXPECT_EQ(1, p.intern("world"_s)); EXPECT_EQ(2, p.size()); - EXPECT_EQ("hello", p.outtern(0)); - EXPECT_EQ("world", p.outtern(1)); + EXPECT_EQ("hello"_s, p.outtern(0)); + EXPECT_EQ("world"_s, p.outtern(1)); } +} // namespace tmwa diff --git a/src/generic/matrix.cpp b/src/generic/matrix.cpp index e1e1f5e..b14ab7d 100644 --- a/src/generic/matrix.cpp +++ b/src/generic/matrix.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/generic/matrix.hpp b/src/generic/matrix.hpp index 40ff9a8..86ce6c2 100644 --- a/src/generic/matrix.hpp +++ b/src/generic/matrix.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_GENERIC_MATRIX_HPP -#define TMWA_GENERIC_MATRIX_HPP +#pragma once // matrix.hpp - A 2D array. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,12 +18,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cassert> +#include <cassert> -# include "../compat/memory.hpp" +#include "../compat/memory.hpp" + +namespace tmwa +{ template<class T> class Matrix { @@ -74,5 +76,4 @@ public: return _ys; } }; - -#endif // TMWA_GENERIC_MATRIX_HPP +} // namespace tmwa diff --git a/src/generic/md5.cpp b/src/generic/md5.cpp index b49d36f..771ad0f 100644 --- a/src/generic/md5.cpp +++ b/src/generic/md5.cpp @@ -18,17 +18,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <cstring> - #include "../compat/rawmem.hpp" #include "../strings/xstring.hpp" -#include "../strings/vstring.hpp" - -#include "random.hpp" #include "../poison.hpp" + +namespace tmwa +{ // auxilary data /* sin() constant table @@ -250,3 +248,4 @@ MD5_state MD5_from_string(XString msg) } return state; } +} // namespace tmwa diff --git a/src/generic/md5.hpp b/src/generic/md5.hpp index 8b1c6ad..50bc987 100644 --- a/src/generic/md5.hpp +++ b/src/generic/md5.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_GENERIC_MD5CALC_HPP -#define TMWA_GENERIC_MD5CALC_HPP +#pragma once // md5.hpp - Fundamental MD5 operations. // // Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,19 +18,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <netinet/in.h> +#include <cstdint> -# include <cstdint> -# include <cstddef> -# include <cstdio> +#include <array> -# include <array> +#include "../strings/fwd.hpp" +#include "../strings/vstring.hpp" -# include "../strings/fwd.hpp" -# include "../strings/vstring.hpp" +namespace tmwa +{ /// The digest state - becomes the output struct MD5_state { @@ -58,5 +56,4 @@ void MD5_to_str(MD5_state state, md5_string& out); // Convenience MD5_state MD5_from_string(XString msg); - -#endif // TMWA_GENERIC_MD5CALC_HPP +} // namespace tmwa diff --git a/src/generic/md5_test.cpp b/src/generic/md5_test.cpp index f6a2324..86cbd53 100644 --- a/src/generic/md5_test.cpp +++ b/src/generic/md5_test.cpp @@ -25,6 +25,9 @@ #include "../poison.hpp" + +namespace tmwa +{ // This should be made part of the main API, // but is not yet to keep the diff small. // Edit: hack to fix the new strict comparison. @@ -38,11 +41,12 @@ VString<32> MD5(XString in) TEST(md5calc, rfc1321) { - EXPECT_EQ("d41d8cd98f00b204e9800998ecf8427e", MD5("")); - EXPECT_EQ("0cc175b9c0f1b6a831c399e269772661", MD5("a")); - EXPECT_EQ("900150983cd24fb0d6963f7d28e17f72", MD5("abc")); - EXPECT_EQ("f96b697d7cb7938d525a2f31aaf161d0", MD5("message digest")); - EXPECT_EQ("c3fcd3d76192e4007dfb496cca67e13b", MD5("abcdefghijklmnopqrstuvwxyz")); - EXPECT_EQ("d174ab98d277d9f5a5611c2c9f419d9f", MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")); - EXPECT_EQ("57edf4a22be3c955ac49da2e2107b67a", MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890")); + EXPECT_EQ("d41d8cd98f00b204e9800998ecf8427e"_s, MD5(""_s)); + EXPECT_EQ("0cc175b9c0f1b6a831c399e269772661"_s, MD5("a"_s)); + EXPECT_EQ("900150983cd24fb0d6963f7d28e17f72"_s, MD5("abc"_s)); + EXPECT_EQ("f96b697d7cb7938d525a2f31aaf161d0"_s, MD5("message digest"_s)); + EXPECT_EQ("c3fcd3d76192e4007dfb496cca67e13b"_s, MD5("abcdefghijklmnopqrstuvwxyz"_s)); + EXPECT_EQ("d174ab98d277d9f5a5611c2c9f419d9f"_s, MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"_s)); + EXPECT_EQ("57edf4a22be3c955ac49da2e2107b67a"_s, MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890"_s)); } +} // namespace tmwa diff --git a/src/generic/oops.cpp b/src/generic/oops.cpp new file mode 100644 index 0000000..601ab37 --- /dev/null +++ b/src/generic/oops.cpp @@ -0,0 +1,48 @@ +#include "oops.hpp" +// oops.cpp - Stuff that shouldn't happen. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <cstdlib> +#include <cstring> +#include <cstdio> + +//#include "../poison.hpp" + + +namespace tmwa +{ +static +std::string do_asprintf(const char *desc, const char *expr, + const char *file, size_t line, const char *function) +{ + char *what = nullptr; + int len = asprintf(&what, "%s:%zu: error: in '%s', incorrectly alleged that '%s' (%s)", + file, line, function, desc, expr); + if (len == -1) + abort(); + std::string out = what; + free(what); + return out; +} + +AssertionError::AssertionError(const char *desc, const char *expr, + const char *file, size_t line, const char *function) +: std::runtime_error(do_asprintf(desc, expr, file, line, function)) +{} +} // namespace tmwa diff --git a/src/generic/oops.hpp b/src/generic/oops.hpp new file mode 100644 index 0000000..f5cf54a --- /dev/null +++ b/src/generic/oops.hpp @@ -0,0 +1,40 @@ +#pragma once +// oops.hpp - Stuff that shouldn't happen. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include <cstddef> + +#include <stdexcept> + + +namespace tmwa +{ +class AssertionError : public std::runtime_error +{ +public: + AssertionError(const char *desc, const char *expr, + const char *file, size_t line, const char *function); +}; + +#define ALLEGE(desc, expr) \ + if (expr) {} \ + else throw AssertionError(desc, #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__) +} // namespace tmwa diff --git a/src/generic/oops_test.cpp b/src/generic/oops_test.cpp new file mode 100644 index 0000000..11c87e7 --- /dev/null +++ b/src/generic/oops_test.cpp @@ -0,0 +1,54 @@ +#include "oops.hpp" +// oops_test.cpp - Testsuite for stuff that shouldn't happen. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <gtest/gtest.h> + +#include "../poison.hpp" + + +namespace tmwa +{ +TEST(oops, okay) +{ + try + { + ALLEGE ("the sky is gray", true); + SUCCEED(); + } + catch (const AssertionError& e) + { + FAIL(); + } +} + +TEST(oops, uhoh) +{ + try + { + ALLEGE ("the sky is falling", 1 == 0); + FAIL(); + } + catch (const AssertionError& e) + { + ASSERT_STREQ(strstr(e.what(), "src/generic/"), + "src/generic/oops_test.cpp:45: error: in 'virtual void tmwa::oops_uhoh_Test::TestBody()', incorrectly alleged that 'the sky is falling' (1 == 0)"); + } +} +} // namespace tmwa diff --git a/src/generic/operators.cpp b/src/generic/operators.cpp index 8d79e1b..614ae51 100644 --- a/src/generic/operators.cpp +++ b/src/generic/operators.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/generic/operators.hpp b/src/generic/operators.hpp index 2a71c46..bb05765 100644 --- a/src/generic/operators.hpp +++ b/src/generic/operators.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_GENERIC_OPERATORS_HPP -#define TMWA_GENERIC_OPERATORS_HPP +#pragma once // operators.hpp - ADL helper for value wrappers. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,8 +18,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" + +namespace tmwa +{ namespace _operators { class Comparable {}; @@ -63,5 +65,4 @@ namespace _operators } using _operators::Comparable; - -#endif // TMWA_GENERIC_OPERATORS_HPP +} // namespace tmwa diff --git a/src/generic/random.cpp b/src/generic/random.cpp index 8a06571..e37a3d1 100644 --- a/src/generic/random.cpp +++ b/src/generic/random.cpp @@ -20,7 +20,11 @@ #include "../poison.hpp" + +namespace tmwa +{ namespace random_ { std::mt19937 generate{std::random_device()()}; } // namespace random_ +} // namespace tmwa diff --git a/src/generic/random.hpp b/src/generic/random.hpp index 45b5371..5d67236 100644 --- a/src/generic/random.hpp +++ b/src/generic/random.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_GENERIC_RANDOM_HPP -#define TMWA_GENERIC_RANDOM_HPP +#pragma once // random.hpp - Random number generation. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,14 +18,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "random.t.hpp" +#include "random.t.hpp" -# include "../sanity.hpp" +#include <random> -# include <random> +namespace tmwa +{ // This is not namespace random since that collides with a C function, // but this can be revisited when everything goes into namespace tmwa. namespace random_ @@ -85,5 +85,4 @@ namespace random_ return random_::choice(il); } } // namespace random_ - -#endif // TMWA_GENERIC_RANDOM_HPP +} // namespace tmwa diff --git a/src/generic/random.t.hpp b/src/generic/random.t.hpp index d26bf56..b4c4764 100644 --- a/src/generic/random.t.hpp +++ b/src/generic/random.t.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_GENERIC_RANDOM_T_HPP -#define TMWA_GENERIC_RANDOM_T_HPP +#pragma once // random.t.hpp - Random number generation. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,8 +18,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" + +namespace tmwa +{ namespace random_ { struct Fraction @@ -39,5 +41,4 @@ namespace random_ } }; } // namespace random_ - -#endif // TMWA_GENERIC_RANDOM_T_HPP +} // namespace tmwa diff --git a/src/generic/random2.hpp b/src/generic/random2.hpp index 40fcbcf..23d165c 100644 --- a/src/generic/random2.hpp +++ b/src/generic/random2.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_GENERIC_RANDOM2_HPP -#define TMWA_GENERIC_RANDOM2_HPP +#pragma once // random2.hpp - Random number generation. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,14 +18,17 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "random.hpp" +#include "random.hpp" -# include <algorithm> +#include <algorithm> -# include "../compat/iter.hpp" +#include "../compat/iter.hpp" + +namespace tmwa +{ namespace random_ { namespace detail @@ -91,5 +93,4 @@ namespace random_ std::random_shuffle(c.begin(), c.end(), random_::to); } } // namespace random_ - -#endif // TMWA_GENERIC_RANDOM2_HPP +} // namespace tmwa diff --git a/src/ints/cmp.cpp b/src/ints/cmp.cpp new file mode 100644 index 0000000..94ff0e3 --- /dev/null +++ b/src/ints/cmp.cpp @@ -0,0 +1,26 @@ +#include "cmp.hpp" +// cmp.cpp - comparison related operations +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/ints/cmp.hpp b/src/ints/cmp.hpp new file mode 100644 index 0000000..08308e1 --- /dev/null +++ b/src/ints/cmp.hpp @@ -0,0 +1,71 @@ +#pragma once +// cmp.hpp - comparison related operations +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include <limits> + +#include "../diagnostics.hpp" + + +namespace tmwa +{ +namespace ints +{ + DIAG_PUSH(); + DIAG_I(type_limits); + template<class T, class U> + T saturate(const U& v) + { + typedef std::numeric_limits<T> Tlim; + typedef std::numeric_limits<U> Ulim; + + if (Tlim::is_signed == Ulim::is_signed) + { + if (v > Tlim::max()) + return Tlim::max(); + if (v < Tlim::min()) + return Tlim::min(); + return v; + } + else if (Ulim::is_signed) + { + // from signed to unsigned + + // Not like v < Tlim::min(), even though Tlim::min() == 0 + if (v < 0) + return 0; + if (v > Tlim::max()) + return Tlim::max(); + return v; + } + else // Tlim::is_signed + { + // from unsigned to signed + if (v > Tlim::max()) + return Tlim::max(); + return v; + } + } + DIAG_POP(); +} // namespace ints + +using ints::saturate; +} // namespace tmwa diff --git a/src/ints/cmp_test.cpp b/src/ints/cmp_test.cpp new file mode 100644 index 0000000..5c605c0 --- /dev/null +++ b/src/ints/cmp_test.cpp @@ -0,0 +1,1465 @@ +#include "cmp.hpp" +// cmp_test.cpp - Testsuite for comparison related operations +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <gtest/gtest.h> + +#include "../compat/cast.hpp" + +#include "../poison.hpp" + + +namespace tmwa +{ +// Google Test is *really* slow to compile this file +#undef EXPECT_EQ +#define EXPECT_EQ(a, b) assert(a == b) + +TEST(ints, sati8) +{ + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int8_t>( -0x80ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x7fULL), saturate<int8_t>(maybe_cast<int8_t>( -0x7fULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x7eULL), saturate<int8_t>(maybe_cast<int8_t>( -0x7eULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x01ULL), saturate<int8_t>(maybe_cast<int8_t>( -0x01ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x00ULL), saturate<int8_t>(maybe_cast<int8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x01ULL), saturate<int8_t>(maybe_cast<int8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7eULL), saturate<int8_t>(maybe_cast<int8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int8_t>( +0x7fULL))); + + EXPECT_EQ(maybe_cast<int8_t>(+0x00ULL), saturate<int8_t>(maybe_cast<uint8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x01ULL), saturate<int8_t>(maybe_cast<uint8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7eULL), saturate<int8_t>(maybe_cast<uint8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint8_t>( +0x7fULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint8_t>( +0x80ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint8_t>( +0xfeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint8_t>( +0xffULL))); + + + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int16_t>( -0x8000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int16_t>( -0x7fffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int16_t>( -0x0100ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int16_t>( -0x00ffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int16_t>( -0x00feULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int16_t>( -0x0081ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int16_t>( -0x0080ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x7fULL), saturate<int8_t>(maybe_cast<int16_t>( -0x007fULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x01ULL), saturate<int8_t>(maybe_cast<int16_t>( -0x0001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x00ULL), saturate<int8_t>(maybe_cast<int16_t>( +0x0000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x01ULL), saturate<int8_t>(maybe_cast<int16_t>( +0x0001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7eULL), saturate<int8_t>(maybe_cast<int16_t>( +0x007eULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int16_t>( +0x007fULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int16_t>( +0x0080ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int16_t>( +0x00feULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int16_t>( +0x00ffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int16_t>( +0x0100ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int16_t>( +0x7ffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int16_t>( +0x7fffULL))); + + EXPECT_EQ(maybe_cast<int8_t>(+0x00ULL), saturate<int8_t>(maybe_cast<uint16_t>(+0x0000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x01ULL), saturate<int8_t>(maybe_cast<uint16_t>(+0x0001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7eULL), saturate<int8_t>(maybe_cast<uint16_t>(+0x007eULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint16_t>(+0x007fULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint16_t>(+0x0080ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint16_t>(+0x00feULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint16_t>(+0x00ffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint16_t>(+0x0100ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint16_t>(+0x7ffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint16_t>(+0x7fffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint16_t>(+0x8000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint16_t>(+0xfffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint16_t>(+0xffffULL))); + + + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x80000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x7fffffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x00010000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x00008001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x00008000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x00007fffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x00000100ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x000000ffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x000000feULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x00000081ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x00000080ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( -0x0000007fULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x01ULL), saturate<int8_t>(maybe_cast<int32_t>( -0x00000001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x00ULL), saturate<int8_t>(maybe_cast<int32_t>( +0x00000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x01ULL), saturate<int8_t>(maybe_cast<int32_t>( +0x00000001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7eULL), saturate<int8_t>(maybe_cast<int32_t>( +0x0000007eULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x0000007fULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x00000080ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x000000feULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x000000ffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x00000100ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x00007ffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x00007fffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x00008000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x00010000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int32_t>( +0x7fffffffULL))); + + EXPECT_EQ(maybe_cast<int8_t>(+0x00ULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x00000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x01ULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x00000001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7eULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x0000007eULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x0000007fULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x00000080ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x000000feULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x000000ffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x00000100ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x00007ffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x00007fffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x00008000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x00010000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x7fffffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0x80000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0xfffffffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint32_t>(+0xffffffffULL))); + + + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x0000000080000001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x0000000000008001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x0000000000000081ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x80ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( -0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int8_t>(-0x01ULL), saturate<int8_t>(maybe_cast<int64_t>( -0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x00ULL), saturate<int8_t>(maybe_cast<int64_t>( +0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x01ULL), saturate<int8_t>(maybe_cast<int64_t>( +0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7eULL), saturate<int8_t>(maybe_cast<int64_t>( +0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<int64_t>( +0x7fffffffffffffffULL))); + + EXPECT_EQ(maybe_cast<int8_t>(+0x00ULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x01ULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7eULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0xfffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int8_t>(+0x7fULL), saturate<int8_t>(maybe_cast<uint64_t>(+0xffffffffffffffffULL))); +} + +TEST(ints, satu8) +{ + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int8_t>( -0x80ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int8_t>( -0x7fULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int8_t>( -0x7eULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int8_t>( -0x01ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x01ULL), saturate<uint8_t>(maybe_cast<int8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7eULL), saturate<uint8_t>(maybe_cast<int8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7fULL), saturate<uint8_t>(maybe_cast<int8_t>( +0x7fULL))); + + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<uint8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x01ULL), saturate<uint8_t>(maybe_cast<uint8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7eULL), saturate<uint8_t>(maybe_cast<uint8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7fULL), saturate<uint8_t>(maybe_cast<uint8_t>( +0x7fULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x80ULL), saturate<uint8_t>(maybe_cast<uint8_t>( +0x80ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xfeULL), saturate<uint8_t>(maybe_cast<uint8_t>( +0xfeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint8_t>( +0xffULL))); + + + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int16_t>( -0x8000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int16_t>( -0x7fffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int16_t>( -0x0100ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int16_t>( -0x00ffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int16_t>( -0x00feULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int16_t>( -0x0081ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int16_t>( -0x0080ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int16_t>( -0x007fULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int16_t>( -0x0001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int16_t>( +0x0000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x01ULL), saturate<uint8_t>(maybe_cast<int16_t>( +0x0001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7eULL), saturate<uint8_t>(maybe_cast<int16_t>( +0x007eULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7fULL), saturate<uint8_t>(maybe_cast<int16_t>( +0x007fULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x80ULL), saturate<uint8_t>(maybe_cast<int16_t>( +0x0080ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xfeULL), saturate<uint8_t>(maybe_cast<int16_t>( +0x00feULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int16_t>( +0x00ffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int16_t>( +0x0100ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int16_t>( +0x7ffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int16_t>( +0x7fffULL))); + + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0x0000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x01ULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0x0001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7eULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0x007eULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7fULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0x007fULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x80ULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0x0080ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xfeULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0x00feULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0x00ffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0x0100ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0x7ffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0x7fffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0x8000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0xfffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint16_t>(+0xffffULL))); + + + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x80000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x7fffffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x00008001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x000000feULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x00000081ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( -0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x00000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x01ULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7eULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x0000007eULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7fULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x80ULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xfeULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x000000feULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x00007ffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int32_t>( +0x7fffffffULL))); + + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x00000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x01ULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7eULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x0000007eULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7fULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x80ULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xfeULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x000000feULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x00007ffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x7fffffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0x80000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0xfffffffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint32_t>(+0xffffffffULL))); + + + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x0000000080000001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x0000000000008001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x0000000000000081ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( -0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x01ULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7eULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7fULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x80ULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xfeULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<int64_t>( +0x7fffffffffffffffULL))); + + EXPECT_EQ(maybe_cast<uint8_t>(+0x00ULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x01ULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7eULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x7fULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0x80ULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xfeULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0xfffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint8_t>(+0xffULL), saturate<uint8_t>(maybe_cast<uint64_t>(+0xffffffffffffffffULL))); +} + +TEST(ints, sati16) +{ + EXPECT_EQ(maybe_cast<int16_t>(-0x80ULL), saturate<int16_t>(maybe_cast<int8_t>( -0x80ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x7fULL), saturate<int16_t>(maybe_cast<int8_t>( -0x7fULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x7eULL), saturate<int16_t>(maybe_cast<int8_t>( -0x7eULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x01ULL), saturate<int16_t>(maybe_cast<int8_t>( -0x01ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00ULL), saturate<int16_t>(maybe_cast<int8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x01ULL), saturate<int16_t>(maybe_cast<int8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7eULL), saturate<int16_t>(maybe_cast<int8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fULL), saturate<int16_t>(maybe_cast<int8_t>( +0x7fULL))); + + EXPECT_EQ(maybe_cast<int16_t>(+0x00ULL), saturate<int16_t>(maybe_cast<uint8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x01ULL), saturate<int16_t>(maybe_cast<uint8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7eULL), saturate<int16_t>(maybe_cast<uint8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fULL), saturate<int16_t>(maybe_cast<uint8_t>( +0x7fULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x80ULL), saturate<int16_t>(maybe_cast<uint8_t>( +0x80ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0xfeULL), saturate<int16_t>(maybe_cast<uint8_t>( +0xfeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0xffULL), saturate<int16_t>(maybe_cast<uint8_t>( +0xffULL))); + + + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int16_t>( -0x8000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x7fffULL), saturate<int16_t>(maybe_cast<int16_t>( -0x7fffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0100ULL), saturate<int16_t>(maybe_cast<int16_t>( -0x0100ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x00ffULL), saturate<int16_t>(maybe_cast<int16_t>( -0x00ffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x00feULL), saturate<int16_t>(maybe_cast<int16_t>( -0x00feULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0081ULL), saturate<int16_t>(maybe_cast<int16_t>( -0x0081ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0080ULL), saturate<int16_t>(maybe_cast<int16_t>( -0x0080ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x007fULL), saturate<int16_t>(maybe_cast<int16_t>( -0x007fULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0001ULL), saturate<int16_t>(maybe_cast<int16_t>( -0x0001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0000ULL), saturate<int16_t>(maybe_cast<int16_t>( +0x0000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0001ULL), saturate<int16_t>(maybe_cast<int16_t>( +0x0001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007eULL), saturate<int16_t>(maybe_cast<int16_t>( +0x007eULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007fULL), saturate<int16_t>(maybe_cast<int16_t>( +0x007fULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0080ULL), saturate<int16_t>(maybe_cast<int16_t>( +0x0080ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00feULL), saturate<int16_t>(maybe_cast<int16_t>( +0x00feULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00ffULL), saturate<int16_t>(maybe_cast<int16_t>( +0x00ffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0100ULL), saturate<int16_t>(maybe_cast<int16_t>( +0x0100ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7ffeULL), saturate<int16_t>(maybe_cast<int16_t>( +0x7ffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int16_t>( +0x7fffULL))); + + EXPECT_EQ(maybe_cast<int16_t>(+0x0000ULL), saturate<int16_t>(maybe_cast<uint16_t>(+0x0000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0001ULL), saturate<int16_t>(maybe_cast<uint16_t>(+0x0001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007eULL), saturate<int16_t>(maybe_cast<uint16_t>(+0x007eULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007fULL), saturate<int16_t>(maybe_cast<uint16_t>(+0x007fULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0080ULL), saturate<int16_t>(maybe_cast<uint16_t>(+0x0080ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00feULL), saturate<int16_t>(maybe_cast<uint16_t>(+0x00feULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00ffULL), saturate<int16_t>(maybe_cast<uint16_t>(+0x00ffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0100ULL), saturate<int16_t>(maybe_cast<uint16_t>(+0x0100ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7ffeULL), saturate<int16_t>(maybe_cast<uint16_t>(+0x7ffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint16_t>(+0x7fffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint16_t>(+0x8000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint16_t>(+0xfffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint16_t>(+0xffffULL))); + + + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int32_t>( -0x80000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int32_t>( -0x7fffffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int32_t>( -0x00010000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int32_t>( -0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int32_t>( -0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int32_t>( -0x00008001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int32_t>( -0x00008000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x7fffULL), saturate<int16_t>(maybe_cast<int32_t>( -0x00007fffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0100ULL), saturate<int16_t>(maybe_cast<int32_t>( -0x00000100ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x00ffULL), saturate<int16_t>(maybe_cast<int32_t>( -0x000000ffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x00feULL), saturate<int16_t>(maybe_cast<int32_t>( -0x000000feULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0081ULL), saturate<int16_t>(maybe_cast<int32_t>( -0x00000081ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0080ULL), saturate<int16_t>(maybe_cast<int32_t>( -0x00000080ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x007fULL), saturate<int16_t>(maybe_cast<int32_t>( -0x0000007fULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0001ULL), saturate<int16_t>(maybe_cast<int32_t>( -0x00000001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0000ULL), saturate<int16_t>(maybe_cast<int32_t>( +0x00000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0001ULL), saturate<int16_t>(maybe_cast<int32_t>( +0x00000001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007eULL), saturate<int16_t>(maybe_cast<int32_t>( +0x0000007eULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007fULL), saturate<int16_t>(maybe_cast<int32_t>( +0x0000007fULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0080ULL), saturate<int16_t>(maybe_cast<int32_t>( +0x00000080ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00feULL), saturate<int16_t>(maybe_cast<int32_t>( +0x000000feULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00ffULL), saturate<int16_t>(maybe_cast<int32_t>( +0x000000ffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0100ULL), saturate<int16_t>(maybe_cast<int32_t>( +0x00000100ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7ffeULL), saturate<int16_t>(maybe_cast<int32_t>( +0x00007ffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int32_t>( +0x00007fffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int32_t>( +0x00008000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int32_t>( +0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int32_t>( +0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int32_t>( +0x00010000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int32_t>( +0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int32_t>( +0x7fffffffULL))); + + EXPECT_EQ(maybe_cast<int16_t>(+0x0000ULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x00000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0001ULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x00000001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007eULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x0000007eULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007fULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x0000007fULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0080ULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x00000080ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00feULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x000000feULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00ffULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x000000ffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0100ULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x00000100ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7ffeULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x00007ffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x00007fffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x00008000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x00010000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x7fffffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint32_t>(+0x80000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint32_t>(+0xfffffffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint32_t>(+0xffffffffULL))); + + + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x0000000080000001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x0000000000008001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x8000ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( -0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0100ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x00ffULL), saturate<int16_t>(maybe_cast<int64_t>( -0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x00feULL), saturate<int16_t>(maybe_cast<int64_t>( -0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0081ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x0000000000000081ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0080ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x007fULL), saturate<int16_t>(maybe_cast<int64_t>( -0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int16_t>(-0x0001ULL), saturate<int16_t>(maybe_cast<int64_t>( -0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0000ULL), saturate<int16_t>(maybe_cast<int64_t>( +0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0001ULL), saturate<int16_t>(maybe_cast<int64_t>( +0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007eULL), saturate<int16_t>(maybe_cast<int64_t>( +0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007fULL), saturate<int16_t>(maybe_cast<int64_t>( +0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0080ULL), saturate<int16_t>(maybe_cast<int64_t>( +0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00feULL), saturate<int16_t>(maybe_cast<int64_t>( +0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00ffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0100ULL), saturate<int16_t>(maybe_cast<int64_t>( +0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7ffeULL), saturate<int16_t>(maybe_cast<int64_t>( +0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<int64_t>( +0x7fffffffffffffffULL))); + + EXPECT_EQ(maybe_cast<int16_t>(+0x0000ULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0001ULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007eULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x007fULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0080ULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00feULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x00ffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x0100ULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7ffeULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0xfffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int16_t>(+0x7fffULL), saturate<int16_t>(maybe_cast<uint64_t>(+0xffffffffffffffffULL))); +} + +TEST(ints, satu16) +{ + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ULL), saturate<uint16_t>(maybe_cast<int8_t>( -0x80ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ULL), saturate<uint16_t>(maybe_cast<int8_t>( -0x7fULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ULL), saturate<uint16_t>(maybe_cast<int8_t>( -0x7eULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ULL), saturate<uint16_t>(maybe_cast<int8_t>( -0x01ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ULL), saturate<uint16_t>(maybe_cast<int8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x01ULL), saturate<uint16_t>(maybe_cast<int8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7eULL), saturate<uint16_t>(maybe_cast<int8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7fULL), saturate<uint16_t>(maybe_cast<int8_t>( +0x7fULL))); + + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ULL), saturate<uint16_t>(maybe_cast<uint8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x01ULL), saturate<uint16_t>(maybe_cast<uint8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7eULL), saturate<uint16_t>(maybe_cast<uint8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7fULL), saturate<uint16_t>(maybe_cast<uint8_t>( +0x7fULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x80ULL), saturate<uint16_t>(maybe_cast<uint8_t>( +0x80ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xfeULL), saturate<uint16_t>(maybe_cast<uint8_t>( +0xfeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffULL), saturate<uint16_t>(maybe_cast<uint8_t>( +0xffULL))); + + + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int16_t>( -0x8000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int16_t>( -0x7fffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int16_t>( -0x0100ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int16_t>( -0x00ffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int16_t>( -0x00feULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int16_t>( -0x0081ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int16_t>( -0x0080ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int16_t>( -0x007fULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int16_t>( -0x0001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int16_t>( +0x0000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0001ULL), saturate<uint16_t>(maybe_cast<int16_t>( +0x0001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007eULL), saturate<uint16_t>(maybe_cast<int16_t>( +0x007eULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007fULL), saturate<uint16_t>(maybe_cast<int16_t>( +0x007fULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0080ULL), saturate<uint16_t>(maybe_cast<int16_t>( +0x0080ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00feULL), saturate<uint16_t>(maybe_cast<int16_t>( +0x00feULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ffULL), saturate<uint16_t>(maybe_cast<int16_t>( +0x00ffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0100ULL), saturate<uint16_t>(maybe_cast<int16_t>( +0x0100ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7ffeULL), saturate<uint16_t>(maybe_cast<int16_t>( +0x7ffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7fffULL), saturate<uint16_t>(maybe_cast<int16_t>( +0x7fffULL))); + + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0x0000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0001ULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0x0001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007eULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0x007eULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007fULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0x007fULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0080ULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0x0080ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00feULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0x00feULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ffULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0x00ffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0100ULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0x0100ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7ffeULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0x7ffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7fffULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0x7fffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x8000ULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0x8000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xfffeULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0xfffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint16_t>(+0xffffULL))); + + + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x80000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x7fffffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x00008001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x000000feULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x00000081ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( -0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x00000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0001ULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007eULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x0000007eULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007fULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0080ULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00feULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x000000feULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ffULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0100ULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7ffeULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x00007ffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7fffULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x8000ULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xfffeULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int32_t>( +0x7fffffffULL))); + + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x00000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0001ULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007eULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x0000007eULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007fULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0080ULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00feULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x000000feULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ffULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0100ULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7ffeULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x00007ffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7fffULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x8000ULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xfffeULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x7fffffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0x80000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0xfffffffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint32_t>(+0xffffffffULL))); + + + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x0000000080000001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x0000000000008001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x0000000000000081ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( -0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0001ULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007eULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007fULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0080ULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00feULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0100ULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7ffeULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7fffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x8000ULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xfffeULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<int64_t>( +0x7fffffffffffffffULL))); + + EXPECT_EQ(maybe_cast<uint16_t>(+0x0000ULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0001ULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007eULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x007fULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0080ULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00feULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x00ffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x0100ULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7ffeULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x7fffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0x8000ULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xfffeULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0xfffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint16_t>(+0xffffULL), saturate<uint16_t>(maybe_cast<uint64_t>(+0xffffffffffffffffULL))); +} + +TEST(ints, sati32) +{ + EXPECT_EQ(maybe_cast<int32_t>(-0x80ULL), saturate<int32_t>(maybe_cast<int8_t>( -0x80ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x7fULL), saturate<int32_t>(maybe_cast<int8_t>( -0x7fULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x7eULL), saturate<int32_t>(maybe_cast<int8_t>( -0x7eULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x01ULL), saturate<int32_t>(maybe_cast<int8_t>( -0x01ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00ULL), saturate<int32_t>(maybe_cast<int8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x01ULL), saturate<int32_t>(maybe_cast<int8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7eULL), saturate<int32_t>(maybe_cast<int8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fULL), saturate<int32_t>(maybe_cast<int8_t>( +0x7fULL))); + + EXPECT_EQ(maybe_cast<int32_t>(+0x00ULL), saturate<int32_t>(maybe_cast<uint8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x01ULL), saturate<int32_t>(maybe_cast<uint8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7eULL), saturate<int32_t>(maybe_cast<uint8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fULL), saturate<int32_t>(maybe_cast<uint8_t>( +0x7fULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x80ULL), saturate<int32_t>(maybe_cast<uint8_t>( +0x80ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0xfeULL), saturate<int32_t>(maybe_cast<uint8_t>( +0xfeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0xffULL), saturate<int32_t>(maybe_cast<uint8_t>( +0xffULL))); + + + EXPECT_EQ(maybe_cast<int32_t>(-0x8000ULL), saturate<int32_t>(maybe_cast<int16_t>( -0x8000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x7fffULL), saturate<int32_t>(maybe_cast<int16_t>( -0x7fffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x0100ULL), saturate<int32_t>(maybe_cast<int16_t>( -0x0100ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00ffULL), saturate<int32_t>(maybe_cast<int16_t>( -0x00ffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00feULL), saturate<int32_t>(maybe_cast<int16_t>( -0x00feULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x0081ULL), saturate<int32_t>(maybe_cast<int16_t>( -0x0081ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x0080ULL), saturate<int32_t>(maybe_cast<int16_t>( -0x0080ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x007fULL), saturate<int32_t>(maybe_cast<int16_t>( -0x007fULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x0001ULL), saturate<int32_t>(maybe_cast<int16_t>( -0x0001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000ULL), saturate<int32_t>(maybe_cast<int16_t>( +0x0000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0001ULL), saturate<int32_t>(maybe_cast<int16_t>( +0x0001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x007eULL), saturate<int32_t>(maybe_cast<int16_t>( +0x007eULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x007fULL), saturate<int32_t>(maybe_cast<int16_t>( +0x007fULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0080ULL), saturate<int32_t>(maybe_cast<int16_t>( +0x0080ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00feULL), saturate<int32_t>(maybe_cast<int16_t>( +0x00feULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00ffULL), saturate<int32_t>(maybe_cast<int16_t>( +0x00ffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0100ULL), saturate<int32_t>(maybe_cast<int16_t>( +0x0100ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7ffeULL), saturate<int32_t>(maybe_cast<int16_t>( +0x7ffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffULL), saturate<int32_t>(maybe_cast<int16_t>( +0x7fffULL))); + + EXPECT_EQ(maybe_cast<int32_t>(+0x0000ULL), saturate<int32_t>(maybe_cast<uint16_t>(+0x0000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0001ULL), saturate<int32_t>(maybe_cast<uint16_t>(+0x0001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x007eULL), saturate<int32_t>(maybe_cast<uint16_t>(+0x007eULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x007fULL), saturate<int32_t>(maybe_cast<uint16_t>(+0x007fULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0080ULL), saturate<int32_t>(maybe_cast<uint16_t>(+0x0080ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00feULL), saturate<int32_t>(maybe_cast<uint16_t>(+0x00feULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00ffULL), saturate<int32_t>(maybe_cast<uint16_t>(+0x00ffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0100ULL), saturate<int32_t>(maybe_cast<uint16_t>(+0x0100ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7ffeULL), saturate<int32_t>(maybe_cast<uint16_t>(+0x7ffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffULL), saturate<int32_t>(maybe_cast<uint16_t>(+0x7fffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x8000ULL), saturate<int32_t>(maybe_cast<uint16_t>(+0x8000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0xfffeULL), saturate<int32_t>(maybe_cast<uint16_t>(+0xfffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0xffffULL), saturate<int32_t>(maybe_cast<uint16_t>(+0xffffULL))); + + + EXPECT_EQ(maybe_cast<int32_t>(-0x80000000ULL), saturate<int32_t>(maybe_cast<int32_t>( -0x80000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x7fffffffULL), saturate<int32_t>(maybe_cast<int32_t>( -0x7fffffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00010000ULL), saturate<int32_t>(maybe_cast<int32_t>( -0x00010000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x0000ffffULL), saturate<int32_t>(maybe_cast<int32_t>( -0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x0000fffeULL), saturate<int32_t>(maybe_cast<int32_t>( -0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00008001ULL), saturate<int32_t>(maybe_cast<int32_t>( -0x00008001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00008000ULL), saturate<int32_t>(maybe_cast<int32_t>( -0x00008000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00007fffULL), saturate<int32_t>(maybe_cast<int32_t>( -0x00007fffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00000100ULL), saturate<int32_t>(maybe_cast<int32_t>( -0x00000100ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x000000ffULL), saturate<int32_t>(maybe_cast<int32_t>( -0x000000ffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x000000feULL), saturate<int32_t>(maybe_cast<int32_t>( -0x000000feULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00000081ULL), saturate<int32_t>(maybe_cast<int32_t>( -0x00000081ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00000080ULL), saturate<int32_t>(maybe_cast<int32_t>( -0x00000080ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x0000007fULL), saturate<int32_t>(maybe_cast<int32_t>( -0x0000007fULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00000001ULL), saturate<int32_t>(maybe_cast<int32_t>( -0x00000001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000000ULL), saturate<int32_t>(maybe_cast<int32_t>( +0x00000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000001ULL), saturate<int32_t>(maybe_cast<int32_t>( +0x00000001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000007eULL), saturate<int32_t>(maybe_cast<int32_t>( +0x0000007eULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000007fULL), saturate<int32_t>(maybe_cast<int32_t>( +0x0000007fULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000080ULL), saturate<int32_t>(maybe_cast<int32_t>( +0x00000080ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x000000feULL), saturate<int32_t>(maybe_cast<int32_t>( +0x000000feULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x000000ffULL), saturate<int32_t>(maybe_cast<int32_t>( +0x000000ffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000100ULL), saturate<int32_t>(maybe_cast<int32_t>( +0x00000100ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00007ffeULL), saturate<int32_t>(maybe_cast<int32_t>( +0x00007ffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00007fffULL), saturate<int32_t>(maybe_cast<int32_t>( +0x00007fffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00008000ULL), saturate<int32_t>(maybe_cast<int32_t>( +0x00008000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000fffeULL), saturate<int32_t>(maybe_cast<int32_t>( +0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000ffffULL), saturate<int32_t>(maybe_cast<int32_t>( +0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00010000ULL), saturate<int32_t>(maybe_cast<int32_t>( +0x00010000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7ffffffeULL), saturate<int32_t>(maybe_cast<int32_t>( +0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<int32_t>( +0x7fffffffULL))); + + EXPECT_EQ(maybe_cast<int32_t>(+0x00000000ULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x00000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000001ULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x00000001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000007eULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x0000007eULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000007fULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x0000007fULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000080ULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x00000080ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x000000feULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x000000feULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x000000ffULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x000000ffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000100ULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x00000100ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00007ffeULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x00007ffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00007fffULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x00007fffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00008000ULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x00008000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000fffeULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000ffffULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00010000ULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x00010000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7ffffffeULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x7fffffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint32_t>(+0x80000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint32_t>(+0xfffffffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint32_t>(+0xffffffffULL))); + + + EXPECT_EQ(maybe_cast<int32_t>(-0x80000000ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x80000000ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x80000000ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x80000000ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x80000000ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x80000000ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x0000000080000001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x80000000ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x7fffffffULL), saturate<int32_t>(maybe_cast<int64_t>( -0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00010000ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x0000ffffULL), saturate<int32_t>(maybe_cast<int64_t>( -0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x0000fffeULL), saturate<int32_t>(maybe_cast<int64_t>( -0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00008001ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x0000000000008001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00008000ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00007fffULL), saturate<int32_t>(maybe_cast<int64_t>( -0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00000100ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x000000ffULL), saturate<int32_t>(maybe_cast<int64_t>( -0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x000000feULL), saturate<int32_t>(maybe_cast<int64_t>( -0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00000081ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x0000000000000081ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00000080ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x0000007fULL), saturate<int32_t>(maybe_cast<int64_t>( -0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int32_t>(-0x00000001ULL), saturate<int32_t>(maybe_cast<int64_t>( -0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000000ULL), saturate<int32_t>(maybe_cast<int64_t>( +0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000001ULL), saturate<int32_t>(maybe_cast<int64_t>( +0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000007eULL), saturate<int32_t>(maybe_cast<int64_t>( +0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000007fULL), saturate<int32_t>(maybe_cast<int64_t>( +0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000080ULL), saturate<int32_t>(maybe_cast<int64_t>( +0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x000000feULL), saturate<int32_t>(maybe_cast<int64_t>( +0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x000000ffULL), saturate<int32_t>(maybe_cast<int64_t>( +0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000100ULL), saturate<int32_t>(maybe_cast<int64_t>( +0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00007ffeULL), saturate<int32_t>(maybe_cast<int64_t>( +0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00007fffULL), saturate<int32_t>(maybe_cast<int64_t>( +0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00008000ULL), saturate<int32_t>(maybe_cast<int64_t>( +0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000fffeULL), saturate<int32_t>(maybe_cast<int64_t>( +0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000ffffULL), saturate<int32_t>(maybe_cast<int64_t>( +0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00010000ULL), saturate<int32_t>(maybe_cast<int64_t>( +0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7ffffffeULL), saturate<int32_t>(maybe_cast<int64_t>( +0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<int64_t>( +0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<int64_t>( +0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<int64_t>( +0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<int64_t>( +0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<int64_t>( +0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<int64_t>( +0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<int64_t>( +0x7fffffffffffffffULL))); + + EXPECT_EQ(maybe_cast<int32_t>(+0x00000000ULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000001ULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000007eULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000007fULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000080ULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x000000feULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x000000ffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00000100ULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00007ffeULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00007fffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00008000ULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000fffeULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x0000ffffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x00010000ULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7ffffffeULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0xfffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int32_t>(+0x7fffffffULL), saturate<int32_t>(maybe_cast<uint64_t>(+0xffffffffffffffffULL))); +} + +TEST(ints, satu32) +{ + EXPECT_EQ(maybe_cast<uint32_t>(+0x00ULL), saturate<uint32_t>(maybe_cast<int8_t>( -0x80ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00ULL), saturate<uint32_t>(maybe_cast<int8_t>( -0x7fULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00ULL), saturate<uint32_t>(maybe_cast<int8_t>( -0x7eULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00ULL), saturate<uint32_t>(maybe_cast<int8_t>( -0x01ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00ULL), saturate<uint32_t>(maybe_cast<int8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x01ULL), saturate<uint32_t>(maybe_cast<int8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7eULL), saturate<uint32_t>(maybe_cast<int8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7fULL), saturate<uint32_t>(maybe_cast<int8_t>( +0x7fULL))); + + EXPECT_EQ(maybe_cast<uint32_t>(+0x00ULL), saturate<uint32_t>(maybe_cast<uint8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x01ULL), saturate<uint32_t>(maybe_cast<uint8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7eULL), saturate<uint32_t>(maybe_cast<uint8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7fULL), saturate<uint32_t>(maybe_cast<uint8_t>( +0x7fULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x80ULL), saturate<uint32_t>(maybe_cast<uint8_t>( +0x80ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xfeULL), saturate<uint32_t>(maybe_cast<uint8_t>( +0xfeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffULL), saturate<uint32_t>(maybe_cast<uint8_t>( +0xffULL))); + + + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ULL), saturate<uint32_t>(maybe_cast<int16_t>( -0x8000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ULL), saturate<uint32_t>(maybe_cast<int16_t>( -0x7fffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ULL), saturate<uint32_t>(maybe_cast<int16_t>( -0x0100ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ULL), saturate<uint32_t>(maybe_cast<int16_t>( -0x00ffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ULL), saturate<uint32_t>(maybe_cast<int16_t>( -0x00feULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ULL), saturate<uint32_t>(maybe_cast<int16_t>( -0x0081ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ULL), saturate<uint32_t>(maybe_cast<int16_t>( -0x0080ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ULL), saturate<uint32_t>(maybe_cast<int16_t>( -0x007fULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ULL), saturate<uint32_t>(maybe_cast<int16_t>( -0x0001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ULL), saturate<uint32_t>(maybe_cast<int16_t>( +0x0000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0001ULL), saturate<uint32_t>(maybe_cast<int16_t>( +0x0001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x007eULL), saturate<uint32_t>(maybe_cast<int16_t>( +0x007eULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x007fULL), saturate<uint32_t>(maybe_cast<int16_t>( +0x007fULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0080ULL), saturate<uint32_t>(maybe_cast<int16_t>( +0x0080ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00feULL), saturate<uint32_t>(maybe_cast<int16_t>( +0x00feULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00ffULL), saturate<uint32_t>(maybe_cast<int16_t>( +0x00ffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0100ULL), saturate<uint32_t>(maybe_cast<int16_t>( +0x0100ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7ffeULL), saturate<uint32_t>(maybe_cast<int16_t>( +0x7ffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7fffULL), saturate<uint32_t>(maybe_cast<int16_t>( +0x7fffULL))); + + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0x0000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0001ULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0x0001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x007eULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0x007eULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x007fULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0x007fULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0080ULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0x0080ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00feULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0x00feULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00ffULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0x00ffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0100ULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0x0100ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7ffeULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0x7ffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7fffULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0x7fffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x8000ULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0x8000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xfffeULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0xfffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffULL), saturate<uint32_t>(maybe_cast<uint16_t>(+0xffffULL))); + + + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x80000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x7fffffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x00008001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x000000feULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x00000081ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( -0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x00000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000001ULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000007eULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x0000007eULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000007fULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000080ULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x000000feULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x000000feULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x000000ffULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000100ULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00007ffeULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x00007ffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00007fffULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00008000ULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000fffeULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ffffULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00010000ULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7ffffffeULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7fffffffULL), saturate<uint32_t>(maybe_cast<int32_t>( +0x7fffffffULL))); + + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x00000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000001ULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000007eULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x0000007eULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000007fULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000080ULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x000000feULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x000000feULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x000000ffULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000100ULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00007ffeULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x00007ffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00007fffULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00008000ULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000fffeULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ffffULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00010000ULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7ffffffeULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7fffffffULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x7fffffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x80000000ULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0x80000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xfffffffeULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0xfffffffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<uint32_t>(+0xffffffffULL))); + + + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x0000000080000001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x0000000000008001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x0000000000000081ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( -0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000001ULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000007eULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000007fULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000080ULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x000000feULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x000000ffULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000100ULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00007ffeULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00007fffULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00008000ULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000fffeULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ffffULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00010000ULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7ffffffeULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7fffffffULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x80000000ULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xfffffffeULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<int64_t>( +0x7fffffffffffffffULL))); + + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000000ULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000001ULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000007eULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000007fULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000080ULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x000000feULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x000000ffULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00000100ULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00007ffeULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00007fffULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00008000ULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000fffeULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x0000ffffULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x00010000ULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7ffffffeULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x7fffffffULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0x80000000ULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xfffffffeULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0xfffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint32_t>(+0xffffffffULL), saturate<uint32_t>(maybe_cast<uint64_t>(+0xffffffffffffffffULL))); +} + +TEST(ints, sati64) +{ + EXPECT_EQ(maybe_cast<int64_t>(-0x80ULL), saturate<int64_t>(maybe_cast<int8_t>( -0x80ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x7fULL), saturate<int64_t>(maybe_cast<int8_t>( -0x7fULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x7eULL), saturate<int64_t>(maybe_cast<int8_t>( -0x7eULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x01ULL), saturate<int64_t>(maybe_cast<int8_t>( -0x01ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00ULL), saturate<int64_t>(maybe_cast<int8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x01ULL), saturate<int64_t>(maybe_cast<int8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7eULL), saturate<int64_t>(maybe_cast<int8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7fULL), saturate<int64_t>(maybe_cast<int8_t>( +0x7fULL))); + + EXPECT_EQ(maybe_cast<int64_t>(+0x00ULL), saturate<int64_t>(maybe_cast<uint8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x01ULL), saturate<int64_t>(maybe_cast<uint8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7eULL), saturate<int64_t>(maybe_cast<uint8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7fULL), saturate<int64_t>(maybe_cast<uint8_t>( +0x7fULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x80ULL), saturate<int64_t>(maybe_cast<uint8_t>( +0x80ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0xfeULL), saturate<int64_t>(maybe_cast<uint8_t>( +0xfeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0xffULL), saturate<int64_t>(maybe_cast<uint8_t>( +0xffULL))); + + + EXPECT_EQ(maybe_cast<int64_t>(-0x8000ULL), saturate<int64_t>(maybe_cast<int16_t>( -0x8000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x7fffULL), saturate<int64_t>(maybe_cast<int16_t>( -0x7fffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0100ULL), saturate<int64_t>(maybe_cast<int16_t>( -0x0100ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00ffULL), saturate<int64_t>(maybe_cast<int16_t>( -0x00ffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00feULL), saturate<int64_t>(maybe_cast<int16_t>( -0x00feULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0081ULL), saturate<int64_t>(maybe_cast<int16_t>( -0x0081ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0080ULL), saturate<int64_t>(maybe_cast<int16_t>( -0x0080ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x007fULL), saturate<int64_t>(maybe_cast<int16_t>( -0x007fULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0001ULL), saturate<int64_t>(maybe_cast<int16_t>( -0x0001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000ULL), saturate<int64_t>(maybe_cast<int16_t>( +0x0000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0001ULL), saturate<int64_t>(maybe_cast<int16_t>( +0x0001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x007eULL), saturate<int64_t>(maybe_cast<int16_t>( +0x007eULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x007fULL), saturate<int64_t>(maybe_cast<int16_t>( +0x007fULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0080ULL), saturate<int64_t>(maybe_cast<int16_t>( +0x0080ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00feULL), saturate<int64_t>(maybe_cast<int16_t>( +0x00feULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00ffULL), saturate<int64_t>(maybe_cast<int16_t>( +0x00ffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0100ULL), saturate<int64_t>(maybe_cast<int16_t>( +0x0100ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7ffeULL), saturate<int64_t>(maybe_cast<int16_t>( +0x7ffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7fffULL), saturate<int64_t>(maybe_cast<int16_t>( +0x7fffULL))); + + EXPECT_EQ(maybe_cast<int64_t>(+0x0000ULL), saturate<int64_t>(maybe_cast<uint16_t>(+0x0000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0001ULL), saturate<int64_t>(maybe_cast<uint16_t>(+0x0001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x007eULL), saturate<int64_t>(maybe_cast<uint16_t>(+0x007eULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x007fULL), saturate<int64_t>(maybe_cast<uint16_t>(+0x007fULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0080ULL), saturate<int64_t>(maybe_cast<uint16_t>(+0x0080ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00feULL), saturate<int64_t>(maybe_cast<uint16_t>(+0x00feULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00ffULL), saturate<int64_t>(maybe_cast<uint16_t>(+0x00ffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0100ULL), saturate<int64_t>(maybe_cast<uint16_t>(+0x0100ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7ffeULL), saturate<int64_t>(maybe_cast<uint16_t>(+0x7ffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7fffULL), saturate<int64_t>(maybe_cast<uint16_t>(+0x7fffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x8000ULL), saturate<int64_t>(maybe_cast<uint16_t>(+0x8000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0xfffeULL), saturate<int64_t>(maybe_cast<uint16_t>(+0xfffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0xffffULL), saturate<int64_t>(maybe_cast<uint16_t>(+0xffffULL))); + + + EXPECT_EQ(maybe_cast<int64_t>(-0x80000000ULL), saturate<int64_t>(maybe_cast<int32_t>( -0x80000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x7fffffffULL), saturate<int64_t>(maybe_cast<int32_t>( -0x7fffffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00010000ULL), saturate<int64_t>(maybe_cast<int32_t>( -0x00010000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000ffffULL), saturate<int64_t>(maybe_cast<int32_t>( -0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000fffeULL), saturate<int64_t>(maybe_cast<int32_t>( -0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00008001ULL), saturate<int64_t>(maybe_cast<int32_t>( -0x00008001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00008000ULL), saturate<int64_t>(maybe_cast<int32_t>( -0x00008000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00007fffULL), saturate<int64_t>(maybe_cast<int32_t>( -0x00007fffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00000100ULL), saturate<int64_t>(maybe_cast<int32_t>( -0x00000100ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x000000ffULL), saturate<int64_t>(maybe_cast<int32_t>( -0x000000ffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x000000feULL), saturate<int64_t>(maybe_cast<int32_t>( -0x000000feULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00000081ULL), saturate<int64_t>(maybe_cast<int32_t>( -0x00000081ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00000080ULL), saturate<int64_t>(maybe_cast<int32_t>( -0x00000080ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000007fULL), saturate<int64_t>(maybe_cast<int32_t>( -0x0000007fULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00000001ULL), saturate<int64_t>(maybe_cast<int32_t>( -0x00000001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000000ULL), saturate<int64_t>(maybe_cast<int32_t>( +0x00000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000001ULL), saturate<int64_t>(maybe_cast<int32_t>( +0x00000001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000007eULL), saturate<int64_t>(maybe_cast<int32_t>( +0x0000007eULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000007fULL), saturate<int64_t>(maybe_cast<int32_t>( +0x0000007fULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000080ULL), saturate<int64_t>(maybe_cast<int32_t>( +0x00000080ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000feULL), saturate<int64_t>(maybe_cast<int32_t>( +0x000000feULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000ffULL), saturate<int64_t>(maybe_cast<int32_t>( +0x000000ffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000100ULL), saturate<int64_t>(maybe_cast<int32_t>( +0x00000100ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00007ffeULL), saturate<int64_t>(maybe_cast<int32_t>( +0x00007ffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00007fffULL), saturate<int64_t>(maybe_cast<int32_t>( +0x00007fffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00008000ULL), saturate<int64_t>(maybe_cast<int32_t>( +0x00008000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000fffeULL), saturate<int64_t>(maybe_cast<int32_t>( +0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000ffffULL), saturate<int64_t>(maybe_cast<int32_t>( +0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00010000ULL), saturate<int64_t>(maybe_cast<int32_t>( +0x00010000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7ffffffeULL), saturate<int64_t>(maybe_cast<int32_t>( +0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7fffffffULL), saturate<int64_t>(maybe_cast<int32_t>( +0x7fffffffULL))); + + EXPECT_EQ(maybe_cast<int64_t>(+0x00000000ULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x00000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000001ULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x00000001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000007eULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x0000007eULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000007fULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x0000007fULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000080ULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x00000080ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000feULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x000000feULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000ffULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x000000ffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000100ULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x00000100ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00007ffeULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x00007ffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00007fffULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x00007fffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00008000ULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x00008000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000fffeULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x0000fffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000ffffULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x0000ffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00010000ULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x00010000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7ffffffeULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7fffffffULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x7fffffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x80000000ULL), saturate<int64_t>(maybe_cast<uint32_t>(+0x80000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0xfffffffeULL), saturate<int64_t>(maybe_cast<uint32_t>(+0xfffffffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0xffffffffULL), saturate<int64_t>(maybe_cast<uint32_t>(+0xffffffffULL))); + + + EXPECT_EQ(maybe_cast<int64_t>(-0x8000000000000000ULL), saturate<int64_t>(maybe_cast<int64_t>( -0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x7fffffffffffffffULL), saturate<int64_t>(maybe_cast<int64_t>( -0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000000100000000ULL), saturate<int64_t>(maybe_cast<int64_t>( -0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00000000ffffffffULL), saturate<int64_t>(maybe_cast<int64_t>( -0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00000000fffffffeULL), saturate<int64_t>(maybe_cast<int64_t>( -0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000000080000001ULL), saturate<int64_t>(maybe_cast<int64_t>( -0x0000000080000001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000000080000000ULL), saturate<int64_t>(maybe_cast<int64_t>( -0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x000000007fffffffULL), saturate<int64_t>(maybe_cast<int64_t>( -0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000000000010000ULL), saturate<int64_t>(maybe_cast<int64_t>( -0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x000000000000ffffULL), saturate<int64_t>(maybe_cast<int64_t>( -0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x000000000000fffeULL), saturate<int64_t>(maybe_cast<int64_t>( -0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000000000008001ULL), saturate<int64_t>(maybe_cast<int64_t>( -0x0000000000008001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000000000008000ULL), saturate<int64_t>(maybe_cast<int64_t>( -0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000000000007fffULL), saturate<int64_t>(maybe_cast<int64_t>( -0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000000000000100ULL), saturate<int64_t>(maybe_cast<int64_t>( -0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00000000000000ffULL), saturate<int64_t>(maybe_cast<int64_t>( -0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x00000000000000feULL), saturate<int64_t>(maybe_cast<int64_t>( -0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000000000000081ULL), saturate<int64_t>(maybe_cast<int64_t>( -0x0000000000000081ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000000000000080ULL), saturate<int64_t>(maybe_cast<int64_t>( -0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x000000000000007fULL), saturate<int64_t>(maybe_cast<int64_t>( -0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int64_t>(-0x0000000000000001ULL), saturate<int64_t>(maybe_cast<int64_t>( -0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000000000ULL), saturate<int64_t>(maybe_cast<int64_t>( +0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000000001ULL), saturate<int64_t>(maybe_cast<int64_t>( +0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000000000007eULL), saturate<int64_t>(maybe_cast<int64_t>( +0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000000000007fULL), saturate<int64_t>(maybe_cast<int64_t>( +0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000000080ULL), saturate<int64_t>(maybe_cast<int64_t>( +0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000000000000feULL), saturate<int64_t>(maybe_cast<int64_t>( +0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000000000000ffULL), saturate<int64_t>(maybe_cast<int64_t>( +0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000000100ULL), saturate<int64_t>(maybe_cast<int64_t>( +0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000007ffeULL), saturate<int64_t>(maybe_cast<int64_t>( +0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000007fffULL), saturate<int64_t>(maybe_cast<int64_t>( +0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000008000ULL), saturate<int64_t>(maybe_cast<int64_t>( +0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000000000fffeULL), saturate<int64_t>(maybe_cast<int64_t>( +0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000000000ffffULL), saturate<int64_t>(maybe_cast<int64_t>( +0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000010000ULL), saturate<int64_t>(maybe_cast<int64_t>( +0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000007ffffffeULL), saturate<int64_t>(maybe_cast<int64_t>( +0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000007fffffffULL), saturate<int64_t>(maybe_cast<int64_t>( +0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000080000000ULL), saturate<int64_t>(maybe_cast<int64_t>( +0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000000fffffffeULL), saturate<int64_t>(maybe_cast<int64_t>( +0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000000ffffffffULL), saturate<int64_t>(maybe_cast<int64_t>( +0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000100000000ULL), saturate<int64_t>(maybe_cast<int64_t>( +0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7ffffffffffffffeULL), saturate<int64_t>(maybe_cast<int64_t>( +0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7fffffffffffffffULL), saturate<int64_t>(maybe_cast<int64_t>( +0x7fffffffffffffffULL))); + + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000000000ULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000000001ULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000000000007eULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000000000007fULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000000080ULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000000000000feULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000000000000ffULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000000100ULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000007ffeULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000007fffULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000008000ULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000000000fffeULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000000000ffffULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000000010000ULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000007ffffffeULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x000000007fffffffULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000080000000ULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000000fffffffeULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x00000000ffffffffULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x0000000100000000ULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7ffffffffffffffeULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7fffffffffffffffULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7fffffffffffffffULL), saturate<int64_t>(maybe_cast<uint64_t>(+0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7fffffffffffffffULL), saturate<int64_t>(maybe_cast<uint64_t>(+0xfffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<int64_t>(+0x7fffffffffffffffULL), saturate<int64_t>(maybe_cast<uint64_t>(+0xffffffffffffffffULL))); +} + +TEST(ints, satu64) +{ + EXPECT_EQ(maybe_cast<uint64_t>(+0x00ULL), saturate<uint64_t>(maybe_cast<int8_t>( -0x80ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00ULL), saturate<uint64_t>(maybe_cast<int8_t>( -0x7fULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00ULL), saturate<uint64_t>(maybe_cast<int8_t>( -0x7eULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00ULL), saturate<uint64_t>(maybe_cast<int8_t>( -0x01ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00ULL), saturate<uint64_t>(maybe_cast<int8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x01ULL), saturate<uint64_t>(maybe_cast<int8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7eULL), saturate<uint64_t>(maybe_cast<int8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7fULL), saturate<uint64_t>(maybe_cast<int8_t>( +0x7fULL))); + + EXPECT_EQ(maybe_cast<uint64_t>(+0x00ULL), saturate<uint64_t>(maybe_cast<uint8_t>( +0x00ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x01ULL), saturate<uint64_t>(maybe_cast<uint8_t>( +0x01ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7eULL), saturate<uint64_t>(maybe_cast<uint8_t>( +0x7eULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7fULL), saturate<uint64_t>(maybe_cast<uint8_t>( +0x7fULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x80ULL), saturate<uint64_t>(maybe_cast<uint8_t>( +0x80ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0xfeULL), saturate<uint64_t>(maybe_cast<uint8_t>( +0xfeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0xffULL), saturate<uint64_t>(maybe_cast<uint8_t>( +0xffULL))); + + + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ULL), saturate<uint64_t>(maybe_cast<int16_t>( -0x8000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ULL), saturate<uint64_t>(maybe_cast<int16_t>( -0x7fffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ULL), saturate<uint64_t>(maybe_cast<int16_t>( -0x0100ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ULL), saturate<uint64_t>(maybe_cast<int16_t>( -0x00ffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ULL), saturate<uint64_t>(maybe_cast<int16_t>( -0x00feULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ULL), saturate<uint64_t>(maybe_cast<int16_t>( -0x0081ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ULL), saturate<uint64_t>(maybe_cast<int16_t>( -0x0080ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ULL), saturate<uint64_t>(maybe_cast<int16_t>( -0x007fULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ULL), saturate<uint64_t>(maybe_cast<int16_t>( -0x0001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ULL), saturate<uint64_t>(maybe_cast<int16_t>( +0x0000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0001ULL), saturate<uint64_t>(maybe_cast<int16_t>( +0x0001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x007eULL), saturate<uint64_t>(maybe_cast<int16_t>( +0x007eULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x007fULL), saturate<uint64_t>(maybe_cast<int16_t>( +0x007fULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0080ULL), saturate<uint64_t>(maybe_cast<int16_t>( +0x0080ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00feULL), saturate<uint64_t>(maybe_cast<int16_t>( +0x00feULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00ffULL), saturate<uint64_t>(maybe_cast<int16_t>( +0x00ffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0100ULL), saturate<uint64_t>(maybe_cast<int16_t>( +0x0100ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7ffeULL), saturate<uint64_t>(maybe_cast<int16_t>( +0x7ffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7fffULL), saturate<uint64_t>(maybe_cast<int16_t>( +0x7fffULL))); + + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0x0000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0001ULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0x0001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x007eULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0x007eULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x007fULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0x007fULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0080ULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0x0080ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00feULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0x00feULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00ffULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0x00ffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0100ULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0x0100ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7ffeULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0x7ffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7fffULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0x7fffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x8000ULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0x8000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0xfffeULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0xfffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0xffffULL), saturate<uint64_t>(maybe_cast<uint16_t>(+0xffffULL))); + + + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x80000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x7fffffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x00008001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x000000feULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x00000081ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( -0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x00000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000001ULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000007eULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x0000007eULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000007fULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000080ULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000feULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x000000feULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000ffULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000100ULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00007ffeULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x00007ffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00007fffULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00008000ULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000fffeULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ffffULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00010000ULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7ffffffeULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7fffffffULL), saturate<uint64_t>(maybe_cast<int32_t>( +0x7fffffffULL))); + + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x00000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000001ULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x00000001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000007eULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x0000007eULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000007fULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x0000007fULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000080ULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x00000080ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000feULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x000000feULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000ffULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x000000ffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000100ULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x00000100ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00007ffeULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x00007ffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00007fffULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x00007fffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00008000ULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x00008000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000fffeULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x0000fffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000ffffULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x0000ffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00010000ULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x00010000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7ffffffeULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x7ffffffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7fffffffULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x7fffffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x80000000ULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0x80000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0xfffffffeULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0xfffffffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0xffffffffULL), saturate<uint64_t>(maybe_cast<uint32_t>(+0xffffffffULL))); + + + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x0000000080000001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x0000000000008001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x0000000000000081ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( -0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000001ULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000000000007eULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000000000007fULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000080ULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000000000feULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000000000ffULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000100ULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000007ffeULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000007fffULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000008000ULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000000000fffeULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000000000ffffULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000010000ULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000007ffffffeULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000007fffffffULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000080000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000fffffffeULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ffffffffULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000100000000ULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7ffffffffffffffeULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7fffffffffffffffULL), saturate<uint64_t>(maybe_cast<int64_t>( +0x7fffffffffffffffULL))); + + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000000ULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x0000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000001ULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x0000000000000001ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000000000007eULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x000000000000007eULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000000000007fULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x000000000000007fULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000080ULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x0000000000000080ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000000000feULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x00000000000000feULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000000000ffULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x00000000000000ffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000000100ULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x0000000000000100ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000007ffeULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x0000000000007ffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000007fffULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x0000000000007fffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000008000ULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x0000000000008000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000000000fffeULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x000000000000fffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000000000ffffULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x000000000000ffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000000010000ULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x0000000000010000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000007ffffffeULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x000000007ffffffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x000000007fffffffULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x000000007fffffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000080000000ULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x0000000080000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000fffffffeULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x00000000fffffffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x00000000ffffffffULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x00000000ffffffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x0000000100000000ULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x0000000100000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7ffffffffffffffeULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x7ffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x7fffffffffffffffULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x7fffffffffffffffULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0x8000000000000000ULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0x8000000000000000ULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0xfffffffffffffffeULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0xfffffffffffffffeULL))); + EXPECT_EQ(maybe_cast<uint64_t>(+0xffffffffffffffffULL), saturate<uint64_t>(maybe_cast<uint64_t>(+0xffffffffffffffffULL))); +} +} // namespace tmwa diff --git a/src/ints/fwd.hpp b/src/ints/fwd.hpp new file mode 100644 index 0000000..a08e546 --- /dev/null +++ b/src/ints/fwd.hpp @@ -0,0 +1,27 @@ +#pragma once +// ints/fwd.hpp - list of type names for ints library +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +// meh, add more when I feel like it +} // namespace tmwa diff --git a/src/ints/little.cpp b/src/ints/little.cpp new file mode 100644 index 0000000..0ae5bf7 --- /dev/null +++ b/src/ints/little.cpp @@ -0,0 +1,26 @@ +#include "little.hpp" +// little.cpp - integers of known endianness +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/ints/little.hpp b/src/ints/little.hpp new file mode 100644 index 0000000..b3046f7 --- /dev/null +++ b/src/ints/little.hpp @@ -0,0 +1,210 @@ +#pragma once +// little.hpp - integers of known endianness +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include <endian.h> + +#include <cstdint> + + +namespace tmwa +{ +// We implement our own actual swapping, because glibc emits assembly +// instead of letting the *compiler* do what it does best. +#if __BYTE_ORDER != __BIG_ENDIAN && __BYTE_ORDER != __LITTLE_ENDIAN +# error "broken endians" +#endif + +namespace ints +{ + // gcc doesn't always provide a builtin for this, + // but it *does* optimize hand-written ones + constexpr + uint16_t bswap16(uint16_t v) + { + return v >> 8 | v << 8; + } + + // TODO hoist this to byte.hpp and also implement big.hpp + struct Byte + { + uint8_t value; + }; + + struct Little16 + { + uint8_t data[2]; + }; + + struct Little32 + { + uint8_t data[4]; + }; + + struct Little64 + { + uint8_t data[8]; + }; + + + inline __attribute__((warn_unused_result)) + bool native_to_network(Byte *net, uint8_t nat) + { + net->value = nat; + return true; + } + inline __attribute__((warn_unused_result)) + bool native_to_network(Little16 *net, uint16_t nat) + { + if (__BYTE_ORDER == __BIG_ENDIAN) + nat = bswap16(nat); + __builtin_memcpy(net, &nat, 2); + return true; + } + inline __attribute__((warn_unused_result)) + bool native_to_network(Little32 *net, uint32_t nat) + { + if (__BYTE_ORDER == __BIG_ENDIAN) + nat = __builtin_bswap32(nat); + __builtin_memcpy(net, &nat, 4); + return true; + } + inline __attribute__((warn_unused_result)) + bool native_to_network(Little64 *net, uint64_t nat) + { + if (__BYTE_ORDER == __BIG_ENDIAN) + nat = __builtin_bswap64(nat); + __builtin_memcpy(net, &nat, 8); + return true; + } + + inline __attribute__((warn_unused_result)) + bool network_to_native(uint8_t *nat, Byte net) + { + *nat = net.value; + return true; + } + inline __attribute__((warn_unused_result)) + bool network_to_native(uint16_t *nat, Little16 net) + { + uint16_t tmp; + __builtin_memcpy(&tmp, &net, 2); + if (__BYTE_ORDER == __BIG_ENDIAN) + tmp = bswap16(tmp); + *nat = tmp; + return true; + } + inline __attribute__((warn_unused_result)) + bool network_to_native(uint32_t *nat, Little32 net) + { + uint32_t tmp; + __builtin_memcpy(&tmp, &net, 4); + if (__BYTE_ORDER == __BIG_ENDIAN) + tmp = __builtin_bswap32(tmp); + *nat = tmp; + return true; + } + inline __attribute__((warn_unused_result)) + bool network_to_native(uint64_t *nat, Little64 net) + { + uint64_t tmp; + __builtin_memcpy(&tmp, &net, 8); + if (__BYTE_ORDER == __BIG_ENDIAN) + tmp = __builtin_bswap64(tmp); + *nat = tmp; + return true; + } + + + inline __attribute__((warn_unused_result)) + bool native_to_network(Byte *net, int8_t nat) + { + net->value = nat; + return true; + } + inline __attribute__((warn_unused_result)) + bool native_to_network(Little16 *net, int16_t nat) + { + if (__BYTE_ORDER == __BIG_ENDIAN) + nat = bswap16(nat); + __builtin_memcpy(net, &nat, 2); + return true; + } + inline __attribute__((warn_unused_result)) + bool native_to_network(Little32 *net, int32_t nat) + { + if (__BYTE_ORDER == __BIG_ENDIAN) + nat = __builtin_bswap32(nat); + __builtin_memcpy(net, &nat, 4); + return true; + } + inline __attribute__((warn_unused_result)) + bool native_to_network(Little64 *net, int64_t nat) + { + if (__BYTE_ORDER == __BIG_ENDIAN) + nat = __builtin_bswap64(nat); + __builtin_memcpy(net, &nat, 8); + return true; + } + + inline __attribute__((warn_unused_result)) + bool network_to_native(int8_t *nat, Byte net) + { + *nat = net.value; + return true; + } + inline __attribute__((warn_unused_result)) + bool network_to_native(int16_t *nat, Little16 net) + { + int16_t tmp; + __builtin_memcpy(&tmp, &net, 2); + if (__BYTE_ORDER == __BIG_ENDIAN) + tmp = bswap16(tmp); + *nat = tmp; + return true; + } + inline __attribute__((warn_unused_result)) + bool network_to_native(int32_t *nat, Little32 net) + { + int32_t tmp; + __builtin_memcpy(&tmp, &net, 4); + if (__BYTE_ORDER == __BIG_ENDIAN) + tmp = __builtin_bswap32(tmp); + *nat = tmp; + return true; + } + inline __attribute__((warn_unused_result)) + bool network_to_native(int64_t *nat, Little64 net) + { + int64_t tmp; + __builtin_memcpy(&tmp, &net, 8); + if (__BYTE_ORDER == __BIG_ENDIAN) + tmp = __builtin_bswap64(tmp); + *nat = tmp; + return true; + } +} // namespace ints + +using ints::Byte; +using ints::Little16; +using ints::Little32; +using ints::Little64; +} // namespace tmwa diff --git a/src/ints/udl.cpp b/src/ints/udl.cpp new file mode 100644 index 0000000..3988903 --- /dev/null +++ b/src/ints/udl.cpp @@ -0,0 +1,26 @@ +#include "udl.hpp" +// udl.cpp - user-defined literals for integers. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/ints/udl.hpp b/src/ints/udl.hpp new file mode 100644 index 0000000..f85a186 --- /dev/null +++ b/src/ints/udl.hpp @@ -0,0 +1,227 @@ +#pragma once +// udl.hpp - user-defined literals for integers. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include <cstdint> + +#include <type_traits> + + +namespace tmwa +{ +namespace ints +{ + namespace + { + typedef unsigned long long ullong; + template<char C> + struct CharParser + { + constexpr static + bool is_dec = '0' <= C && C <= '9'; + constexpr static + bool is_upper = 'A' <= C && C <= 'F'; + constexpr static + bool is_lower = 'a' <= C && C <= 'f'; + + static_assert(is_dec || is_upper || is_lower, "char base"); + + constexpr static + ullong value = is_upper ? (C - 'A' + 10) : is_lower ? (C - 'a' + 10) : C - '0'; + }; + + template<ullong base, ullong accum, char... C> + struct BaseParser; + template<ullong base, ullong accum, char F, char... R> + struct BaseParser<base, accum, F, R...> + { + constexpr static + ullong mulled = accum * base; + constexpr static + ullong add = CharParser<F>::value; + static_assert(add < base, "parse base"); + constexpr static + ullong added = mulled + add; + static_assert(added > accum || accum == 0, "parse overflow"); + + constexpr static + ullong value = BaseParser<base, added, R...>::value; + }; + template<ullong base, ullong accum> + struct BaseParser<base, accum> + { + constexpr static + ullong value = accum; + }; + + template<char... C> + struct IntParser + { + constexpr static + ullong value = BaseParser<10, 0, C...>::value; + }; + + template<char... C> + struct IntParser<'0', C...> + { + constexpr static + ullong value = BaseParser<8, 0, C...>::value; + }; + + template<char... C> + struct IntParser<'0', 'x', C...> + { + constexpr static + ullong value = BaseParser<16, 0, C...>::value; + }; + + template<char... C> + struct IntParser<'0', 'X', C...> + { + constexpr static + ullong value = BaseParser<16, 0, C...>::value; + }; + + template<char... C> + struct IntParser<'0', 'b', C...> + { + constexpr static + ullong value = BaseParser<2, 0, C...>::value; + }; + + template<char... C> + struct IntParser<'0', 'B', C...> + { + constexpr static + ullong value = BaseParser<2, 0, C...>::value; + }; + + template<bool S, ullong V> + struct SignedMagnitudeConstant + { + static constexpr + bool sign = S; + static constexpr + ullong magnitude = V; + + template<class T> + constexpr + operator T() const + { + typedef typename std::make_unsigned<T>::type U; + // boo, body of constexpr function can't use variables +#define is_signed bool(T(-1) < T(0)) + static_assert(is_signed >= (sign && magnitude), "signed"); +#define max ullong(ullong(U(-1) >> is_signed)) + static_assert(magnitude <= max || (sign && magnitude == max + 1), "magna"); +#undef is_signed +#undef max + return sign ? T(ullong(-magnitude)) : T(magnitude); + } + }; + + template<bool S1, ullong V1, bool S2, ullong V2> + constexpr + bool operator == (SignedMagnitudeConstant<S1, V1>, SignedMagnitudeConstant<S2, V2>) + { + return V1 == V2 && (S1 == S2 || !V1); + } + template<bool S1, ullong V1, bool S2, ullong V2> + constexpr + bool operator != (SignedMagnitudeConstant<S1, V1> lhs, SignedMagnitudeConstant<S2, V2> rhs) + { + return !(lhs == rhs); + } + template<bool S, ullong V> + constexpr + SignedMagnitudeConstant<!S, V> operator -(SignedMagnitudeConstant<S, V>) + { + return {}; + } + + struct pint8 { int8_t value; int8_t operator +() { return value; } }; + struct pint16 { int16_t value; int16_t operator +() { return value; } }; + struct pint32 { int32_t value; int32_t operator +() { return value; } }; + struct pint64 { int64_t value; int64_t operator +() { return value; } }; + struct nint8 { int8_t value; int8_t operator -() { return value; } }; + struct nint16 { int16_t value; int16_t operator -() { return value; } }; + struct nint32 { int32_t value; int32_t operator -() { return value; } }; + struct nint64 { int64_t value; int64_t operator -() { return value; } }; + + template<char... C> + constexpr + SignedMagnitudeConstant<false, IntParser<C...>::value> operator "" _const() + { return {}; } + + template<char... C> + constexpr + uint8_t operator "" _u8 () { return operator "" _const<C...>(); } + template<char... C> + constexpr + uint16_t operator "" _u16 () { return operator "" _const<C...>(); } + template<char... C> + constexpr + uint32_t operator "" _u32 () { return operator "" _const<C...>(); } + template<char... C> + constexpr + uint64_t operator "" _u64 () { return operator "" _const<C...>(); } + template<char... C> + constexpr + pint8 operator "" _p8 () { return pint8{operator "" _const<C...>()}; } + template<char... C> + constexpr + pint16 operator "" _p16 () { return pint16{operator "" _const<C...>()}; } + template<char... C> + constexpr + pint32 operator "" _p32 () { return pint32{operator "" _const<C...>()}; } + template<char... C> + constexpr + pint64 operator "" _p64 () { return pint64{operator "" _const<C...>()}; } + template<char... C> + constexpr + nint8 operator "" _n8 () { return nint8{-operator "" _const<C...>()}; } + template<char... C> + constexpr + nint16 operator "" _n16 () { return nint16{-operator "" _const<C...>()}; } + template<char... C> + constexpr + nint32 operator "" _n32 () { return nint32{-operator "" _const<C...>()}; } + template<char... C> + constexpr + nint64 operator "" _n64 () { return nint64{-operator "" _const<C...>()}; } + } // anonymous namespace +} // namespace ints + +using ints::operator "" _const; + +using ints::operator "" _u8; +using ints::operator "" _u16; +using ints::operator "" _u32; +using ints::operator "" _u64; +using ints::operator "" _p8; +using ints::operator "" _p16; +using ints::operator "" _p32; +using ints::operator "" _p64; +using ints::operator "" _n8; +using ints::operator "" _n16; +using ints::operator "" _n32; +using ints::operator "" _n64; +} // namespace tmwa diff --git a/src/ints/udl_test.cpp b/src/ints/udl_test.cpp new file mode 100644 index 0000000..279edde --- /dev/null +++ b/src/ints/udl_test.cpp @@ -0,0 +1,788 @@ +#include "udl.hpp" +// udl_test.cpp - Testsuite for a user-defined integer suffixes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <gtest/gtest.h> + +#include "../compat/cast.hpp" + +#include "../diagnostics.hpp" +#include "../poison.hpp" + + +namespace tmwa +{ +DIAG_PUSH(); +DIAG_I(unused_variable); + +TEST(ints, smc) +{ + { + ints::SignedMagnitudeConstant<false, 0> i; + (void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + (void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0> i; + (void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + (void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x7e> i; + (void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + (void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x7e> i; + (void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x7f> i; + (void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + (void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x7f> i; + (void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x80> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + (void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x80> i; + (void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0xfe> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + (void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0xfe> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0xff> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + (void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0xff> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false,0x100> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x100> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x7ffe> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x7ffe> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x7fff> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x7fff> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x8000> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x8000> i; + //(void)static_cast<int8_t>(i); + (void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0xfffe> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0xfffe> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0xffff> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + (void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0xffff> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false,0x10000> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x10000> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x7ffffffe> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x7ffffffe> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x7fffffff> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x7fffffff> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x80000000> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x80000000> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + (void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0xfffffffe> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0xfffffffe> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0xffffffff> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + (void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0xffffffff> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false,0x100000000> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + //(void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x100000000> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x7ffffffffffffffe> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + //(void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x7ffffffffffffffe> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x7fffffffffffffff> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + //(void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x7fffffffffffffff> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0x8000000000000000> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + //(void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + //(void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0x8000000000000000> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + (void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0xfffffffffffffffe> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + //(void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + //(void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0xfffffffffffffffe> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + //(void)static_cast<int64_t>(i); + } + { + ints::SignedMagnitudeConstant<false, 0xffffffffffffffff> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + //(void)static_cast<int64_t>(i); + //(void)static_cast<uint8_t>(i); + //(void)static_cast<uint16_t>(i); + //(void)static_cast<uint32_t>(i); + (void)static_cast<uint64_t>(i); + } + { + ints::SignedMagnitudeConstant<true, 0xffffffffffffffff> i; + //(void)static_cast<int8_t>(i); + //(void)static_cast<int16_t>(i); + //(void)static_cast<int32_t>(i); + //(void)static_cast<int64_t>(i); + } + { + //ints::SignedMagnitudeConstant<false,0x10000000000000000> i; + } + { + //ints::SignedMagnitudeConstant<true, 0x10000000000000000> i; + } +} +DIAG_POP(); + +TEST(ints, constant) +{ + // gtest is funny with conversions + assert(0_const == (ints::SignedMagnitudeConstant<false, 0>{})); + assert(1_const == (ints::SignedMagnitudeConstant<false, 1>{})); + assert(1_const == (ints::SignedMagnitudeConstant<false, 1>{})); +} + +TEST(ints, udl8) +{ + EXPECT_EQ(0b00000000_u8, maybe_cast<uint8_t>(0b00000000U)); + EXPECT_EQ(0b00000001_u8, maybe_cast<uint8_t>(0b00000001U)); + EXPECT_EQ(0b11111110_u8, maybe_cast<uint8_t>(0b11111110U)); + EXPECT_EQ(0b11111111_u8, maybe_cast<uint8_t>(0b11111111U)); + EXPECT_EQ(-0b10000000_n8, maybe_cast<int8_t>(-0b10000000)); + EXPECT_EQ(-0b01111111_n8, maybe_cast<int8_t>(-0b01111111)); + EXPECT_EQ(-0b00000001_n8, maybe_cast<int8_t>(-0b00000001)); + EXPECT_EQ(+0b00000000_p8, maybe_cast<int8_t>(0b00000000)); + EXPECT_EQ(+0b00000001_p8, maybe_cast<int8_t>(0b00000001)); + EXPECT_EQ(+0b01111110_p8, maybe_cast<int8_t>(0b01111110)); + EXPECT_EQ(+0b01111111_p8, maybe_cast<int8_t>(0b01111111)); + + EXPECT_EQ(0B00000000_u8, maybe_cast<uint8_t>(0B00000000U)); + EXPECT_EQ(0B00000001_u8, maybe_cast<uint8_t>(0B00000001U)); + EXPECT_EQ(0B11111110_u8, maybe_cast<uint8_t>(0B11111110U)); + EXPECT_EQ(0B11111111_u8, maybe_cast<uint8_t>(0B11111111U)); + EXPECT_EQ(-0B10000000_n8, maybe_cast<int8_t>(-0B10000000)); + EXPECT_EQ(-0B01111111_n8, maybe_cast<int8_t>(-0B01111111)); + EXPECT_EQ(-0B00000001_n8, maybe_cast<int8_t>(-0B00000001)); + EXPECT_EQ(+0B00000000_p8, maybe_cast<int8_t>(0B00000000)); + EXPECT_EQ(+0B00000001_p8, maybe_cast<int8_t>(0B00000001)); + EXPECT_EQ(+0B01111110_p8, maybe_cast<int8_t>(0B01111110)); + EXPECT_EQ(+0B01111111_p8, maybe_cast<int8_t>(0B01111111)); + + EXPECT_EQ(0000_u8, maybe_cast<uint8_t>(0000U)); + EXPECT_EQ(0001_u8, maybe_cast<uint8_t>(0001U)); + EXPECT_EQ(0376_u8, maybe_cast<uint8_t>(0376U)); + EXPECT_EQ(0377_u8, maybe_cast<uint8_t>(0377U)); + EXPECT_EQ(-0200_n8, maybe_cast<int8_t>(-0200)); + EXPECT_EQ(-0177_n8, maybe_cast<int8_t>(-0177)); + EXPECT_EQ(-0001_n8, maybe_cast<int8_t>(-0001)); + EXPECT_EQ(+0000_p8, maybe_cast<int8_t>(0000)); + EXPECT_EQ(+0001_p8, maybe_cast<int8_t>(0001)); + EXPECT_EQ(+0176_p8, maybe_cast<int8_t>(0176)); + EXPECT_EQ(+0177_p8, maybe_cast<int8_t>(0177)); + + EXPECT_EQ(0_u8, maybe_cast<uint8_t>(0U)); + EXPECT_EQ(1_u8, maybe_cast<uint8_t>(1U)); + EXPECT_EQ(254_u8, maybe_cast<uint8_t>(254U)); + EXPECT_EQ(255_u8, maybe_cast<uint8_t>(255U)); + EXPECT_EQ(-128_n8, maybe_cast<int8_t>(-128)); + EXPECT_EQ(-127_n8, maybe_cast<int8_t>(-127)); + EXPECT_EQ(-1_n8, maybe_cast<int8_t>(-1)); + EXPECT_EQ(+0_p8, maybe_cast<int8_t>(0)); + EXPECT_EQ(+1_p8, maybe_cast<int8_t>(1)); + EXPECT_EQ(+126_p8, maybe_cast<int8_t>(126)); + EXPECT_EQ(+127_p8, maybe_cast<int8_t>(127)); + + EXPECT_EQ(0x00_u8, maybe_cast<uint8_t>(0x00U)); + EXPECT_EQ(0x01_u8, maybe_cast<uint8_t>(0x01U)); + EXPECT_EQ(0xfe_u8, maybe_cast<uint8_t>(0xfeU)); + EXPECT_EQ(0xff_u8, maybe_cast<uint8_t>(0xffU)); + EXPECT_EQ(-0x80_n8, maybe_cast<int8_t>(-0x80)); + EXPECT_EQ(-0x7f_n8, maybe_cast<int8_t>(-0x7f)); + EXPECT_EQ(-0x01_n8, maybe_cast<int8_t>(-0x01)); + EXPECT_EQ(+0x00_p8, maybe_cast<int8_t>(0x00)); + EXPECT_EQ(+0x01_p8, maybe_cast<int8_t>(0x01)); + EXPECT_EQ(+0x7e_p8, maybe_cast<int8_t>(0x7e)); + EXPECT_EQ(+0x7f_p8, maybe_cast<int8_t>(0x7f)); + + EXPECT_EQ(0X00_u8, maybe_cast<uint8_t>(0X00U)); + EXPECT_EQ(0X01_u8, maybe_cast<uint8_t>(0X01U)); + EXPECT_EQ(0XFE_u8, maybe_cast<uint8_t>(0XFEU)); + EXPECT_EQ(0XFF_u8, maybe_cast<uint8_t>(0XFFU)); + EXPECT_EQ(-0X80_n8, maybe_cast<int8_t>(-0X80)); + EXPECT_EQ(-0X7F_n8, maybe_cast<int8_t>(-0X7F)); + EXPECT_EQ(-0X01_n8, maybe_cast<int8_t>(-0X01)); + EXPECT_EQ(+0X00_p8, maybe_cast<int8_t>(0X00)); + EXPECT_EQ(+0X01_p8, maybe_cast<int8_t>(0X01)); + EXPECT_EQ(+0X7E_p8, maybe_cast<int8_t>(0X7E)); + EXPECT_EQ(+0X7F_p8, maybe_cast<int8_t>(0X7F)); +} + +TEST(ints, udl16) +{ + EXPECT_EQ(0b0000000000000000_u16, maybe_cast<uint16_t>(0b0000000000000000U)); + EXPECT_EQ(0b0000000000000001_u16, maybe_cast<uint16_t>(0b0000000000000001U)); + EXPECT_EQ(0b1111111111111110_u16, maybe_cast<uint16_t>(0b1111111111111110U)); + EXPECT_EQ(0b1111111111111111_u16, maybe_cast<uint16_t>(0b1111111111111111U)); + EXPECT_EQ(-0b1000000000000000_n16, maybe_cast<int16_t>(-0b1000000000000000)); + EXPECT_EQ(-0b0111111111111111_n16, maybe_cast<int16_t>(-0b0111111111111111)); + EXPECT_EQ(-0b0000000000000001_n16, maybe_cast<int16_t>(-0b0000000000000001)); + EXPECT_EQ(+0b0000000000000000_p16, maybe_cast<int16_t>(0b0000000000000000)); + EXPECT_EQ(+0b0000000000000001_p16, maybe_cast<int16_t>(0b0000000000000001)); + EXPECT_EQ(+0b0111111111111110_p16, maybe_cast<int16_t>(0b0111111111111110)); + EXPECT_EQ(+0b0111111111111111_p16, maybe_cast<int16_t>(0b0111111111111111)); + + EXPECT_EQ(0B0000000000000000_u16, maybe_cast<uint16_t>(0B0000000000000000U)); + EXPECT_EQ(0B0000000000000001_u16, maybe_cast<uint16_t>(0B0000000000000001U)); + EXPECT_EQ(0B1111111111111110_u16, maybe_cast<uint16_t>(0B1111111111111110U)); + EXPECT_EQ(0B1111111111111111_u16, maybe_cast<uint16_t>(0B1111111111111111U)); + EXPECT_EQ(-0B1000000000000000_n16, maybe_cast<int16_t>(-0B1000000000000000)); + EXPECT_EQ(-0B0111111111111111_n16, maybe_cast<int16_t>(-0B0111111111111111)); + EXPECT_EQ(-0B0000000000000001_n16, maybe_cast<int16_t>(-0B0000000000000001)); + EXPECT_EQ(+0B0000000000000000_p16, maybe_cast<int16_t>(0B0000000000000000)); + EXPECT_EQ(+0B0000000000000001_p16, maybe_cast<int16_t>(0B0000000000000001)); + EXPECT_EQ(+0B0111111111111110_p16, maybe_cast<int16_t>(0B0111111111111110)); + EXPECT_EQ(+0B0111111111111111_p16, maybe_cast<int16_t>(0B0111111111111111)); + + EXPECT_EQ(0000000_u16, maybe_cast<uint16_t>(0000000U)); + EXPECT_EQ(0000001_u16, maybe_cast<uint16_t>(0000001U)); + EXPECT_EQ(0177776_u16, maybe_cast<uint16_t>(0177776U)); + EXPECT_EQ(0177777_u16, maybe_cast<uint16_t>(0177777U)); + EXPECT_EQ(-0100000_n16, maybe_cast<int16_t>(-0100000)); + EXPECT_EQ(-0077777_n16, maybe_cast<int16_t>(-0077777)); + EXPECT_EQ(-0000001_n16, maybe_cast<int16_t>(-0000001)); + EXPECT_EQ(+000000_p16, maybe_cast<int16_t>(000000)); + EXPECT_EQ(+000001_p16, maybe_cast<int16_t>(000001)); + EXPECT_EQ(+077776_p16, maybe_cast<int16_t>(077776)); + EXPECT_EQ(+077777_p16, maybe_cast<int16_t>(077777)); + + EXPECT_EQ(0_u16, maybe_cast<uint16_t>(0U)); + EXPECT_EQ(1_u16, maybe_cast<uint16_t>(1U)); + EXPECT_EQ(65534_u16, maybe_cast<uint16_t>(65534U)); + EXPECT_EQ(65535_u16, maybe_cast<uint16_t>(65535U)); + EXPECT_EQ(-32768_n16, maybe_cast<int16_t>(-32768)); + EXPECT_EQ(-32767_n16, maybe_cast<int16_t>(-32767)); + EXPECT_EQ(-1_n16, maybe_cast<int16_t>(-1)); + EXPECT_EQ(+0_p16, maybe_cast<int16_t>(0)); + EXPECT_EQ(+1_p16, maybe_cast<int16_t>(1)); + EXPECT_EQ(+32766_p16, maybe_cast<int16_t>(32766)); + EXPECT_EQ(+32767_p16, maybe_cast<int16_t>(32767)); + + EXPECT_EQ(0x0000_u16, maybe_cast<uint16_t>(0x0000U)); + EXPECT_EQ(0x0001_u16, maybe_cast<uint16_t>(0x0001U)); + EXPECT_EQ(0xfffe_u16, maybe_cast<uint16_t>(0xfffeU)); + EXPECT_EQ(0xffff_u16, maybe_cast<uint16_t>(0xffffU)); + EXPECT_EQ(-0x8000_n16, maybe_cast<int16_t>(-0x8000)); + EXPECT_EQ(-0x7fff_n16, maybe_cast<int16_t>(-0x7fff)); + EXPECT_EQ(-0x0001_n16, maybe_cast<int16_t>(-0x0001)); + EXPECT_EQ(+0x0000_p16, maybe_cast<int16_t>(0x0000)); + EXPECT_EQ(+0x0001_p16, maybe_cast<int16_t>(0x0001)); + EXPECT_EQ(+0x7ffe_p16, maybe_cast<int16_t>(0x7ffe)); + EXPECT_EQ(+0x7fff_p16, maybe_cast<int16_t>(0x7fff)); + + EXPECT_EQ(0X0000_u16, maybe_cast<uint16_t>(0X0000U)); + EXPECT_EQ(0X0001_u16, maybe_cast<uint16_t>(0X0001U)); + EXPECT_EQ(0XFFFE_u16, maybe_cast<uint16_t>(0XFFFEU)); + EXPECT_EQ(0XFFFF_u16, maybe_cast<uint16_t>(0XFFFFU)); + EXPECT_EQ(-0X8000_n16, maybe_cast<int16_t>(-0X8000)); + EXPECT_EQ(-0X7FFF_n16, maybe_cast<int16_t>(-0X7FFF)); + EXPECT_EQ(-0X0001_n16, maybe_cast<int16_t>(-0X0001)); + EXPECT_EQ(+0X0000_p16, maybe_cast<int16_t>(0X0000)); + EXPECT_EQ(+0X0001_p16, maybe_cast<int16_t>(0X0001)); + EXPECT_EQ(+0X7FFE_p16, maybe_cast<int16_t>(0X7FFE)); + EXPECT_EQ(+0X7FFF_p16, maybe_cast<int16_t>(0X7FFF)); +} + +TEST(ints, udl32) +{ + EXPECT_EQ(0b00000000000000000000000000000000_u32, maybe_cast<uint32_t>(0b00000000000000000000000000000000U)); + EXPECT_EQ(0b00000000000000000000000000000001_u32, maybe_cast<uint32_t>(0b00000000000000000000000000000001U)); + EXPECT_EQ(0b11111111111111111111111111111110_u32, maybe_cast<uint32_t>(0b11111111111111111111111111111110U)); + EXPECT_EQ(0b11111111111111111111111111111111_u32, maybe_cast<uint32_t>(0b11111111111111111111111111111111U)); + EXPECT_EQ(-0b10000000000000000000000000000000_n32, maybe_cast<int32_t>(-0b10000000000000000000000000000000)); + EXPECT_EQ(-0b01111111111111111111111111111111_n32, maybe_cast<int32_t>(-0b01111111111111111111111111111111)); + EXPECT_EQ(-0b00000000000000000000000000000001_n32, maybe_cast<int32_t>(-0b00000000000000000000000000000001)); + EXPECT_EQ(+0b00000000000000000000000000000000_p32, maybe_cast<int32_t>(0b00000000000000000000000000000000)); + EXPECT_EQ(+0b00000000000000000000000000000001_p32, maybe_cast<int32_t>(0b00000000000000000000000000000001)); + EXPECT_EQ(+0b01111111111111111111111111111110_p32, maybe_cast<int32_t>(0b01111111111111111111111111111110)); + EXPECT_EQ(+0b01111111111111111111111111111111_p32, maybe_cast<int32_t>(0b01111111111111111111111111111111)); + + EXPECT_EQ(0B00000000000000000000000000000000_u32, maybe_cast<uint32_t>(0B00000000000000000000000000000000U)); + EXPECT_EQ(0B00000000000000000000000000000001_u32, maybe_cast<uint32_t>(0B00000000000000000000000000000001U)); + EXPECT_EQ(0B11111111111111111111111111111110_u32, maybe_cast<uint32_t>(0B11111111111111111111111111111110U)); + EXPECT_EQ(0B11111111111111111111111111111111_u32, maybe_cast<uint32_t>(0B11111111111111111111111111111111U)); + EXPECT_EQ(-0B10000000000000000000000000000000_n32, maybe_cast<int32_t>(-0B10000000000000000000000000000000)); + EXPECT_EQ(-0B01111111111111111111111111111111_n32, maybe_cast<int32_t>(-0B01111111111111111111111111111111)); + EXPECT_EQ(-0B00000000000000000000000000000001_n32, maybe_cast<int32_t>(-0B00000000000000000000000000000001)); + EXPECT_EQ(+0B00000000000000000000000000000000_p32, maybe_cast<int32_t>(0B00000000000000000000000000000000)); + EXPECT_EQ(+0B00000000000000000000000000000001_p32, maybe_cast<int32_t>(0B00000000000000000000000000000001)); + EXPECT_EQ(+0B01111111111111111111111111111110_p32, maybe_cast<int32_t>(0B01111111111111111111111111111110)); + EXPECT_EQ(+0B01111111111111111111111111111111_p32, maybe_cast<int32_t>(0B01111111111111111111111111111111)); + + EXPECT_EQ(000000000000_u32, maybe_cast<uint32_t>(000000000000U)); + EXPECT_EQ(000000000001_u32, maybe_cast<uint32_t>(000000000001U)); + EXPECT_EQ(037777777776_u32, maybe_cast<uint32_t>(037777777776U)); + EXPECT_EQ(037777777777_u32, maybe_cast<uint32_t>(037777777777U)); + EXPECT_EQ(-020000000000_n32, maybe_cast<int32_t>(-020000000000)); + EXPECT_EQ(-017777777777_n32, maybe_cast<int32_t>(-017777777777)); + EXPECT_EQ(-000000000001_n32, maybe_cast<int32_t>(-000000000001)); + EXPECT_EQ(+000000000000_p32, maybe_cast<int32_t>(000000000000)); + EXPECT_EQ(+000000000001_p32, maybe_cast<int32_t>(000000000001)); + EXPECT_EQ(+017777777776_p32, maybe_cast<int32_t>(017777777776)); + EXPECT_EQ(+017777777777_p32, maybe_cast<int32_t>(017777777777)); + + EXPECT_EQ(0_u32, maybe_cast<uint32_t>(0U)); + EXPECT_EQ(1_u32, maybe_cast<uint32_t>(1U)); + EXPECT_EQ(4294967294_u32, maybe_cast<uint32_t>(4294967294U)); + EXPECT_EQ(4294967295_u32, maybe_cast<uint32_t>(4294967295U)); + EXPECT_EQ(-2147483648_n32, maybe_cast<int32_t>(-2147483648)); + EXPECT_EQ(-2147483647_n32, maybe_cast<int32_t>(-2147483647)); + EXPECT_EQ(-1_n32, maybe_cast<int32_t>(-1)); + EXPECT_EQ(+0_p32, maybe_cast<int32_t>(0)); + EXPECT_EQ(+1_p32, maybe_cast<int32_t>(1)); + EXPECT_EQ(+2147483646_p32, maybe_cast<int32_t>(2147483646)); + EXPECT_EQ(+2147483647_p32, maybe_cast<int32_t>(2147483647)); + + EXPECT_EQ(0x00000000_u32, maybe_cast<uint32_t>(0x00000000U)); + EXPECT_EQ(0x00000001_u32, maybe_cast<uint32_t>(0x00000001U)); + EXPECT_EQ(0xfffffffe_u32, maybe_cast<uint32_t>(0xfffffffeU)); + EXPECT_EQ(0xffffffff_u32, maybe_cast<uint32_t>(0xffffffffU)); + EXPECT_EQ(-0x80000000_n32, maybe_cast<int32_t>(-0x80000000)); + EXPECT_EQ(-0x7fffffff_n32, maybe_cast<int32_t>(-0x7fffffff)); + EXPECT_EQ(-0x00000001_n32, maybe_cast<int32_t>(-0x00000001)); + EXPECT_EQ(+0x00000000_p32, maybe_cast<int32_t>(0x00000000)); + EXPECT_EQ(+0x00000001_p32, maybe_cast<int32_t>(0x00000001)); + EXPECT_EQ(+0x7ffffffe_p32, maybe_cast<int32_t>(0x7ffffffe)); + EXPECT_EQ(+0x7fffffff_p32, maybe_cast<int32_t>(0x7fffffff)); + + EXPECT_EQ(0X00000000_u32, maybe_cast<uint32_t>(0X00000000U)); + EXPECT_EQ(0X00000001_u32, maybe_cast<uint32_t>(0X00000001U)); + EXPECT_EQ(0XFFFFFFFE_u32, maybe_cast<uint32_t>(0XFFFFFFFEU)); + EXPECT_EQ(0XFFFFFFFF_u32, maybe_cast<uint32_t>(0XFFFFFFFFU)); + EXPECT_EQ(-0X80000000_n32, maybe_cast<int32_t>(-0X80000000)); + EXPECT_EQ(-0X7FFFFFFF_n32, maybe_cast<int32_t>(-0X7FFFFFFF)); + EXPECT_EQ(-0X00000001_n32, maybe_cast<int32_t>(-0X00000001)); + EXPECT_EQ(+0X00000000_p32, maybe_cast<int32_t>(0X00000000)); + EXPECT_EQ(+0X00000001_p32, maybe_cast<int32_t>(0X00000001)); + EXPECT_EQ(+0X7FFFFFFE_p32, maybe_cast<int32_t>(0X7FFFFFFE)); + EXPECT_EQ(+0X7FFFFFFF_p32, maybe_cast<int32_t>(0X7FFFFFFF)); +} + +TEST(ints, udl64) +{ + EXPECT_EQ(0b0000000000000000000000000000000000000000000000000000000000000000_u64, maybe_cast<uint64_t>(0b0000000000000000000000000000000000000000000000000000000000000000U)); + EXPECT_EQ(0b0000000000000000000000000000000000000000000000000000000000000001_u64, maybe_cast<uint64_t>(0b0000000000000000000000000000000000000000000000000000000000000001U)); + EXPECT_EQ(0b1111111111111111111111111111111111111111111111111111111111111110_u64, maybe_cast<uint64_t>(0b1111111111111111111111111111111111111111111111111111111111111110U)); + EXPECT_EQ(0b1111111111111111111111111111111111111111111111111111111111111111_u64, maybe_cast<uint64_t>(0b1111111111111111111111111111111111111111111111111111111111111111U)); + EXPECT_EQ(-0b1000000000000000000000000000000000000000000000000000000000000000_n64, maybe_cast<int64_t>(-0b1000000000000000000000000000000000000000000000000000000000000000)); + EXPECT_EQ(-0b0111111111111111111111111111111111111111111111111111111111111111_n64, maybe_cast<int64_t>(-0b0111111111111111111111111111111111111111111111111111111111111111)); + EXPECT_EQ(-0b0000000000000000000000000000000000000000000000000000000000000001_n64, maybe_cast<int64_t>(-0b0000000000000000000000000000000000000000000000000000000000000001)); + EXPECT_EQ(+0b0000000000000000000000000000000000000000000000000000000000000000_p64, maybe_cast<int64_t>(0b0000000000000000000000000000000000000000000000000000000000000000)); + EXPECT_EQ(+0b0000000000000000000000000000000000000000000000000000000000000001_p64, maybe_cast<int64_t>(0b0000000000000000000000000000000000000000000000000000000000000001)); + EXPECT_EQ(+0b0111111111111111111111111111111111111111111111111111111111111110_p64, maybe_cast<int64_t>(0b0111111111111111111111111111111111111111111111111111111111111110)); + EXPECT_EQ(+0b0111111111111111111111111111111111111111111111111111111111111111_p64, maybe_cast<int64_t>(0b0111111111111111111111111111111111111111111111111111111111111111)); + + EXPECT_EQ(0B0000000000000000000000000000000000000000000000000000000000000000_u64, maybe_cast<uint64_t>(0B0000000000000000000000000000000000000000000000000000000000000000U)); + EXPECT_EQ(0B0000000000000000000000000000000000000000000000000000000000000001_u64, maybe_cast<uint64_t>(0B0000000000000000000000000000000000000000000000000000000000000001U)); + EXPECT_EQ(0B1111111111111111111111111111111111111111111111111111111111111110_u64, maybe_cast<uint64_t>(0B1111111111111111111111111111111111111111111111111111111111111110U)); + EXPECT_EQ(0B1111111111111111111111111111111111111111111111111111111111111111_u64, maybe_cast<uint64_t>(0B1111111111111111111111111111111111111111111111111111111111111111U)); + EXPECT_EQ(-0B1000000000000000000000000000000000000000000000000000000000000000_n64, maybe_cast<int64_t>(-0B1000000000000000000000000000000000000000000000000000000000000000)); + EXPECT_EQ(-0B0111111111111111111111111111111111111111111111111111111111111111_n64, maybe_cast<int64_t>(-0B0111111111111111111111111111111111111111111111111111111111111111)); + EXPECT_EQ(-0B0000000000000000000000000000000000000000000000000000000000000001_n64, maybe_cast<int64_t>(-0B0000000000000000000000000000000000000000000000000000000000000001)); + EXPECT_EQ(+0B0000000000000000000000000000000000000000000000000000000000000000_p64, maybe_cast<int64_t>(0B0000000000000000000000000000000000000000000000000000000000000000)); + EXPECT_EQ(+0B0000000000000000000000000000000000000000000000000000000000000001_p64, maybe_cast<int64_t>(0B0000000000000000000000000000000000000000000000000000000000000001)); + EXPECT_EQ(+0B0111111111111111111111111111111111111111111111111111111111111110_p64, maybe_cast<int64_t>(0B0111111111111111111111111111111111111111111111111111111111111110)); + EXPECT_EQ(+0B0111111111111111111111111111111111111111111111111111111111111111_p64, maybe_cast<int64_t>(0B0111111111111111111111111111111111111111111111111111111111111111)); + + EXPECT_EQ(00000000000000000000000_u64, maybe_cast<uint64_t>(00000000000000000000000U)); + EXPECT_EQ(00000000000000000000001_u64, maybe_cast<uint64_t>(00000000000000000000001U)); + EXPECT_EQ(01777777777777777777776_u64, maybe_cast<uint64_t>(01777777777777777777776U)); + EXPECT_EQ(01777777777777777777777_u64, maybe_cast<uint64_t>(01777777777777777777777U)); + EXPECT_EQ(-01000000000000000000000_n64, maybe_cast<int64_t>(-01000000000000000000000)); + EXPECT_EQ(-00777777777777777777777_n64, maybe_cast<int64_t>(-00777777777777777777777)); + EXPECT_EQ(-00000000000000000000001_n64, maybe_cast<int64_t>(-000000000000000000000001)); + EXPECT_EQ(+0000000000000000000000_p64, maybe_cast<int64_t>(0000000000000000000000)); + EXPECT_EQ(+0000000000000000000001_p64, maybe_cast<int64_t>(0000000000000000000001)); + EXPECT_EQ(+0777777777777777777776_p64, maybe_cast<int64_t>(0777777777777777777776)); + EXPECT_EQ(+0777777777777777777777_p64, maybe_cast<int64_t>(0777777777777777777777)); + + EXPECT_EQ(0_u64, maybe_cast<uint64_t>(0U)); + EXPECT_EQ(1_u64, maybe_cast<uint64_t>(1U)); + EXPECT_EQ(18446744073709551614_u64, maybe_cast<uint64_t>(18446744073709551614U)); + EXPECT_EQ(18446744073709551615_u64, maybe_cast<uint64_t>(18446744073709551615U)); + EXPECT_EQ(-9223372036854775808_n64, maybe_cast<int64_t>(-9223372036854775808U)); + EXPECT_EQ(-9223372036854775807_n64, maybe_cast<int64_t>(-9223372036854775807)); + EXPECT_EQ(-1_n64, maybe_cast<int64_t>(-1)); + EXPECT_EQ(+0_p64, maybe_cast<int64_t>(0)); + EXPECT_EQ(+1_p64, maybe_cast<int64_t>(1)); + EXPECT_EQ(+9223372036854775806_p64, maybe_cast<int64_t>(9223372036854775806)); + EXPECT_EQ(+9223372036854775807_p64, maybe_cast<int64_t>(9223372036854775807)); + + EXPECT_EQ(0x0000000000000000_u64, maybe_cast<uint64_t>(0x0000000000000000U)); + EXPECT_EQ(0x0000000000000001_u64, maybe_cast<uint64_t>(0x0000000000000001U)); + EXPECT_EQ(0xfffffffffffffffe_u64, maybe_cast<uint64_t>(0xfffffffffffffffeU)); + EXPECT_EQ(0xffffffffffffffff_u64, maybe_cast<uint64_t>(0xffffffffffffffffU)); + EXPECT_EQ(-0x8000000000000000_n64, maybe_cast<int64_t>(-0x8000000000000000)); + EXPECT_EQ(-0x7fffffffffffffff_n64, maybe_cast<int64_t>(-0x7fffffffffffffff)); + EXPECT_EQ(-0x0000000000000001_n64, maybe_cast<int64_t>(-0x0000000000000001)); + EXPECT_EQ(+0x0000000000000000_p64, maybe_cast<int64_t>(0x0000000000000000)); + EXPECT_EQ(+0x0000000000000001_p64, maybe_cast<int64_t>(0x0000000000000001)); + EXPECT_EQ(+0x7ffffffffffffffe_p64, maybe_cast<int64_t>(0x7ffffffffffffffe)); + EXPECT_EQ(+0x7fffffffffffffff_p64, maybe_cast<int64_t>(0x7fffffffffffffff)); + + EXPECT_EQ(0X0000000000000000_u64, maybe_cast<uint64_t>(0X0000000000000000U)); + EXPECT_EQ(0X0000000000000001_u64, maybe_cast<uint64_t>(0X0000000000000001U)); + EXPECT_EQ(0XFFFFFFFFFFFFFFFE_u64, maybe_cast<uint64_t>(0XFFFFFFFFFFFFFFFEU)); + EXPECT_EQ(0XFFFFFFFFFFFFFFFF_u64, maybe_cast<uint64_t>(0XFFFFFFFFFFFFFFFFU)); + EXPECT_EQ(-0X8000000000000000_n64, maybe_cast<int64_t>(-0X8000000000000000)); + EXPECT_EQ(-0X7FFFFFFFFFFFFFFF_n64, maybe_cast<int64_t>(-0X7FFFFFFFFFFFFFFF)); + EXPECT_EQ(-0X0000000000000001_n64, maybe_cast<int64_t>(-0X0000000000000001)); + EXPECT_EQ(+0X0000000000000000_p64, maybe_cast<int64_t>(0X0000000000000000)); + EXPECT_EQ(+0X0000000000000001_p64, maybe_cast<int64_t>(0X0000000000000001)); + EXPECT_EQ(+0X7FFFFFFFFFFFFFFE_p64, maybe_cast<int64_t>(0X7FFFFFFFFFFFFFFE)); + EXPECT_EQ(+0X7FFFFFFFFFFFFFFF_p64, maybe_cast<int64_t>(0X7FFFFFFFFFFFFFFF)); +} +} // namespace tmwa diff --git a/src/ints/wrap.cpp b/src/ints/wrap.cpp new file mode 100644 index 0000000..84d4b33 --- /dev/null +++ b/src/ints/wrap.cpp @@ -0,0 +1,26 @@ +#include "wrap.hpp" +// wrap.cpp - basic integer wrapper classes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/ints/wrap.hpp b/src/ints/wrap.hpp new file mode 100644 index 0000000..707c787 --- /dev/null +++ b/src/ints/wrap.hpp @@ -0,0 +1,110 @@ +#pragma once +// wrap.hpp - basic integer wrapper classes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include <cstdint> + +#include <type_traits> + + +namespace tmwa +{ +namespace ints +{ + namespace wrapped + { + template<class R> + struct Wrapped + { + typedef R wrapped_type; + R _value; + protected: + constexpr + Wrapped(uint32_t v=0) + : _value(v) + {} + public: + explicit + operator bool () const { return _value; } + bool operator !() const { return !_value; } + }; + + template<class W, typename=typename W::wrapped_type> + bool operator == (W l, W r) + { + return l._value == r._value; + } + template<class W, typename=typename W::wrapped_type> + bool operator != (W l, W r) + { + return l._value != r._value; + } + template<class W, typename=typename W::wrapped_type> + bool operator < (W l, W r) + { + return l._value < r._value; + } + + template<class T> + constexpr + typename T::wrapped_type unwrap(typename std::enable_if<true, T>::type w) + { + return w._value; + } + template<class T> + constexpr + T wrap(typename T::wrapped_type v) + { + struct Sub : T + { + constexpr + Sub(typename T::wrapped_type v2) + : T(v2) + {} + }; + return Sub(v); + } + + template<class W> + constexpr + W next(W w) + { + return wrap<W>(unwrap<W>(w) + 1); + } + template<class W> + constexpr + W prev(W w) + { + return wrap<W>(unwrap<W>(w) - 1); + } + + template<class R> + R convert_for_printf(Wrapped<R> w) + { + return w._value; + } + } // namespace wrapped +} // namespace ints + +using ints::wrapped::Wrapped; +using ints::wrapped::unwrap; +using ints::wrapped::wrap; +} // namespace tmwa diff --git a/src/io/cxxstdio.cpp b/src/io/cxxstdio.cpp index fbfdd46..ca4e880 100644 --- a/src/io/cxxstdio.cpp +++ b/src/io/cxxstdio.cpp @@ -1,5 +1,5 @@ #include "cxxstdio.hpp" -// cxxstdio.cpp - pass C++ types through scanf/printf +// cxxstdio.cpp - pass C++ types through printf // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> // @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/io/cxxstdio.hpp b/src/io/cxxstdio.hpp index 66419df..20d3a33 100644 --- a/src/io/cxxstdio.hpp +++ b/src/io/cxxstdio.hpp @@ -1,6 +1,5 @@ -#ifndef TMWA_IO_CXXSTDIO_HPP -#define TMWA_IO_CXXSTDIO_HPP -// cxxstdio.hpp - pass C++ types through scanf/printf +#pragma once +// cxxstdio.hpp - pass C++ types through printf // // Copyright © 2011-2013 Ben Longbons <b.r.longbons@gmail.com> // @@ -19,44 +18,29 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdarg> -# include <cstdio> +#include <cstdarg> +#include <cstdio> -# include "../compat/cast.hpp" +#include "../compat/cast.hpp" -# include "../generic/enum.hpp" +#include "../generic/enum.hpp" -# include "fwd.hpp" +#include "../diagnostics.hpp" +namespace tmwa +{ namespace cxxstdio { - // other implementations of do_vprint or do_vscan are injected by ADL. + // other implementations of do_vprint are injected by ADL. inline __attribute__((format(printf, 2, 0))) int do_vprint(FILE *out, const char *fmt, va_list ap) { return vfprintf(out, fmt, ap); } - inline __attribute__((format(scanf, 2, 0))) - int do_vscan(FILE *in, const char *fmt, va_list ap) - { - return vfscanf(in, fmt, ap); - } - -# if 0 - inline __attribute__((format(scanf, 2, 0))) - int do_vscan(const char *in, const char *fmt, va_list ap) - { - return vsscanf(in, fmt, ap); - } -# else - inline - int do_vscan(const char *, const char *, va_list) = delete; -# endif - template<class T> inline __attribute__((format(printf, 2, 3))) int do_print(T&& t, const char *fmt, ...) @@ -69,19 +53,6 @@ namespace cxxstdio return rv; } - template<class T> - inline __attribute__((format(scanf, 2, 3))) - int do_scan(T&& t, const char *fmt, ...) - { - int rv; - va_list ap; - va_start(ap, fmt); - rv = do_vscan(std::forward<T>(t), fmt, ap); - va_end(ap); - return rv; - } - - template<class T, typename=typename std::enable_if<!std::is_class<T>::value>::type> typename remove_enum<T>::type decay_for_printf(T v) { @@ -95,13 +66,10 @@ namespace cxxstdio return std::forward<T>(v); } - template<class T, typename = typename std::enable_if<!std::is_enum<T>::value>::type> - T& convert_for_scanf(T& v) - { - return v; - } + inline + const char *convert_for_printf(const char *) = delete; -# if 0 +#if 0 template<class E> constexpr E get_enum_min_value(decltype(E::min_value)) @@ -127,7 +95,7 @@ namespace cxxstdio { return def; } -# else +#else template<class E> constexpr E get_enum_min_value(E) @@ -140,24 +108,24 @@ namespace cxxstdio { return E::max_value; } -# endif +#endif template<class E> class EnumConverter { E& out; typedef typename underlying_type<E>::type U; -# if 0 +#if 0 constexpr static U min_value = U(get_enum_min_value<E>(E(std::numeric_limits<U>::min()))); constexpr static U max_value = U(get_enum_max_value<E>(E(std::numeric_limits<U>::max()))); -# else +#else constexpr static U min_value = U(get_enum_min_value(E())); constexpr static U max_value = U(get_enum_max_value(E())); -# endif +#endif U mid; public: EnumConverter(E& e) @@ -165,11 +133,13 @@ namespace cxxstdio {} ~EnumConverter() { -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wtype-limits" + DIAG_PUSH(); + DIAG_I(type_limits); if (min_value <= mid && mid <= max_value) -# pragma GCC diagnostic pop + { + DIAG_POP(); out = E(mid); + } } U *operator &() { @@ -177,12 +147,6 @@ namespace cxxstdio } }; - template<class T, typename = typename std::enable_if<std::is_enum<T>::value>::type> - EnumConverter<T> convert_for_scanf(T& v) - { - return v; - } - template<class Format> class PrintFormatter { @@ -192,63 +156,35 @@ namespace cxxstdio int print(T&& t, A&&... a) { constexpr static - const char *print_format = Format::print_format(); + const char *print_format = Format::print_format().format_string(); return do_print(std::forward<T>(t), print_format, decay_for_printf(convert_for_printf(std::forward<A>(a)))...); } }; - template<class Format> - class ScanFormatter - { - public: - template<class T, class... A> - static - int scan(T&& t, A&&... a) - { - constexpr static - const char *scan_format = Format::scan_format(); - return do_scan(std::forward<T>(t), scan_format, - &convert_for_scanf(*a)...); - } - }; - -# define XPRINTF(out, fmt, ...) \ +#define XPRINTF(out, fmt, ...) \ ({ \ struct format_impl \ { \ constexpr static \ - const char *print_format() { return fmt; } \ + FormatString print_format() { return fmt; } \ }; \ cxxstdio::PrintFormatter<format_impl>::print(out, ## __VA_ARGS__); \ }) -# define XSCANF(out, fmt, ...) \ - ({ \ - struct format_impl \ - { \ - constexpr static \ - const char *scan_format() { return fmt; } \ - }; \ - cxxstdio::ScanFormatter<format_impl>::scan(out, ## __VA_ARGS__); \ - }) - -# define FPRINTF(file, fmt, ...) XPRINTF(/*no_cast<FILE *>*/(file), fmt, ## __VA_ARGS__) -# define FSCANF(file, fmt, ...) XSCANF(no_cast<FILE *>(file), fmt, ## __VA_ARGS__) -# define PRINTF(fmt, ...) FPRINTF(stdout, fmt, ## __VA_ARGS__) -# define SPRINTF(str, fmt, ...) XPRINTF(base_cast<AString&>(str), fmt, ## __VA_ARGS__) -# define SNPRINTF(str, n, fmt, ...) XPRINTF(base_cast<VString<n-1>&>(str), fmt, ## __VA_ARGS__) -# define SCANF(fmt, ...) FSCANF(stdin, fmt, ## __VA_ARGS__) -# define SSCANF(str, fmt, ...) XSCANF(maybe_cast<ZString>(str), fmt, ## __VA_ARGS__) +#define FPRINTF(file, fmt, ...) XPRINTF(/*no_cast<FILE *>*/(file), fmt, ## __VA_ARGS__) +#define PRINTF(fmt, ...) FPRINTF(stdout, fmt, ## __VA_ARGS__) +#define SPRINTF(str, fmt, ...) XPRINTF(base_cast<AString&>(str), fmt, ## __VA_ARGS__) +#define SNPRINTF(str, n, fmt, ...) XPRINTF(base_cast<VString<n-1>&>(str), fmt, ## __VA_ARGS__) -# define STRPRINTF(fmt, ...) \ +#define STRPRINTF(fmt, ...) \ ({ \ AString _out_impl; \ SPRINTF(_out_impl, fmt, ## __VA_ARGS__); \ _out_impl; \ }) -# define STRNPRINTF(n, fmt, ...) \ +#define STRNPRINTF(n, fmt, ...) \ ({ \ VString<n - 1> _out_impl; \ SNPRINTF(_out_impl, n, fmt, ## __VA_ARGS__); \ @@ -256,5 +192,4 @@ namespace cxxstdio }) } // namespace cxxstdio - -#endif // TMWA_IO_CXXSTDIO_HPP +} // namespace tmwa diff --git a/src/io/dir.cpp b/src/io/dir.cpp new file mode 100644 index 0000000..2acb75a --- /dev/null +++ b/src/io/dir.cpp @@ -0,0 +1,54 @@ +#include "dir.hpp" +// io/dir.cpp - rooted file operations +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <fcntl.h> + +#include "../strings/zstring.hpp" + +#include "../poison.hpp" + + +namespace tmwa +{ +namespace io +{ + DirFd::DirFd() + : dirfd(FD::cast_dammit(AT_FDCWD)) + {} + + DirFd::DirFd(ZString path) + : dirfd(FD::open(path, O_DIRECTORY | O_RDONLY, 0)) + {} + + DirFd::DirFd(const DirFd& root, ZString path) + : dirfd(FD::openat(root.dirfd, path, O_DIRECTORY | O_RDONLY, 0)) + {} + + DirFd::~DirFd() + { + dirfd.close(); + } + + FD DirFd::open_fd(ZString name, int flags, int mode) const + { + return FD::openat(dirfd, name, flags, mode); + } +} // namespace io +} // namespace tmwa diff --git a/src/io/dir.hpp b/src/io/dir.hpp new file mode 100644 index 0000000..071f309 --- /dev/null +++ b/src/io/dir.hpp @@ -0,0 +1,50 @@ +#pragma once +// io/dir.hpp - rooted file operations +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include "../strings/fwd.hpp" + +#include "fd.hpp" + + +namespace tmwa +{ +namespace io +{ + class DirFd + { + private: + FD dirfd; + + public: + DirFd(); + explicit + DirFd(ZString); + DirFd(const DirFd&, ZString); + + DirFd(const DirFd&) = delete; + ~DirFd(); + DirFd& operator = (const DirFd&) = delete; + + FD open_fd(ZString name, int flags, int mode=FD::DEFAULT_MODE) const; + }; +} // namespace io +} // namespace tmwa diff --git a/src/io/fd.cpp b/src/io/fd.cpp index 4fc33e9..c0b44e8 100644 --- a/src/io/fd.cpp +++ b/src/io/fd.cpp @@ -25,12 +25,19 @@ #include "../poison.hpp" + +namespace tmwa +{ namespace io { FD FD::open(ZString path, int flags, int mode) { return FD(::open(path.c_str(), flags, mode)); } + FD FD::openat(FD dirfd, ZString path, int flags, int mode) + { + return FD(::openat(dirfd.fd, path.c_str(), flags, mode)); + } FD FD::socket(int domain, int type, int protocol) { return FD(::socket(domain, type, protocol)); @@ -163,3 +170,4 @@ namespace io timeout, sigmask); } } // namespace io +} // namespace tmwa diff --git a/src/io/fd.hpp b/src/io/fd.hpp index 7afb40f..d04d5bf 100644 --- a/src/io/fd.hpp +++ b/src/io/fd.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_IO_FD_HPP -#define TMWA_IO_FD_HPP +#pragma once // io/fd.hpp - typesafe (but not scopesafe) file descriptors // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,16 +18,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <sys/select.h> -# include <sys/socket.h> +#include <sys/select.h> +#include <sys/socket.h> -# include <unistd.h> +#include "../strings/fwd.hpp" -# include "../strings/fwd.hpp" +#include "../diagnostics.hpp" +namespace tmwa +{ namespace io { class FD @@ -55,8 +56,13 @@ namespace io FD stdout() { return FD(1); } static FD stderr() { return FD(2); } + + static const int DEFAULT_MODE = 0666; + static - FD open(ZString path, int flags, int mode=0666); + FD open(ZString path, int flags, int mode=DEFAULT_MODE); + static + FD openat(FD dirfd, ZString path, int flags, int mode=DEFAULT_MODE); static FD socket(int domain, int type, int protocol); FD accept(struct sockaddr *addr, socklen_t *addrlen); @@ -64,6 +70,7 @@ namespace io int pipe(FD& r, FD& w); static int pipe2(FD& r, FD& w, int flags); + static FD sysconf_SC_OPEN_MAX(); @@ -138,24 +145,24 @@ namespace io } void clr(FD fd) { -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wold-style-cast" + DIAG_PUSH(); + DIAG_I(old_style_cast); FD_CLR(fd.uncast_dammit(), &fds); -# pragma GCC diagnostic pop + DIAG_POP(); } bool isset(FD fd) { -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wold-style-cast" + DIAG_PUSH(); + DIAG_I(old_style_cast); return FD_ISSET(fd.uncast_dammit(), &fds); -# pragma GCC diagnostic pop + DIAG_POP(); } void set(FD fd) { -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wold-style-cast" + DIAG_PUSH(); + DIAG_I(old_style_cast); FD_SET(fd.uncast_dammit(), &fds); -# pragma GCC diagnostic pop + DIAG_POP(); } static @@ -164,5 +171,4 @@ namespace io int pselect(int nfds, FD_Set *readfds, FD_Set *writefds, FD_Set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask); }; } // namespace io - -#endif // TMWA_IO_FD_HPP +} // namespace tmwa diff --git a/src/io/fwd.hpp b/src/io/fwd.hpp index 1e5fa82..deeb08c 100644 --- a/src/io/fwd.hpp +++ b/src/io/fwd.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_IO_FWD_HPP -#define TMWA_IO_FWD_HPP +#pragma once // io/fwd.hpp - Forward declarations of I/O classes // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,14 +18,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "../sanity.hpp" +namespace tmwa +{ namespace io { class ReadFile; class WriteFile; class AppendFile; } // namespace io - -#endif // TMWA_IO_FWD_HPP +} // namespace tmwa diff --git a/src/io/line.cpp b/src/io/line.cpp index f7470a6..a1cdf42 100644 --- a/src/io/line.cpp +++ b/src/io/line.cpp @@ -1,5 +1,5 @@ #include "line.hpp" -// io/line.hpp - Input from files, line-by-line +// io/line.cpp - Input from files, line-by-line // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> // @@ -18,44 +18,44 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <fcntl.h> -#include <unistd.h> - #include "../strings/astring.hpp" #include "../strings/mstring.hpp" #include "../strings/zstring.hpp" +#include "../strings/xstring.hpp" #include "cxxstdio.hpp" #include "../poison.hpp" +namespace tmwa +{ namespace io { AString Line::message_str(ZString cat, ZString msg) const { MString out; if (column) - out += STRPRINTF("%s:%u:%u: %s: %s\n", + out += STRPRINTF("%s:%u:%u: %s: %s\n"_fmt, filename, line, column, cat, msg); else - out += STRPRINTF("%s:%u: %s: %s\n", + out += STRPRINTF("%s:%u: %s: %s\n"_fmt, filename, line, cat, msg); - out += STRPRINTF("%s\n", text); - out += STRPRINTF("%*c\n", column, '^'); + out += STRPRINTF("%s\n"_fmt, text); + out += STRPRINTF("%*c\n"_fmt, column, '^'); return AString(out); } void Line::message(ZString cat, ZString msg) const { if (column) - FPRINTF(stderr, "%s:%u:%u: %s: %s\n", + FPRINTF(stderr, "%s:%u:%u: %s: %s\n"_fmt, filename, line, column, cat, msg); else - FPRINTF(stderr, "%s:%u: %s: %s\n", + FPRINTF(stderr, "%s:%u: %s: %s\n"_fmt, filename, line, cat, msg); - FPRINTF(stderr, "%s\n", text); - FPRINTF(stderr, "%*c\n", column, '^'); + FPRINTF(stderr, "%s\n"_fmt, text); + FPRINTF(stderr, "%*c\n"_fmt, column, '^'); } AString LineSpan::message_str(ZString cat, ZString msg) const @@ -67,24 +67,24 @@ namespace io MString out; if (begin.line == end.line) { - out += STRPRINTF("%s:%u:%u: %s: %s\n", + out += STRPRINTF("%s:%u:%u: %s: %s\n"_fmt, begin.filename, begin.line, begin.column, cat, msg); - out += STRPRINTF("%s\n", begin.text); - out += STRPRINTF("%*c", begin.column, '^'); + out += STRPRINTF("%s\n"_fmt, begin.text); + out += STRPRINTF("%*c"_fmt, begin.column, '^'); for (unsigned c = begin.column; c != end.column; ++c) out += '~'; out += '\n'; } else { - out += STRPRINTF("%s:%u:%u: %s: %s\n", + out += STRPRINTF("%s:%u:%u: %s: %s\n"_fmt, begin.filename, begin.line, begin.column, cat, msg); - out += STRPRINTF("%s\n", begin.text); - out += STRPRINTF("%*c", begin.column, '^'); + out += STRPRINTF("%s\n"_fmt, begin.text); + out += STRPRINTF("%*c"_fmt, begin.column, '^'); for (unsigned c = begin.column; c != begin.text.size(); ++c) out += '~'; - out += " ...\n"; - out += STRPRINTF("%s\n", end.text); + out += " ...\n"_s; + out += STRPRINTF("%s\n"_fmt, end.text); for (unsigned c = 0; c != end.column; ++c) out += '~'; out += '\n'; @@ -94,7 +94,7 @@ namespace io void LineSpan::message(ZString cat, ZString msg) const { - FPRINTF(stderr, "%s", message_str(cat, msg)); + FPRINTF(stderr, "%s"_fmt, message_str(cat, msg)); } LineReader::LineReader(ZString name) @@ -180,3 +180,4 @@ namespace io return line != 0; } } // namespace io +} // namespace tmwa diff --git a/src/io/line.hpp b/src/io/line.hpp index a9e8944..8244c5e 100644 --- a/src/io/line.hpp +++ b/src/io/line.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_IO_LINE_HPP -#define TMWA_IO_LINE_HPP +#pragma once // io/line.hpp - Input from files, line-by-line // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,16 +18,17 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/rstring.hpp" -# include "../strings/astring.hpp" -# include "../strings/zstring.hpp" +#include "../strings/rstring.hpp" +#include "../strings/zstring.hpp" +#include "../strings/literal.hpp" -# include "fd.hpp" -# include "read.hpp" +#include "read.hpp" +namespace tmwa +{ namespace io { // TODO split this out @@ -42,9 +42,9 @@ namespace io AString message_str(ZString cat, ZString msg) const; void message(ZString cat, ZString msg) const; - void note(ZString msg) const { message("note", msg); } - void warning(ZString msg) const { message("warning", msg); } - void error(ZString msg) const { message("error", msg); } + void note(ZString msg) const { message("note"_s, msg); } + void warning(ZString msg) const { message("warning"_s, msg); } + void error(ZString msg) const { message("error"_s, msg); } }; // psst, don't tell anyone @@ -65,9 +65,9 @@ namespace io AString message_str(ZString cat, ZString msg) const; void message(ZString cat, ZString msg) const; - void note(ZString msg) const { message("note", msg); } - void warning(ZString msg) const { message("warning", msg); } - void error(ZString msg) const { message("error", msg); } + void note(ZString msg) const { message("note"_s, msg); } + void warning(ZString msg) const { message("warning"_s, msg); } + void error(ZString msg) const { message("error"_s, msg); } }; class LineReader @@ -104,5 +104,4 @@ namespace io bool is_open(); }; } // namespace io - -#endif // TMWA_IO_LINE_HPP +} // namespace tmwa diff --git a/src/io/line_test.cpp b/src/io/line_test.cpp index feee1fb..edf60bd 100644 --- a/src/io/line_test.cpp +++ b/src/io/line_test.cpp @@ -20,10 +20,14 @@ #include <gtest/gtest.h> +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../poison.hpp" + +namespace tmwa +{ static io::FD string_pipe(ZString sz) { @@ -42,80 +46,80 @@ io::FD string_pipe(ZString sz) TEST(io, line1) { - io::LineReader lr("<string1>", string_pipe("Hello World\n")); + io::LineReader lr("<string1>"_s, string_pipe("Hello World\n"_s)); io::Line hi; EXPECT_TRUE(lr.read_line(hi)); - EXPECT_EQ(hi.text, "Hello World"); - EXPECT_EQ(hi.filename, "<string1>"); + EXPECT_EQ(hi.text, "Hello World"_s); + EXPECT_EQ(hi.filename, "<string1>"_s); EXPECT_EQ(hi.line, 1); EXPECT_EQ(hi.column, 0); EXPECT_FALSE(lr.read_line(hi)); } TEST(io, line2) { - io::LineReader lr("<string2>", string_pipe("Hello\nWorld")); + io::LineReader lr("<string2>"_s, string_pipe("Hello\nWorld"_s)); io::Line hi; EXPECT_TRUE(lr.read_line(hi)); - EXPECT_EQ(hi.text, "Hello"); - EXPECT_EQ(hi.filename, "<string2>"); + EXPECT_EQ(hi.text, "Hello"_s); + EXPECT_EQ(hi.filename, "<string2>"_s); EXPECT_EQ(hi.line, 1); EXPECT_EQ(hi.column, 0); EXPECT_TRUE(lr.read_line(hi)); - EXPECT_EQ(hi.text, "World"); - EXPECT_EQ(hi.filename, "<string2>"); + EXPECT_EQ(hi.text, "World"_s); + EXPECT_EQ(hi.filename, "<string2>"_s); EXPECT_EQ(hi.line, 2); EXPECT_EQ(hi.column, 0); EXPECT_FALSE(lr.read_line(hi)); } TEST(io, line3) { - io::LineReader lr("<string3>", string_pipe("Hello\rWorld")); + io::LineReader lr("<string3>"_s, string_pipe("Hello\rWorld"_s)); io::Line hi; EXPECT_TRUE(lr.read_line(hi)); - EXPECT_EQ(hi.text, "Hello"); - EXPECT_EQ(hi.filename, "<string3>"); + EXPECT_EQ(hi.text, "Hello"_s); + EXPECT_EQ(hi.filename, "<string3>"_s); EXPECT_EQ(hi.line, 1); EXPECT_EQ(hi.column, 0); EXPECT_TRUE(lr.read_line(hi)); - EXPECT_EQ(hi.text, "World"); - EXPECT_EQ(hi.filename, "<string3>"); + EXPECT_EQ(hi.text, "World"_s); + EXPECT_EQ(hi.filename, "<string3>"_s); EXPECT_EQ(hi.line, 2); EXPECT_EQ(hi.column, 0); EXPECT_FALSE(lr.read_line(hi)); } TEST(io, line4) { - io::LineReader lr("<string4>", string_pipe("Hello\r\nWorld")); + io::LineReader lr("<string4>"_s, string_pipe("Hello\r\nWorld"_s)); io::Line hi; EXPECT_TRUE(lr.read_line(hi)); - EXPECT_EQ(hi.text, "Hello"); - EXPECT_EQ(hi.filename, "<string4>"); + EXPECT_EQ(hi.text, "Hello"_s); + EXPECT_EQ(hi.filename, "<string4>"_s); EXPECT_EQ(hi.line, 1); EXPECT_EQ(hi.column, 0); EXPECT_TRUE(lr.read_line(hi)); - EXPECT_EQ(hi.text, "World"); - EXPECT_EQ(hi.filename, "<string4>"); + EXPECT_EQ(hi.text, "World"_s); + EXPECT_EQ(hi.filename, "<string4>"_s); EXPECT_EQ(hi.line, 2); EXPECT_EQ(hi.column, 0); EXPECT_FALSE(lr.read_line(hi)); } TEST(io, line5) { - io::LineReader lr("<string5>", string_pipe("Hello\n\rWorld")); + io::LineReader lr("<string5>"_s, string_pipe("Hello\n\rWorld"_s)); io::Line hi; EXPECT_TRUE(lr.read_line(hi)); - EXPECT_EQ(hi.text, "Hello"); - EXPECT_EQ(hi.filename, "<string5>"); + EXPECT_EQ(hi.text, "Hello"_s); + EXPECT_EQ(hi.filename, "<string5>"_s); EXPECT_EQ(hi.line, 1); EXPECT_EQ(hi.column, 0); EXPECT_TRUE(lr.read_line(hi)); - EXPECT_EQ(hi.text, ""); - EXPECT_EQ(hi.filename, "<string5>"); + EXPECT_EQ(hi.text, ""_s); + EXPECT_EQ(hi.filename, "<string5>"_s); EXPECT_EQ(hi.line, 2); EXPECT_EQ(hi.column, 0); EXPECT_TRUE(lr.read_line(hi)); - EXPECT_EQ(hi.text, "World"); - EXPECT_EQ(hi.filename, "<string5>"); + EXPECT_EQ(hi.text, "World"_s); + EXPECT_EQ(hi.filename, "<string5>"_s); EXPECT_EQ(hi.line, 3); EXPECT_EQ(hi.column, 0); EXPECT_FALSE(lr.read_line(hi)); @@ -123,47 +127,47 @@ TEST(io, line5) TEST(io, linechar1) { - io::LineCharReader lr("<stringchar1>", string_pipe("Hi Wu\n")); + io::LineCharReader lr("<stringchar1>"_s, string_pipe("Hi Wu\n"_s)); io::LineChar c; EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'H'); - EXPECT_EQ(c.text, "Hi Wu"); - EXPECT_EQ(c.filename, "<stringchar1>"); + EXPECT_EQ(c.text, "Hi Wu"_s); + EXPECT_EQ(c.filename, "<stringchar1>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 1); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'i'); - EXPECT_EQ(c.text, "Hi Wu"); - EXPECT_EQ(c.filename, "<stringchar1>"); + EXPECT_EQ(c.text, "Hi Wu"_s); + EXPECT_EQ(c.filename, "<stringchar1>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 2); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), ' '); - EXPECT_EQ(c.text, "Hi Wu"); - EXPECT_EQ(c.filename, "<stringchar1>"); + EXPECT_EQ(c.text, "Hi Wu"_s); + EXPECT_EQ(c.filename, "<stringchar1>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 3); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'W'); - EXPECT_EQ(c.text, "Hi Wu"); - EXPECT_EQ(c.filename, "<stringchar1>"); + EXPECT_EQ(c.text, "Hi Wu"_s); + EXPECT_EQ(c.filename, "<stringchar1>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 4); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'u'); - EXPECT_EQ(c.text, "Hi Wu"); - EXPECT_EQ(c.filename, "<stringchar1>"); + EXPECT_EQ(c.text, "Hi Wu"_s); + EXPECT_EQ(c.filename, "<stringchar1>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 5); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), '\n'); - EXPECT_EQ(c.text, "Hi Wu"); - EXPECT_EQ(c.filename, "<stringchar1>"); + EXPECT_EQ(c.text, "Hi Wu"_s); + EXPECT_EQ(c.filename, "<stringchar1>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 6); lr.adv(); @@ -171,47 +175,47 @@ TEST(io, linechar1) } TEST(io, linechar2) { - io::LineCharReader lr("<stringchar2>", string_pipe("Hi\nWu")); + io::LineCharReader lr("<stringchar2>"_s, string_pipe("Hi\nWu"_s)); io::LineChar c; EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'H'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar2>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar2>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 1); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'i'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar2>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar2>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 2); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), '\n'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar2>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar2>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 3); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'W'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar2>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar2>"_s); EXPECT_EQ(c.line, 2); EXPECT_EQ(c.column, 1); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'u'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar2>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar2>"_s); EXPECT_EQ(c.line, 2); EXPECT_EQ(c.column, 2); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), '\n'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar2>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar2>"_s); EXPECT_EQ(c.line, 2); EXPECT_EQ(c.column, 3); lr.adv(); @@ -219,47 +223,47 @@ TEST(io, linechar2) } TEST(io, linechar3) { - io::LineCharReader lr("<stringchar3>", string_pipe("Hi\rWu")); + io::LineCharReader lr("<stringchar3>"_s, string_pipe("Hi\rWu"_s)); io::LineChar c; EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'H'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar3>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar3>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 1); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'i'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar3>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar3>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 2); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), '\n'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar3>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar3>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 3); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'W'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar3>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar3>"_s); EXPECT_EQ(c.line, 2); EXPECT_EQ(c.column, 1); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'u'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar3>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar3>"_s); EXPECT_EQ(c.line, 2); EXPECT_EQ(c.column, 2); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), '\n'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar3>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar3>"_s); EXPECT_EQ(c.line, 2); EXPECT_EQ(c.column, 3); lr.adv(); @@ -267,47 +271,47 @@ TEST(io, linechar3) } TEST(io, linechar4) { - io::LineCharReader lr("<stringchar4>", string_pipe("Hi\r\nWu")); + io::LineCharReader lr("<stringchar4>"_s, string_pipe("Hi\r\nWu"_s)); io::LineChar c; EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'H'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar4>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar4>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 1); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'i'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar4>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar4>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 2); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), '\n'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar4>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar4>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 3); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'W'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar4>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar4>"_s); EXPECT_EQ(c.line, 2); EXPECT_EQ(c.column, 1); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'u'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar4>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar4>"_s); EXPECT_EQ(c.line, 2); EXPECT_EQ(c.column, 2); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), '\n'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar4>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar4>"_s); EXPECT_EQ(c.line, 2); EXPECT_EQ(c.column, 3); lr.adv(); @@ -315,54 +319,54 @@ TEST(io, linechar4) } TEST(io, linechar5) { - io::LineCharReader lr("<stringchar5>", string_pipe("Hi\n\rWu")); + io::LineCharReader lr("<stringchar5>"_s, string_pipe("Hi\n\rWu"_s)); io::LineChar c; EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'H'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar5>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar5>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 1); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'i'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar5>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar5>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 2); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), '\n'); - EXPECT_EQ(c.text, "Hi"); - EXPECT_EQ(c.filename, "<stringchar5>"); + EXPECT_EQ(c.text, "Hi"_s); + EXPECT_EQ(c.filename, "<stringchar5>"_s); EXPECT_EQ(c.line, 1); EXPECT_EQ(c.column, 3); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), '\n'); - EXPECT_EQ(c.text, ""); - EXPECT_EQ(c.filename, "<stringchar5>"); + EXPECT_EQ(c.text, ""_s); + EXPECT_EQ(c.filename, "<stringchar5>"_s); EXPECT_EQ(c.line, 2); EXPECT_EQ(c.column, 1); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'W'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar5>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar5>"_s); EXPECT_EQ(c.line, 3); EXPECT_EQ(c.column, 1); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), 'u'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar5>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar5>"_s); EXPECT_EQ(c.line, 3); EXPECT_EQ(c.column, 2); lr.adv(); EXPECT_TRUE(lr.get(c)); EXPECT_EQ(c.ch(), '\n'); - EXPECT_EQ(c.text, "Wu"); - EXPECT_EQ(c.filename, "<stringchar5>"); + EXPECT_EQ(c.text, "Wu"_s); + EXPECT_EQ(c.filename, "<stringchar5>"_s); EXPECT_EQ(c.line, 3); EXPECT_EQ(c.column, 3); lr.adv(); @@ -371,7 +375,7 @@ TEST(io, linechar5) TEST(io, linespan) { - io::LineCharReader lr("<span>", string_pipe("Hello,\nWorld!\n")); + io::LineCharReader lr("<span>"_s, string_pipe("Hello,\nWorld!\n"_s)); io::LineSpan span; do { @@ -385,10 +389,10 @@ TEST(io, linespan) lr.adv(); } while (span.end.ch() != 'o'); - EXPECT_EQ(span.message_str("info", "meh"), + EXPECT_EQ(span.message_str("info"_s, "meh"_s), "<span>:1:2: info: meh\n" "Hello,\n" - " ^~~~\n" + " ^~~~\n"_s ); span.begin = span.end; do @@ -398,21 +402,22 @@ TEST(io, linespan) } while (span.end.ch() != 'r'); - EXPECT_EQ(span.begin.message_str("note", "foo"), + EXPECT_EQ(span.begin.message_str("note"_s, "foo"_s), "<span>:1:5: note: foo\n" "Hello,\n" - " ^\n" + " ^\n"_s ); - EXPECT_EQ(span.end.message_str("warning", "bar"), + EXPECT_EQ(span.end.message_str("warning"_s, "bar"_s), "<span>:2:3: warning: bar\n" "World!\n" - " ^\n" + " ^\n"_s ); - EXPECT_EQ(span.message_str("error", "qux"), + EXPECT_EQ(span.message_str("error"_s, "qux"_s), "<span>:1:5: error: qux\n" "Hello,\n" " ^~ ...\n" "World!\n" - "~~~\n" + "~~~\n"_s ); } +} // namespace tmwa diff --git a/src/io/lock.cpp b/src/io/lock.cpp index 96c3649..911b5db 100644 --- a/src/io/lock.cpp +++ b/src/io/lock.cpp @@ -1,5 +1,5 @@ #include "lock.hpp" -// io/lock.hpp - Output to files with atomic replacement and backups. +// io/lock.cpp - Output to files with atomic replacement and backups. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> // @@ -21,7 +21,13 @@ #include <fcntl.h> #include <unistd.h> +#include <cerrno> +#include <cstdio> +#include <cstdlib> + +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" +#include "../strings/literal.hpp" #include "cxxstdio.hpp" #include "fd.hpp" @@ -29,9 +35,11 @@ #include "../poison.hpp" +namespace tmwa +{ /// number of backups to keep static -const int backup_count = 10; +const int backup_count = 9; /// Protected file writing /// (Until the file is closed, it keeps the old file) @@ -49,7 +57,7 @@ namespace io AString newfile; do { - newfile = STRPRINTF("%s_%d.tmp", filename, no++); + newfile = STRPRINTF("%s_%d.tmp"_fmt, filename, no++); fd = FD::open(newfile, O_WRONLY | O_CREAT | O_EXCL, 0666); } while (fd == FD() && errno == EEXIST); @@ -67,21 +75,22 @@ namespace io if (!WriteFile::close()) { // leave partial file - FPRINTF(stderr, "Warning: failed to write replacement for %s\n", filename); + FPRINTF(stderr, "Warning: failed to write replacement for %s\n"_fmt, filename); abort(); } int n = backup_count; - AString old_filename = STRPRINTF("%s.%d", filename, n); + AString old_filename = STRPRINTF("%s.%d"_fmt, filename, n); while (--n) { - AString newer_filename = STRPRINTF("%s.%d", filename, n); + AString newer_filename = STRPRINTF("%s.%d"_fmt, filename, n); rename(newer_filename.c_str(), old_filename.c_str()); old_filename = std::move(newer_filename); } rename(filename.c_str(), old_filename.c_str()); - AString tmpfile = STRPRINTF("%s_%d.tmp", filename, tmp_suffix); + AString tmpfile = STRPRINTF("%s_%d.tmp"_fmt, filename, tmp_suffix); rename(tmpfile.c_str(), filename.c_str()); } } // namespace io +} // namespace tmwa diff --git a/src/io/lock.hpp b/src/io/lock.hpp index b879da5..005b371 100644 --- a/src/io/lock.hpp +++ b/src/io/lock.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_IO_LOCK_HPP -#define TMWA_IO_LOCK_HPP +#pragma once // io/lock.hpp - Output to files with atomic replacement and backups. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,13 +18,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "write.hpp" +#include "write.hpp" -# include "../strings/rstring.hpp" +#include "../strings/rstring.hpp" +namespace tmwa +{ namespace io { class WriteLock : public WriteFile @@ -38,5 +39,4 @@ namespace io bool close() = delete; }; } // namespace io - -#endif // TMWA_IO_LOCK_HPP +} // namespace tmwa diff --git a/src/io/read.cpp b/src/io/read.cpp index 2ef35cc..3ae5246 100644 --- a/src/io/read.cpp +++ b/src/io/read.cpp @@ -19,17 +19,19 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include <fcntl.h> -#include <unistd.h> #include "../strings/astring.hpp" #include "../strings/mstring.hpp" #include "../strings/zstring.hpp" +#include "../strings/literal.hpp" #include "../io/cxxstdio.hpp" #include "../poison.hpp" +namespace tmwa +{ namespace io { ReadFile::ReadFile(FD f) @@ -40,6 +42,10 @@ namespace io : fd(FD::open(name, O_RDONLY | O_CLOEXEC)), start(0), end(0) { } + ReadFile::ReadFile(const DirFd& dir, ZString name) + : fd(dir.open_fd(name, O_RDONLY | O_CLOEXEC)), start(0), end(0) + { + } ReadFile::~ReadFile() { fd.close(); @@ -105,12 +111,12 @@ namespace io if (unhappy) { if (happy) - PRINTF("warning: file contains CR\n"); + FPRINTF(stderr, "warning: file contains CR\n"_fmt); else - PRINTF("warning: file contains bare CR\n"); + FPRINTF(stderr, "warning: file contains bare CR\n"_fmt); } else if (!happy && anything) - PRINTF("warning: file does not contain a trailing newline\n"); + FPRINTF(stderr, "warning: file does not contain a trailing newline\n"_fmt); line = AString(tmp); return anything; } @@ -120,3 +126,4 @@ namespace io return fd != FD(); } } // namespace io +} // namespace tmwa diff --git a/src/io/read.hpp b/src/io/read.hpp index f99fb56..1ec26ca 100644 --- a/src/io/read.hpp +++ b/src/io/read.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_IO_READ_HPP -#define TMWA_IO_READ_HPP +#pragma once // io/read.hpp - Input from files. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,12 +18,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "fd.hpp" +#include "dir.hpp" +#include "fd.hpp" +namespace tmwa +{ namespace io { class ReadFile @@ -38,6 +40,8 @@ namespace io ReadFile(FD fd); explicit ReadFile(ZString name); + ReadFile(const DirFd& dir, ZString name); + ReadFile& operator = (ReadFile&&) = delete; ReadFile(ReadFile&&) = delete; ~ReadFile(); @@ -49,5 +53,4 @@ namespace io bool is_open(); }; } // namespace io - -#endif // TMWA_IO_READ_HPP +} // namespace tmwa diff --git a/src/io/read_test.cpp b/src/io/read_test.cpp index 87f95ba..8fe84b7 100644 --- a/src/io/read_test.cpp +++ b/src/io/read_test.cpp @@ -20,10 +20,15 @@ #include <gtest/gtest.h> +#include "../strings/astring.hpp" #include "../strings/zstring.hpp" +#include "../strings/literal.hpp" #include "../poison.hpp" + +namespace tmwa +{ static io::FD string_pipe(ZString sz) { @@ -42,43 +47,44 @@ io::FD string_pipe(ZString sz) TEST(io, read1) { - io::ReadFile rf(string_pipe("Hello")); + io::ReadFile rf(string_pipe("Hello"_s)); AString hi; EXPECT_TRUE(rf.getline(hi)); - EXPECT_EQ(hi, "Hello"); + EXPECT_EQ(hi, "Hello"_s); EXPECT_FALSE(rf.getline(hi)); } TEST(io, read2) { - io::ReadFile rf(string_pipe("Hello\n")); + io::ReadFile rf(string_pipe("Hello\n"_s)); AString hi; EXPECT_TRUE(rf.getline(hi)); - EXPECT_EQ(hi, "Hello"); + EXPECT_EQ(hi, "Hello"_s); EXPECT_FALSE(rf.getline(hi)); } TEST(io, read3) { - io::ReadFile rf(string_pipe("Hello\r")); + io::ReadFile rf(string_pipe("Hello\r"_s)); AString hi; EXPECT_TRUE(rf.getline(hi)); - EXPECT_EQ(hi, "Hello"); + EXPECT_EQ(hi, "Hello"_s); EXPECT_FALSE(rf.getline(hi)); } TEST(io, read4) { - io::ReadFile rf(string_pipe("Hello\r\n")); + io::ReadFile rf(string_pipe("Hello\r\n"_s)); AString hi; EXPECT_TRUE(rf.getline(hi)); - EXPECT_EQ(hi, "Hello"); + EXPECT_EQ(hi, "Hello"_s); EXPECT_FALSE(rf.getline(hi)); } TEST(io, read5) { - io::ReadFile rf(string_pipe("Hello\n\r")); + io::ReadFile rf(string_pipe("Hello\n\r"_s)); AString hi; EXPECT_TRUE(rf.getline(hi)); - EXPECT_EQ(hi, "Hello"); + EXPECT_EQ(hi, "Hello"_s); EXPECT_TRUE(rf.getline(hi)); EXPECT_FALSE(hi); EXPECT_FALSE(rf.getline(hi)); } +} // namespace tmwa diff --git a/src/io/tty.cpp b/src/io/tty.cpp index e71ee44..c498740 100644 --- a/src/io/tty.cpp +++ b/src/io/tty.cpp @@ -20,4 +20,8 @@ #include "../poison.hpp" + +namespace tmwa +{ /* Nothing to see here, move along */ +} // namespace tmwa diff --git a/src/io/tty.hpp b/src/io/tty.hpp index 97487b8..f754b91 100644 --- a/src/io/tty.hpp +++ b/src/io/tty.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_IO_TTY_HPP -#define TMWA_IO_TTY_HPP +#pragma once // io/tty.hpp - terminal escape sequences // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,20 +18,21 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# define SGR_BLACK "\e[30m" -# define SGR_RED "\e[31m" -# define SGR_GREEN "\e[32m" -# define SGR_YELLOW "\e[33m" -# define SGR_BLUE "\e[34m" -# define SGR_MAGENTA "\e[35m" -# define SGR_CYAN "\e[36m" -# define SGR_WHITE "\e[37m" +namespace tmwa +{ +#define SGR_BLACK "\e[30m" +#define SGR_RED "\e[31m" +#define SGR_GREEN "\e[32m" +#define SGR_YELLOW "\e[33m" +#define SGR_BLUE "\e[34m" +#define SGR_MAGENTA "\e[35m" +#define SGR_CYAN "\e[36m" +#define SGR_WHITE "\e[37m" -# define SGR_BOLD "\e[1m" +#define SGR_BOLD "\e[1m" -# define SGR_RESET "\e[0m" - -#endif // TMWA_IO_TTY_HPP +#define SGR_RESET "\e[0m" +} // namespace tmwa diff --git a/src/io/write.cpp b/src/io/write.cpp index 5993a69..833b173 100644 --- a/src/io/write.cpp +++ b/src/io/write.cpp @@ -18,16 +18,21 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <sys/uio.h> - #include <fcntl.h> -#include <unistd.h> +#include <cstdio> +#include <cstdlib> + +#include <algorithm> + +#include "../strings/zstring.hpp" #include "../strings/xstring.hpp" #include "../poison.hpp" +namespace tmwa +{ namespace io { WriteFile::WriteFile(FD f, bool linebuffered) @@ -36,6 +41,9 @@ namespace io WriteFile::WriteFile(ZString name, bool linebuffered) : fd(FD::open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)), lb(linebuffered), buflen(0) {} + WriteFile::WriteFile(const DirFd& dir, ZString name, bool linebuffered) + : fd(dir.open_fd(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)), lb(linebuffered), buflen(0) + {} WriteFile::~WriteFile() { if (fd != FD()) @@ -174,3 +182,4 @@ namespace io return len; } } // namespace io +} // namespace tmwa diff --git a/src/io/write.hpp b/src/io/write.hpp index 870ebb5..1ab05f3 100644 --- a/src/io/write.hpp +++ b/src/io/write.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_IO_WRITE_HPP -#define TMWA_IO_WRITE_HPP +#pragma once // io/write.hpp - Output to files. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,14 +18,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdarg> +#include <cstdarg> -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "fd.hpp" +#include "dir.hpp" +#include "fd.hpp" + +namespace tmwa +{ namespace io { class WriteFile @@ -34,7 +37,6 @@ namespace io private: FD fd; bool lb; - struct {} _unused; unsigned short buflen; char buf[4096]; public: @@ -42,6 +44,8 @@ namespace io WriteFile(FD fd, bool linebuffered=false); explicit WriteFile(ZString name, bool linebuffered=false); + WriteFile(const DirFd& dir, ZString name, bool linebuffered=false); + WriteFile(WriteFile&&) = delete; WriteFile& operator = (WriteFile&&) = delete; ~WriteFile(); @@ -65,5 +69,4 @@ namespace io __attribute__((format(printf, 2, 0))) int do_vprint(WriteFile& out, const char *fmt, va_list ap); } // namespace io - -#endif // TMWA_IO_WRITE_HPP +} // namespace tmwa diff --git a/src/io/write_test.cpp b/src/io/write_test.cpp index ae8eccd..2347e7e 100644 --- a/src/io/write_test.cpp +++ b/src/io/write_test.cpp @@ -26,9 +26,13 @@ #include "../strings/astring.hpp" #include "../strings/mstring.hpp" #include "../strings/xstring.hpp" +#include "../strings/literal.hpp" #include "../poison.hpp" + +namespace tmwa +{ static io::FD pipew(io::FD& rfd) { @@ -65,7 +69,7 @@ public: if (rv == -1) { if (errno != EAGAIN) - return {"Error, read failed :("}; + return "Error, read failed :("_s; rv = 0; } if (rv == 0) @@ -81,11 +85,11 @@ TEST(io, write1) PipeWriter pw(false); io::WriteFile& wf = pw.wf; wf.really_put("Hello, ", 7); - EXPECT_EQ("", pw.slurp()); - wf.put_line("World!\n"); - EXPECT_EQ("", pw.slurp()); + EXPECT_EQ(""_s, pw.slurp()); + wf.put_line("World!\n"_s); + EXPECT_EQ(""_s, pw.slurp()); EXPECT_TRUE(wf.close()); - EXPECT_EQ("Hello, World!\n", pw.slurp()); + EXPECT_EQ("Hello, World!\n"_s, pw.slurp()); } TEST(io, write2) @@ -93,10 +97,11 @@ TEST(io, write2) PipeWriter pw(true); io::WriteFile& wf = pw.wf; wf.really_put("Hello, ", 7); - EXPECT_EQ("", pw.slurp()); - wf.put_line("World!"); + EXPECT_EQ(""_s, pw.slurp()); + wf.put_line("World!"_s); wf.really_put("XXX", 3); - EXPECT_EQ("Hello, World!\n", pw.slurp()); + EXPECT_EQ("Hello, World!\n"_s, pw.slurp()); EXPECT_TRUE(wf.close()); - EXPECT_EQ("XXX", pw.slurp()); + EXPECT_EQ("XXX"_s, pw.slurp()); } +} // namespace tmwa diff --git a/src/login/fwd.hpp b/src/login/fwd.hpp new file mode 100644 index 0000000..94fe3c0 --- /dev/null +++ b/src/login/fwd.hpp @@ -0,0 +1,27 @@ +#pragma once +// login/fwd.hpp - list of type names for login server +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +// meh, add more when I feel like it +} // namespace tmwa diff --git a/src/login/login.cpp b/src/login/login.cpp index a60b34e..ccb68fc 100644 --- a/src/login/login.cpp +++ b/src/login/login.cpp @@ -1,3 +1,4 @@ +#include "login.hpp" // login.cpp - Core of the login server. // // Copyright © ????-2004 Athena Dev Teams @@ -20,8 +21,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <arpa/inet.h> -#include <sys/types.h> #include <sys/wait.h> #include <netdb.h> @@ -29,14 +28,12 @@ #include <sys/resource.h> -#include <cstdlib> -#include <cstring> #include <ctime> #include <algorithm> -#include <array> #include <set> -#include <type_traits> + +#include "../ints/udl.hpp" #include "../strings/mstring.hpp" #include "../strings/astring.hpp" @@ -51,24 +48,36 @@ #include "../io/lock.hpp" #include "../io/read.hpp" #include "../io/tty.hpp" +#include "../io/write.hpp" + +#include "../net/packets.hpp" +#include "../net/socket.hpp" +#include "../net/timer.hpp" #include "../mmo/config_parse.hpp" #include "../mmo/core.hpp" #include "../mmo/extract.hpp" #include "../mmo/human_time_diff.hpp" +#include "../mmo/ids.hpp" #include "../mmo/md5more.hpp" #include "../mmo/mmo.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" -#include "../mmo/version.hpp" #include "../mmo/utils.hpp" +#include "../mmo/version.hpp" + +#include "../proto2/any-user.hpp" +#include "../proto2/login-admin.hpp" +#include "../proto2/login-char.hpp" +#include "../proto2/login-user.hpp" #include "../poison.hpp" + +namespace tmwa +{ constexpr int MAX_SERVERS = 30; -constexpr int START_ACCOUNT_NUM = 2000000; -constexpr int END_ACCOUNT_NUM = 100000000; +constexpr AccountId START_ACCOUNT_NUM = wrap<AccountId>(2000000); +constexpr AccountId END_ACCOUNT_NUM = wrap<AccountId>(100000000); struct mmo_account { @@ -76,10 +85,10 @@ struct mmo_account AccountPass passwd; int passwdenc; - long account_id; - long login_id1; - long login_id2; - long char_id; + AccountId account_id; + int login_id1; + int login_id2; + AccountId char_id; timestamp_milliseconds_buffer lastlogin; SEX sex; }; @@ -93,9 +102,7 @@ struct mmo_char_server }; static -int account_id_count = START_ACCOUNT_NUM; -static -int server_num; +AccountId account_id_count = START_ACCOUNT_NUM; static int new_account = 0; static @@ -114,19 +121,19 @@ static ServerName main_server; static -AString account_filename = "save/account.txt"; +AString account_filename = "save/account.txt"_s; static -AString gm_account_filename = "save/gm_account.txt"; +AString gm_account_filename = "save/gm_account.txt"_s; static -AString login_log_filename = "log/login.log"; +AString login_log_filename = "log/login.log"_s; static -AString login_log_unknown_packets_filename = "log/login_unknown_packets.log"; +AString login_log_unknown_packets_filename = "log/login_unknown_packets.log"_s; static int save_unknown_packets = 0; static tick_t creation_time_GM_account_file; static -std::chrono::seconds gm_account_filename_check_timer = std::chrono::seconds(15); +std::chrono::seconds gm_account_filename_check_timer = 15_s; static int display_parse_login = 0; // 0: no, 1: yes @@ -144,7 +151,7 @@ Array<int, MAX_SERVERS> server_freezeflag; // Char-server anti-freeze system. static int anti_freeze_enable = 0; static -std::chrono::seconds anti_freeze_interval = std::chrono::seconds(15); +std::chrono::seconds anti_freeze_interval = 15_s; static Session *login_session; @@ -163,7 +170,7 @@ std::vector<IP4Mask> access_allow, access_deny, access_ladmin; static -int min_level_to_connect = 0; // minimum level of player/GM (0: player, 1-99: gm) to connect on the server +GmLevel min_level_to_connect = GmLevel::from(0_u32); // minimum level of player/GM (0: player, 1-99: gm) to connect on the server static int add_to_unlimited_account = 0; // Give possibility or not to adjust (ladmin command: timeadd) the time of an unlimited account. static @@ -171,30 +178,32 @@ int start_limited_time = -1; // Starting additional sec from now for the limit static int check_ip_flag = 1; // It's to check IP of a player between login-server and char-server (part of anti-hacking system) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmissing-noreturn" +DIAG_PUSH(); +DIAG_I(missing_noreturn); void SessionDeleter::operator()(SessionData *) { - assert(false && "login server does not have sessions anymore"); + assert(false && "login server does not have sessions anymore"_s); } -#pragma GCC diagnostic pop +DIAG_POP(); constexpr int AUTH_FIFO_SIZE = 256; struct AuthFifo { - int account_id, login_id1, login_id2; + AccountId account_id; + int login_id1, login_id2; IP4Address ip; SEX sex; int delflag; }; static Array<AuthFifo, AUTH_FIFO_SIZE> auth_fifo; +// TODO replace with auto_fifo_it static int auth_fifo_pos = 0; struct AuthData { - int account_id; + AccountId account_id; SEX sex; AccountName userid; AccountCrypt pass; @@ -208,7 +217,7 @@ struct AuthData IP4Address last_ip; // save of last IP of connection VString<254> memo; // a memo field int account_reg2_num; - Array<struct global_reg, ACCOUNT_REG2_NUM> account_reg2; + Array<GlobalReg, ACCOUNT_REG2_NUM> account_reg2; }; static std::vector<AuthData> auth_data; @@ -220,28 +229,15 @@ AccountPass admin_pass; static AString gm_pass; static -int level_new_gm = 60; +GmLevel level_new_gm = GmLevel::from(60u); static -Map<int, GM_Account> gm_account_db; +Map<AccountId, GM_Account> gm_account_db; static pid_t pid = 0; // For forked DB writes -namespace e -{ -enum class VERSION_2 : uint8_t -{ - /// client supports updatehost - UPDATEHOST = 0x01, - /// send servers in forward order - SERVERORDER = 0x02, -}; -ENUM_BITWISE_OPERATORS(VERSION_2) -} -using e::VERSION_2; - //------------------------------ // Writing function of logs file //------------------------------ @@ -269,9 +265,9 @@ void delete_fromchar(Session *sess) assert (it != server_session.end()); int id = it - server_session.begin(); IP4Address ip = sess->client_ip; - PRINTF("Char-server '%s' has disconnected.\n", server[id].name); - LOGIN_LOG("Char-server '%s' has disconnected (ip: %s).\n", - server[id].name, ip); + PRINTF("Char-server '%s' has disconnected.\n"_fmt, server[id].name); + LOGIN_LOG("Char-server '%s' has disconnected (ip: %s).\n"_fmt, + server[id].name, ip); server_session[id] = nullptr; server[id] = mmo_char_server{}; } @@ -279,7 +275,7 @@ void delete_fromchar(Session *sess) static void delete_admin(Session *s) { - PRINTF("Remote administration has disconnected (session #%d).\n", + PRINTF("Remote administration has disconnected (session #%d).\n"_fmt, s); } @@ -289,11 +285,11 @@ void delete_admin(Session *s) // and returns its level (or 0 if it isn't a GM account or if not found) //---------------------------------------------------------------------- static -uint8_t isGM(int account_id) +GmLevel isGM(AccountId account_id) { GM_Account *p = gm_account_db.search(account_id); - if (p == NULL) - return 0; + if (p == nullptr) + return GmLevel(); return p->level; } @@ -304,7 +300,6 @@ static int read_gm_account(void) { int c = 0; - int GM_level; gm_account_db.clear(); @@ -313,12 +308,12 @@ int read_gm_account(void) io::ReadFile fp(gm_account_filename); if (!fp.is_open()) { - PRINTF("read_gm_account: GM accounts file [%s] not found.\n", + PRINTF("read_gm_account: GM accounts file [%s] not found.\n"_fmt, + gm_account_filename); + PRINTF(" Actually, there is no GM accounts on the server.\n"_fmt); + LOGIN_LOG("read_gm_account: GM accounts file [%s] not found.\n"_fmt, gm_account_filename); - PRINTF(" Actually, there is no GM accounts on the server.\n"); - LOGIN_LOG("read_gm_account: GM accounts file [%s] not found.\n", - gm_account_filename); - LOGIN_LOG(" Actually, there is no GM accounts on the server.\n"); + LOGIN_LOG(" Actually, there is no GM accounts on the server.\n"_fmt); return 1; } // limited to 4000, because we send information to char-servers (more than 4000 GM accounts???) @@ -330,49 +325,40 @@ int read_gm_account(void) continue; GM_Account p {}; if (!extract(line, record<' '>(&p.account_id, &p.level))) - PRINTF("read_gm_account: file [%s], invalid 'id_acount level' format: '%s'\n", - gm_account_filename, line); - else if (p.level <= 0) - PRINTF("read_gm_account: file [%s] %dth account (invalid level [0 or negative]: %d).\n", - gm_account_filename, c + 1, p.level); + PRINTF("read_gm_account: file [%s], invalid 'id_acount level' format: '%s'\n"_fmt, + gm_account_filename, line); else { - if (p.level > 99) - { - PRINTF("read_gm_account: file [%s] %dth account (invalid level, but corrected: %d->99).\n", - gm_account_filename, c + 1, p.level); - p.level = 99; - } - if ((GM_level = isGM(p.account_id)) > 0) + GmLevel GM_level = isGM(p.account_id); + if (GM_level) { // if it's not a new account if (GM_level == p.level) - PRINTF("read_gm_account: GM account %d defined twice (same level: %d).\n", - p.account_id, p.level); + PRINTF("read_gm_account: GM account %d defined twice (same level: %d).\n"_fmt, + p.account_id, p.level); else - PRINTF("read_gm_account: GM account %d defined twice (levels: %d and %d).\n", - p.account_id, GM_level, p.level); + PRINTF("read_gm_account: GM account %d defined twice (levels: %d and %d).\n"_fmt, + p.account_id, GM_level, p.level); } if (GM_level != p.level) { // if new account or new level gm_account_db.insert(p.account_id, p); - //PRINTF("GM account:%d, level: %d->%d\n", p.account_id, GM_level, p.level); - if (GM_level == 0) + if (!GM_level) { // if new account c++; if (c >= 4000) { - PRINTF("***WARNING: 4000 GM accounts found. Next GM accounts are not readed.\n"); - LOGIN_LOG("***WARNING: 4000 GM accounts found. Next GM accounts are not readed.\n"); + PRINTF("***WARNING: 4000 GM accounts found. Next GM accounts are not readed.\n"_fmt); + LOGIN_LOG("***WARNING: 4000 GM accounts found. Next GM accounts are not readed.\n"_fmt); } } } } } - PRINTF("read_gm_account: file '%s' readed (%d GM accounts found).\n", + PRINTF("read_gm_account: file '%s' readed (%d GM accounts found).\n"_fmt, + gm_account_filename, c); + LOGIN_LOG("read_gm_account: file '%s' readed (%d GM accounts found).\n"_fmt, gm_account_filename, c); - LOGIN_LOG("read_gm_account: file '%s' readed (%d GM accounts found).\n", - gm_account_filename, c); return 0; } @@ -484,7 +470,7 @@ AString mmo_auth_tostr(const AuthData *p) "%lld\t" "%s\t" "%s\t" - "%lld\t", + "%lld\t"_fmt, p->account_id, p->userid, p->pass, @@ -502,7 +488,7 @@ AString mmo_auth_tostr(const AuthData *p) assert (p->account_reg2_num < ACCOUNT_REG2_NUM); for (int i = 0; i < p->account_reg2_num; i++) if (p->account_reg2[i].str) - str += STRPRINTF("%s,%d ", + str += STRPRINTF("%s,%d "_fmt, p->account_reg2[i].str, p->account_reg2[i].value); return AString(str); @@ -511,7 +497,7 @@ AString mmo_auth_tostr(const AuthData *p) static bool extract(XString line, AuthData *ad) { - std::vector<struct global_reg> vars; + std::vector<GlobalReg> vars; VString<1> sex; VString<15> ip; if (!extract(line, @@ -531,13 +517,15 @@ bool extract(XString line, AuthData *ad) &ad->ban_until_time, vrec<' '>(&vars)))) return false; + if (ad->lastlogin == stringish<timestamp_milliseconds_buffer>("-"_s)) + stamp_time(ad->lastlogin); ad->last_ip = IP4Address(); - if (ip != "-" && !extract(ip, &ad->last_ip)) + if (ip != "-"_s && !extract(ip, &ad->last_ip)) return false; - if (ad->account_id > END_ACCOUNT_NUM) + if (!(ad->account_id < END_ACCOUNT_NUM)) return false; // TODO replace *every* lookup with a map lookup - static std::set<int> seen_ids; + static std::set<AccountId> seen_ids; static std::set<AccountName> seen_names; // we don't have to worry about deleted characters, // this is only called during startup @@ -571,7 +559,7 @@ bool extract(XString line, AuthData *ad) if (!ad->error_message || ad->state != 7) // 7, because state is packet 0x006a value + 1 - ad->error_message = stringish<timestamp_seconds_buffer>("-"); + ad->error_message = stringish<timestamp_seconds_buffer>("-"_s); if (vars.size() > ACCOUNT_REG2_NUM) return false; @@ -594,8 +582,8 @@ int mmo_auth_init(void) { // no account file -> no account -> no login, including char-server (ERROR) // not anymore! :-) - PRINTF(SGR_BOLD SGR_RED "mmo_auth_init: Accounts file [%s] not found." SGR_RESET "\n", - account_filename); + PRINTF(SGR_BOLD SGR_RED "mmo_auth_init: Accounts file [%s] not found." SGR_RESET "\n"_fmt, + account_filename); return 0; } @@ -612,28 +600,29 @@ int mmo_auth_init(void) AuthData ad {}; if (!extract(line, &ad)) { - int i = 0; - if (SSCANF(line, "%d\t%%newid%%\n%n", &ad.account_id, &i) == 1 - && i > 0 && ad.account_id > account_id_count) - account_id_count = ad.account_id; + if (extract(line, record<'\t'>(&ad.account_id, "%newid%"_s))) + { + if (account_id_count < ad.account_id) + account_id_count = ad.account_id; + } else - LOGIN_LOG("Account skipped\n%s", line); + LOGIN_LOG("Account skipped\n%s"_fmt, line); continue; } auth_data.push_back(ad); - if (isGM(ad.account_id) > 0) + if (isGM(ad.account_id)) gm_count++; - if (ad.account_id >= account_id_count) - account_id_count = ad.account_id + 1; + if (account_id_count < next(ad.account_id)) + account_id_count = next(ad.account_id); } - AString str = STRPRINTF("%s has %zu accounts (%d GMs)\n", + AString str = STRPRINTF("%s has %zu accounts (%d GMs)\n"_fmt, account_filename, auth_data.size(), gm_count); - PRINTF("%s: %s\n", __PRETTY_FUNCTION__, str); - LOGIN_LOG("%s\n", line); + PRINTF("mmo_auth_init: %s\n"_fmt, str); + LOGIN_LOG("%s\n"_fmt, line); return 0; } @@ -648,39 +637,39 @@ void mmo_auth_sync(void) if (!fp.is_open()) { - PRINTF("uh-oh - unable to save accounts\n"); + PRINTF("uh-oh - unable to save accounts\n"_fmt); return; } FPRINTF(fp, - "// Accounts file: here are saved all information about the accounts.\n"); + "// Accounts file: here are saved all information about the accounts.\n"_fmt); FPRINTF(fp, - "// Structure: ID, account name, password, last login time, sex, # of logins, state, email, error message for state 7, validity time, last (accepted) login ip, memo field, ban timestamp, repeated(register text, register value)\n"); - FPRINTF(fp, "// Some explanations:\n"); + "// Structure: ID, account name, password, last login time, sex, # of logins, state, email, error message for state 7, validity time, last (accepted) login ip, memo field, ban timestamp, repeated(register text, register value)\n"_fmt); + FPRINTF(fp, "// Some explanations:\n"_fmt); FPRINTF(fp, - "// account name : between 4 to 23 char for a normal account (standard client can't send less than 4 char).\n"); - FPRINTF(fp, "// account password: between 4 to 23 char\n"); + "// account name : between 4 to 23 char for a normal account (standard client can't send less than 4 char).\n"_fmt); + FPRINTF(fp, "// account password: between 4 to 23 char\n"_fmt); FPRINTF(fp, - "// sex : M or F for normal accounts, S for server accounts\n"); + "// sex : M or F for normal accounts, S for server accounts\n"_fmt); FPRINTF(fp, - "// state : 0: account is ok, 1 to 256: error code of packet 0x006a + 1\n"); + "// state : 0: account is ok, 1 to 256: error code of packet 0x006a + 1\n"_fmt); FPRINTF(fp, - "// email : between 3 to 39 char (a@a.com is like no email)\n"); + "// email : between 3 to 39 char (a@a.com is like no email)\n"_fmt); FPRINTF(fp, - "// error message : text for the state 7: 'Your are Prohibited to login until <text>'. Max 19 char\n"); + "// error message : text for the state 7: 'Your are Prohibited to login until <text>'. Max 19 char\n"_fmt); FPRINTF(fp, - "// valitidy time : 0: unlimited account, <other value>: date calculated by addition of 1/1/1970 + value (number of seconds since the 1/1/1970)\n"); - FPRINTF(fp, "// memo field : max 254 char\n"); + "// valitidy time : 0: unlimited account, <other value>: date calculated by addition of 1/1/1970 + value (number of seconds since the 1/1/1970)\n"_fmt); + FPRINTF(fp, "// memo field : max 254 char\n"_fmt); FPRINTF(fp, - "// ban time : 0: no ban, <other value>: banned until the date: date calculated by addition of 1/1/1970 + value (number of seconds since the 1/1/1970)\n"); + "// ban time : 0: no ban, <other value>: banned until the date: date calculated by addition of 1/1/1970 + value (number of seconds since the 1/1/1970)\n"_fmt); for (const AuthData& ad : auth_data) { - if (ad.account_id < 0) + if (!ad.account_id) continue; AString line = mmo_auth_tostr(&ad); fp.put_line(line); } - FPRINTF(fp, "%d\t%%newid%%\n", account_id_count); + FPRINTF(fp, "%d\t%%newid%%\n"_fmt, account_id_count); } // We want to sync the DB to disk as little as possible as it's fairly @@ -721,44 +710,41 @@ void check_auth_sync(TimerData *, tick_t) return; } -//-------------------------------------------------------------------- -// Packet send to all char-servers, except one (wos: without our self) -//-------------------------------------------------------------------- + static -void charif_sendallwos(Session *ss, const uint8_t *buf, size_t len) +auto iter_char_sessions() -> decltype(filter_iterator<Session *>(&server_session)) { - for (int i = 0; i < MAX_SERVERS; i++) - { - Session *s = server_session[i]; - if (s && s != ss) - { - WFIFO_BUF_CLONE(s, buf, len); - WFIFOSET(s, len); - } - } + return filter_iterator<Session *>(&server_session); } //----------------------------------------------------- // Send GM accounts to all char-server //----------------------------------------------------- static -void send_GM_accounts(void) +void send_GM_accounts(Session *only=nullptr) { - uint8_t buf[32000]; - int len; + std::vector<Packet_Repeat<0x2732>> tail; - len = 4; - WBUFW(buf, 0) = 0x2732; for (const AuthData& ad : auth_data) + { // send only existing accounts. We can not create a GM account when server is online. - if (uint8_t GM_value = isGM(ad.account_id)) + if (GmLevel GM_value = isGM(ad.account_id)) { - WBUFL(buf, len) = ad.account_id; - WBUFB(buf, len + 4) = GM_value; - len += 5; + Packet_Repeat<0x2732> item; + item.account_id = ad.account_id; + item.gm_level = GM_value; + tail.push_back(item); } - WBUFW(buf, 2) = len; - charif_sendallwos(nullptr, buf, len); + } + if (only) + { + send_packet_repeatonly<0x2732, 4, 5>(only, tail); + return; + } + for (Session *ss : iter_char_sessions()) + { + send_packet_repeatonly<0x2732, 4, 5>(ss, tail); + } } //----------------------------------------------------- @@ -785,17 +771,18 @@ void check_GM_file(TimerData *, tick_t) // Account creation (with e-mail check) //------------------------------------- static -int mmo_auth_new(struct mmo_account *account, SEX sex, AccountEmail email) +AccountId mmo_auth_new(struct mmo_account *account, SEX sex, AccountEmail email) { - while (isGM(account_id_count) > 0) - account_id_count++; + while (isGM(account_id_count)) + account_id_count = next(account_id_count); struct AuthData ad {}; - ad.account_id = account_id_count++; + ad.account_id = account_id_count; + account_id_count = next(account_id_count); ad.userid = account->userid; ad.pass = MD5_saltcrypt(account->passwd, make_salt()); - ad.lastlogin = stringish<timestamp_milliseconds_buffer>("-"); + stamp_time(ad.lastlogin); ad.sex = sex; ad.logincount = 0; ad.state = 0; @@ -805,7 +792,7 @@ int mmo_auth_new(struct mmo_account *account, SEX sex, AccountEmail email) else ad.email = email; - ad.error_message = stringish<timestamp_seconds_buffer>("-"); + ad.error_message = stringish<timestamp_seconds_buffer>("-"_s); ad.ban_until_time = TimeT(); if (start_limited_time < 0) @@ -820,7 +807,7 @@ int mmo_auth_new(struct mmo_account *account, SEX sex, AccountEmail email) } ad.last_ip = IP4Address(); - ad.memo = "!"; + ad.memo = "!"_s; ad.account_reg2_num = 0; auth_data.push_back(ad); @@ -839,8 +826,8 @@ int mmo_auth(struct mmo_account *account, Session *s) // Account creation with _M/_F if (account->passwdenc == 0 - && (account->userid.endswith("_F") || account->userid.endswith("_M")) - && new_account == 1 && account_id_count <= END_ACCOUNT_NUM + && (account->userid.endswith("_F"_s) || account->userid.endswith("_M"_s)) + && new_account == 1 && account_id_count < END_ACCOUNT_NUM && (account->userid.size() - 2) >= 4 && account->passwd.size() >= 4) { new_account_sex = account->userid.back(); @@ -855,24 +842,24 @@ int mmo_auth(struct mmo_account *account, Session *s) int encpasswdok = 0; if (new_account_sex) { - LOGIN_LOG("Attempt of creation of an already existant account (account: %s_%c, ip: %s)\n", - account->userid, new_account_sex, ip); + LOGIN_LOG("Attempt of creation of an already existant account (account: %s_%c, ip: %s)\n"_fmt, + account->userid, new_account_sex, ip); return 9; // 9 = Account already exists } if ((!pass_ok(account->passwd, ad->pass)) && !encpasswdok) { if (account->passwdenc == 0) - LOGIN_LOG("Invalid password (account: %s, ip: %s)\n", - account->userid, ip); + LOGIN_LOG("Invalid password (account: %s, ip: %s)\n"_fmt, + account->userid, ip); return 1; // 1 = Incorrect Password } if (ad->state) { - LOGIN_LOG("Connection refused (account: %s, state: %d, ip: %s)\n", - account->userid, ad->state, - ip); + LOGIN_LOG("Connection refused (account: %s, state: %d, ip: %s)\n"_fmt, + account->userid, ad->state, + ip); switch (ad->state) { // packet 0x006a value + 1 case 1: // 0 = Unregistered ID @@ -899,15 +886,15 @@ int mmo_auth(struct mmo_account *account, Session *s) if (ad->ban_until_time > TimeT::now()) { // always banned - LOGIN_LOG("Connection refused (account: %s, banned until %s, ip: %s)\n", - account->userid, tmpstr, ip); + LOGIN_LOG("Connection refused (account: %s, banned until %s, ip: %s)\n"_fmt, + account->userid, tmpstr, ip); return 6; // 6 = Your are Prohibited to log in until %s } else { // ban is finished - LOGIN_LOG("End of ban (account: %s, previously banned until %s -> not more banned, ip: %s)\n", - account->userid, tmpstr, ip); + LOGIN_LOG("End of ban (account: %s, previously banned until %s -> not more banned, ip: %s)\n"_fmt, + account->userid, tmpstr, ip); ad->ban_until_time = TimeT(); // reset the ban time } } @@ -915,28 +902,28 @@ int mmo_auth(struct mmo_account *account, Session *s) if (ad->connect_until_time && ad->connect_until_time < TimeT::now()) { - LOGIN_LOG("Connection refused (account: %s, expired ID, ip: %s)\n", - account->userid, ip); + LOGIN_LOG("Connection refused (account: %s, expired ID, ip: %s)\n"_fmt, + account->userid, ip); return 2; // 2 = This ID is expired } - LOGIN_LOG("Authentification accepted (account: %s (id: %d), ip: %s)\n", - account->userid, ad->account_id, ip); + LOGIN_LOG("Authentification accepted (account: %s (id: %d), ip: %s)\n"_fmt, + account->userid, ad->account_id, ip); } else { if (new_account_sex == '\0') { - LOGIN_LOG("Unknown account (account: %s, ip: %s)\n", - account->userid, ip); + LOGIN_LOG("Unknown account (account: %s, ip: %s)\n"_fmt, + account->userid, ip); return 0; // 0 = Unregistered ID } else { - int new_id = mmo_auth_new(account, sex_from_char(new_account_sex), DEFAULT_EMAIL); - LOGIN_LOG("Account creation and authentification accepted (account %s (id: %d), sex: %c, connection with _F/_M, ip: %s)\n", - account->userid, new_id, - new_account_sex, ip); + AccountId new_id = mmo_auth_new(account, sex_from_char(new_account_sex), DEFAULT_EMAIL); + LOGIN_LOG("Account creation and authentification accepted (account %s (id: %d), sex: %c, connection with _F/_M, ip: %s)\n"_fmt, + account->userid, new_id, + new_account_sex, ip); ad = &auth_data.back(); } } @@ -964,18 +951,16 @@ void char_anti_freeze_system(TimerData *, tick_t) { int i; - //PRINTF("Entering in char_anti_freeze_system function to check freeze of servers.\n"); for (i = 0; i < MAX_SERVERS; i++) { if (server_session[i]) { // if char-server is online - //PRINTF("char_anti_freeze_system: server #%d '%s', flag: %d.\n", i, server[i].name, server_freezeflag[i]); if (server_freezeflag[i]-- < 1) { // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed - PRINTF("Char-server anti-freeze system: char-server #%d '%s' is freezed -> disconnection.\n", - i, server[i].name); - LOGIN_LOG("Char-server anti-freeze system: char-server #%d '%s' is freezed -> disconnection.\n", - i, server[i].name); + PRINTF("Char-server anti-freeze system: char-server #%d '%s' is freezed -> disconnection.\n"_fmt, + i, server[i].name); + LOGIN_LOG("Char-server anti-freeze system: char-server #%d '%s' is freezed -> disconnection.\n"_fmt, + i, server[i].name); server_session[i]->set_eof(); } } @@ -1000,67 +985,81 @@ void parse_fromchar(Session *s) return; } - while (RFIFOREST(s) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id)) { - if (display_parse_fromchar == 2 || (display_parse_fromchar == 1 && RFIFOW(s, 0) != 0x2714)) // 0x2714 is done very often (number of players) - PRINTF("parse_fromchar: connection #%d, packet: 0x%x (with being read: %zu bytes).\n", - s, RFIFOW(s, 0), RFIFOREST(s)); + if (display_parse_fromchar == 2 || (display_parse_fromchar == 1 && packet_id != 0x2714)) // 0x2714 is done very often (number of players) + PRINTF("parse_fromchar: connection #%d, packet: 0x%x (with being read: %zu bytes).\n"_fmt, + s, packet_id, packet_avail(s)); - switch (RFIFOW(s, 0)) + switch (packet_id) { // request from map-server via char-server to reload GM accounts (by Yor). case 0x2709: - LOGIN_LOG("Char-server '%s': Request to re-load GM configuration file (ip: %s).\n", - server[id].name, ip); + { + Packet_Fixed<0x2709> fixed; + rv = recv_fpacket<0x2709, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + + LOGIN_LOG("Char-server '%s': Request to re-load GM configuration file (ip: %s).\n"_fmt, + server[id].name, ip); read_gm_account(); // send GM accounts to all char-servers send_GM_accounts(); - RFIFOSKIP(s, 2); break; + } case 0x2712: // request from char-server to authentify an account - if (RFIFOREST(s) < 19) - return; + { + Packet_Fixed<0x2712> fixed; + rv = recv_fpacket<0x2712, 19>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - int acc = RFIFOL(s, 2); + AccountId acc = fixed.account_id; int i; for (i = 0; i < AUTH_FIFO_SIZE; i++) { if (auth_fifo[i].account_id == acc && - auth_fifo[i].login_id1 == RFIFOL(s, 6) && - auth_fifo[i].login_id2 == RFIFOL(s, 10) && // relate to the versions higher than 18 - auth_fifo[i].sex == static_cast<SEX>(RFIFOB(s, 14)) && + auth_fifo[i].login_id1 == fixed.login_id1 && + auth_fifo[i].login_id2 == fixed.login_id2 && // relate to the versions higher than 18 + auth_fifo[i].sex == fixed.sex && (!check_ip_flag - || auth_fifo[i].ip == RFIFOIP(s, 15)) + || auth_fifo[i].ip == fixed.ip) && !auth_fifo[i].delflag) { - int p; auth_fifo[i].delflag = 1; - LOGIN_LOG("Char-server '%s': authentification of the account %d accepted (ip: %s).\n", - server[id].name, acc, ip); + LOGIN_LOG("Char-server '%s': authentification of the account %d accepted (ip: %s).\n"_fmt, + server[id].name, acc, ip); for (const AuthData& ad : auth_data) { if (ad.account_id == acc) { - WFIFOW(s, 0) = 0x2729; // Sending of the account_reg2 - WFIFOL(s, 4) = acc; + Packet_Head<0x2729> head_29; + head_29.account_id = acc; + std::vector<Packet_Repeat<0x2729>> repeat_29; int j; - for (p = 8, j = 0; + for (j = 0; j < ad.account_reg2_num; - p += 36, j++) + j++) { - WFIFO_STRING(s, p, ad.account_reg2[j].str, 32); - WFIFOL(s, p + 32) = ad.account_reg2[j].value; + Packet_Repeat<0x2729> item; + item.name = ad.account_reg2[j].str; + item.value = ad.account_reg2[j].value; + repeat_29.push_back(item); } - WFIFOW(s, 2) = p; - WFIFOSET(s, p); -// PRINTF("parse_fromchar: Sending of account_reg2: login->char (auth fifo)\n"); - WFIFOW(s, 0) = 0x2713; - WFIFOL(s, 2) = acc; - WFIFOB(s, 6) = 0; - WFIFO_STRING(s, 7, ad.email, 40); - WFIFOL(s, 47) = static_cast<time_t>(ad.connect_until_time); - WFIFOSET(s, 51); + send_vpacket<0x2729, 8, 36>(s, head_29, repeat_29); + + Packet_Fixed<0x2713> fixed_13; + fixed_13.account_id = acc; + fixed_13.invalid = 0; + fixed_13.email = ad.email; + fixed_13.connect_until = ad.connect_until_time; + + send_fpacket<0x2713, 51>(s, fixed_13); break; } } @@ -1070,109 +1069,91 @@ void parse_fromchar(Session *s) // authentification not found if (i == AUTH_FIFO_SIZE) { - LOGIN_LOG("Char-server '%s': authentification of the account %d REFUSED (ip: %s).\n", - server[id].name, acc, ip); - WFIFOW(s, 0) = 0x2713; - WFIFOL(s, 2) = acc; - WFIFOB(s, 6) = 1; - // It is unnecessary to send email - // It is unnecessary to send validity date of the account - WFIFOSET(s, 51); + LOGIN_LOG("Char-server '%s': authentification of the account %d REFUSED (ip: %s).\n"_fmt, + server[id].name, acc, ip); + + Packet_Fixed<0x2713> fixed_13; + fixed_13.account_id = acc; + fixed_13.invalid = 1; + // fixed_13.email + // fixed_13.connect_until + + send_fpacket<0x2713, 51>(s, fixed_13); } } - RFIFOSKIP(s, 19); break; + } case 0x2714: - if (RFIFOREST(s) < 6) - return; - //PRINTF("parse_fromchar: Receiving of the users number of the server '%s': %d\n", server[id].name, RFIFOL(fd,2)); - server[id].users = RFIFOL(s, 2); + { + Packet_Fixed<0x2714> fixed; + rv = recv_fpacket<0x2714, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + + server[id].users = fixed.users; if (anti_freeze_enable) server_freezeflag[id] = 5; // Char anti-freeze system. Counter. 5 ok, 4...0 freezed - RFIFOSKIP(s, 6); - break; - - // we receive a e-mail creation of an account with a default e-mail (no answer) - case 0x2715: - if (RFIFOREST(s) < 46) - return; - { - int acc = RFIFOL(s, 2); - AccountEmail email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 6)); - if (!e_mail_check(email)) - LOGIN_LOG("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - e-mail is invalid (account: %d, ip: %s)\n", - server[id].name, acc, ip); - else - { - for (AuthData& ad : auth_data) - { - if (ad.account_id == acc - && (ad.email == DEFAULT_EMAIL || !ad.email)) - { - ad.email = email; - LOGIN_LOG("Char-server '%s': Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", - server[id].name, acc, email, ip); - goto x2715_out; - } - } - LOGIN_LOG("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - account doesn't exist or e-mail of account isn't default e-mail (account: %d, ip: %s).\n", - server[id].name, acc, ip); - } - x2715_out: - RFIFOSKIP(s, 46); break; + } // We receive an e-mail/limited time request, because a player comes back from a map-server to the char-server - } case 0x2716: - if (RFIFOREST(s) < 6) - return; { - int account_id = RFIFOL(s, 2); - //PRINTF("parse_fromchar: E-mail/limited time request from '%s' server (concerned account: %d)\n", server[id].name, RFIFOL(fd,2)); + Packet_Fixed<0x2716> fixed; + rv = recv_fpacket<0x2716, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; for (const AuthData& ad : auth_data) { if (ad.account_id == account_id) { - LOGIN_LOG("Char-server '%s': e-mail of the account %d found (ip: %s).\n", + LOGIN_LOG("Char-server '%s': e-mail of the account %d found (ip: %s).\n"_fmt, server[id].name, account_id, ip); - WFIFOW(s, 0) = 0x2717; - WFIFOL(s, 2) = account_id; - WFIFO_STRING(s, 6, ad.email, 40); - WFIFOL(s, 46) = static_cast<time_t>(ad.connect_until_time); - WFIFOSET(s, 50); + + Packet_Fixed<0x2717> fixed_17; + fixed_17.account_id = account_id; + fixed_17.email = ad.email; + fixed_17.connect_until = ad.connect_until_time; + + send_fpacket<0x2717, 50>(s, fixed_17); + if (rv != RecvResult::Complete) + break; goto x2716_end; } } - LOGIN_LOG("Char-server '%s': e-mail of the account %d NOT found (ip: %s).\n", + LOGIN_LOG("Char-server '%s': e-mail of the account %d NOT found (ip: %s).\n"_fmt, server[id].name, account_id, ip); - } x2716_end: - RFIFOSKIP(s, 6); break; + } case 0x2720: // To become GM request - if (RFIFOREST(s) < 4 || RFIFOREST(s) < RFIFOW(s, 2)) - return; + { + Packet_Head<0x2720> head; + AString repeat; + rv = recv_vpacket<0x2720, 8, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + break; + { - int acc; - unsigned char buf[10]; - acc = RFIFOL(s, 4); - //PRINTF("parse_fromchar: Request to become a GM acount from %d account.\n", acc); - WBUFW(buf, 0) = 0x2721; - WBUFL(buf, 2) = acc; - WBUFL(buf, 6) = 0; - size_t len = RFIFOW(s, 2) - 8; - AString pass = RFIFO_STRING(s, 8, len); + AccountId acc = head.account_id; + + Packet_Fixed<0x2721> fixed_21; + fixed_21.account_id = acc; + fixed_21.gm_level = GmLevel(); + + AString pass = repeat; if (pass == gm_pass) { // only non-GM can become GM - if (isGM(acc) == 0) + if (!isGM(acc)) { // if we autorise creation - if (level_new_gm > 0) + if (level_new_gm) { // if we can open the file to add the new GM io::AppendFile fp(gm_account_filename); @@ -1181,75 +1162,82 @@ void parse_fromchar(Session *s) timestamp_seconds_buffer tmpstr; stamp_time(tmpstr); FPRINTF(fp, - "\n// %s: @GM command on account %d\n%d %d\n", - tmpstr, - acc, acc, level_new_gm); + "\n// %s: @GM command on account %d\n%d %d\n"_fmt, + tmpstr, + acc, acc, level_new_gm); if (!fp.close()) { - PRINTF("warning: didn't actually save GM file\n"); + PRINTF("warning: didn't actually save GM file\n"_fmt); } - WBUFL(buf, 6) = level_new_gm; + fixed_21.gm_level = level_new_gm; read_gm_account(); send_GM_accounts(); - PRINTF("GM Change of the account %d: level 0 -> %d.\n", - acc, level_new_gm); - LOGIN_LOG("Char-server '%s': GM Change of the account %d: level 0 -> %d (ip: %s).\n", - server[id].name, acc, - level_new_gm, ip); + PRINTF("GM Change of the account %d: level 0 -> %d.\n"_fmt, + acc, level_new_gm); + LOGIN_LOG("Char-server '%s': GM Change of the account %d: level 0 -> %d (ip: %s).\n"_fmt, + server[id].name, acc, + level_new_gm, ip); } else { - PRINTF("Error of GM change (suggested account: %d, correct password, unable to add a GM account in GM accounts file)\n", - acc); - LOGIN_LOG("Char-server '%s': Error of GM change (suggested account: %d, correct password, unable to add a GM account in GM accounts file, ip: %s).\n", - server[id].name, acc, ip); + PRINTF("Error of GM change (suggested account: %d, correct password, unable to add a GM account in GM accounts file)\n"_fmt, + acc); + LOGIN_LOG("Char-server '%s': Error of GM change (suggested account: %d, correct password, unable to add a GM account in GM accounts file, ip: %s).\n"_fmt, + server[id].name, acc, ip); } } else { - PRINTF("Error of GM change (suggested account: %d, correct password, but GM creation is disable (level_new_gm = 0))\n", - acc); - LOGIN_LOG("Char-server '%s': Error of GM change (suggested account: %d, correct password, but GM creation is disable (level_new_gm = 0), ip: %s).\n", - server[id].name, acc, ip); + PRINTF("Error of GM change (suggested account: %d, correct password, but GM creation is disable (level_new_gm = 0))\n"_fmt, + acc); + LOGIN_LOG("Char-server '%s': Error of GM change (suggested account: %d, correct password, but GM creation is disable (level_new_gm = 0), ip: %s).\n"_fmt, + server[id].name, acc, ip); } } else { - PRINTF("Error of GM change (suggested account: %d (already GM), correct password).\n", - acc); - LOGIN_LOG("Char-server '%s': Error of GM change (suggested account: %d (already GM), correct password, ip: %s).\n", - server[id].name, acc, ip); + PRINTF("Error of GM change (suggested account: %d (already GM), correct password).\n"_fmt, + acc); + LOGIN_LOG("Char-server '%s': Error of GM change (suggested account: %d (already GM), correct password, ip: %s).\n"_fmt, + server[id].name, acc, ip); } } else { - PRINTF("Error of GM change (suggested account: %d, invalid password).\n", - acc); - LOGIN_LOG("Char-server '%s': Error of GM change (suggested account: %d, invalid password, ip: %s).\n", - server[id].name, acc, ip); + PRINTF("Error of GM change (suggested account: %d, invalid password).\n"_fmt, + acc); + LOGIN_LOG("Char-server '%s': Error of GM change (suggested account: %d, invalid password, ip: %s).\n"_fmt, + server[id].name, acc, ip); + } + for (Session *ss : iter_char_sessions()) + { + send_fpacket<0x2721, 10>(ss, fixed_21); } - charif_sendallwos(nullptr, buf, 10); } - RFIFOSKIP(s, RFIFOW(s, 2)); - return; + break; + } // Map server send information to change an email of an account via char-server case 0x2722: // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B - if (RFIFOREST(s) < 86) - return; + { + Packet_Fixed<0x2722> fixed; + rv = recv_fpacket<0x2722, 86>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - int acc = RFIFOL(s, 2); - AccountEmail actual_email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 6).to_print()); - AccountEmail new_email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 46)); + AccountId acc = fixed.account_id; + AccountEmail actual_email = stringish<AccountEmail>(fixed.old_email.to_print()); + AccountEmail new_email = fixed.new_email; if (!e_mail_check(actual_email)) - LOGIN_LOG("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n", - server[id].name, acc, ip); + LOGIN_LOG("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n"_fmt, + server[id].name, acc, ip); else if (!e_mail_check(new_email)) - LOGIN_LOG("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)\n", - server[id].name, acc, ip); + LOGIN_LOG("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)\n"_fmt, + server[id].name, acc, ip); else if (new_email == DEFAULT_EMAIL) - LOGIN_LOG("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n", - server[id].name, acc, ip); + LOGIN_LOG("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n"_fmt, + server[id].name, acc, ip); else { for (AuthData& ad : auth_data) @@ -1259,77 +1247,90 @@ void parse_fromchar(Session *s) if (ad.email == actual_email) { ad.email = new_email; - LOGIN_LOG("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n", - server[id].name, acc, - ad.userid, new_email, ip); + LOGIN_LOG("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n"_fmt, + server[id].name, acc, + ad.userid, new_email, ip); } else - LOGIN_LOG("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n", - server[id].name, acc, - ad.userid, - ad.email, actual_email, ip); + LOGIN_LOG("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n"_fmt, + server[id].name, acc, + ad.userid, + ad.email, actual_email, ip); goto x2722_out; } } - LOGIN_LOG("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n", + LOGIN_LOG("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n"_fmt, server[id].name, acc, ip); } } x2722_out: - RFIFOSKIP(s, 86); break; + } // Receiving of map-server via char-server a status change resquest (by Yor) case 0x2724: - if (RFIFOREST(s) < 10) - return; + { + Packet_Fixed<0x2724> fixed; + rv = recv_fpacket<0x2724, 10>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - int acc, statut; - acc = RFIFOL(s, 2); - statut = RFIFOL(s, 6); + AccountId acc = fixed.account_id; + int statut = fixed.status; for (AuthData& ad : auth_data) { if (ad.account_id == acc) { if (ad.state != statut) { - LOGIN_LOG("Char-server '%s': Status change (account: %d, new status %d, ip: %s).\n", - server[id].name, acc, statut, - ip); + LOGIN_LOG("Char-server '%s': Status change (account: %d, new status %d, ip: %s).\n"_fmt, + server[id].name, acc, statut, + ip); if (statut != 0) { - unsigned char buf[16]; - WBUFW(buf, 0) = 0x2731; - WBUFL(buf, 2) = acc; - WBUFB(buf, 6) = 0; // 0: change of statut, 1: ban - WBUFL(buf, 7) = statut; // status or final date of a banishment - charif_sendallwos(nullptr, buf, 11); + Packet_Fixed<0x2731> fixed_31; + fixed_31.account_id = acc; + fixed_31.ban_not_status = 0; + fixed_31.status_or_ban_until = static_cast<time_t>(statut); + + for (Session *ss : iter_char_sessions()) + { + send_fpacket<0x2731, 11>(ss, fixed_31); + } + for (int j = 0; j < AUTH_FIFO_SIZE; j++) + { if (auth_fifo[j].account_id == acc) auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification) + } } ad.state = statut; } else - LOGIN_LOG("Char-server '%s': Error of Status change - actual status is already the good status (account: %d, status %d, ip: %s).\n", - server[id].name, acc, statut, - ip); + LOGIN_LOG("Char-server '%s': Error of Status change - actual status is already the good status (account: %d, status %d, ip: %s).\n"_fmt, + server[id].name, acc, statut, + ip); goto x2724_out; } } - LOGIN_LOG("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s).\n", + LOGIN_LOG("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s).\n"_fmt, server[id].name, acc, statut, ip); x2724_out: - RFIFOSKIP(s, 10); + ; } - return; + break; + } case 0x2725: // Receiving of map-server via char-server a ban resquest (by Yor) - if (RFIFOREST(s) < 18) - return; + { + Packet_Fixed<0x2725> fixed; + rv = recv_fpacket<0x2725, 18>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - int acc; - acc = RFIFOL(s, 2); + AccountId acc = fixed.account_id; for (AuthData& ad : auth_data) { if (ad.account_id == acc) @@ -1342,8 +1343,7 @@ void parse_fromchar(Session *s) else timestamp = ad.ban_until_time; struct tm tmtime = timestamp; - HumanTimeDiff ban_diff; - RFIFO_STRUCT(s, 6, ban_diff); + HumanTimeDiff ban_diff = fixed.ban_add; tmtime.tm_year += ban_diff.year; tmtime.tm_mon += ban_diff.month; tmtime.tm_mday += ban_diff.day; @@ -1359,137 +1359,170 @@ void parse_fromchar(Session *s) { if (timestamp) { - unsigned char buf[16]; timestamp_seconds_buffer tmpstr; if (timestamp) stamp_time(tmpstr, ×tamp); - LOGIN_LOG("Char-server '%s': Ban request (account: %d, new final date of banishment: %lld (%s), ip: %s).\n", + LOGIN_LOG("Char-server '%s': Ban request (account: %d, new final date of banishment: %lld (%s), ip: %s).\n"_fmt, server[id].name, acc, timestamp, tmpstr, ip); - WBUFW(buf, 0) = 0x2731; - WBUFL(buf, 2) = ad.account_id; - WBUFB(buf, 6) = 1; // 0: change of statut, 1: ban - WBUFL(buf, 7) = static_cast<time_t>(timestamp); // status or final date of a banishment - charif_sendallwos(nullptr, buf, 11); + Packet_Fixed<0x2731> fixed_31; + fixed_31.account_id = ad.account_id; + fixed_31.ban_not_status = 1; + fixed_31.status_or_ban_until = timestamp; + + for (Session *ss : iter_char_sessions()) + { + send_fpacket<0x2731, 11>(ss, fixed_31); + } + for (int j = 0; j < AUTH_FIFO_SIZE; j++) - if (auth_fifo[j].account_id == - acc) + { + if (auth_fifo[j].account_id == acc) auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification) + } } else { - LOGIN_LOG("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n", - server[id].name, acc, - ip); + LOGIN_LOG("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n"_fmt, + server[id].name, acc, + ip); } ad.ban_until_time = timestamp; } else { - LOGIN_LOG("Char-server '%s': Error of ban request (account: %d, no change for ban date, ip: %s).\n", - server[id].name, acc, ip); + LOGIN_LOG("Char-server '%s': Error of ban request (account: %d, no change for ban date, ip: %s).\n"_fmt, + server[id].name, acc, ip); } } else { - LOGIN_LOG("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n", - server[id].name, acc, ip); + LOGIN_LOG("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n"_fmt, + server[id].name, acc, ip); } goto x2725_out; } } - LOGIN_LOG("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n", + LOGIN_LOG("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n"_fmt, server[id].name, acc, ip); x2725_out: - RFIFOSKIP(s, 18); + ; } - return; + break; + } case 0x2727: // Change of sex (sex is reversed) - if (RFIFOREST(s) < 6) - return; + { + Packet_Fixed<0x2727> fixed; + rv = recv_fpacket<0x2727, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - int acc; - acc = RFIFOL(s, 2); + AccountId acc = fixed.account_id; for (AuthData& ad : auth_data) { if (ad.account_id == acc) { { - unsigned char buf[16]; SEX sex; if (ad.sex == SEX::FEMALE) sex = SEX::MALE; else sex = SEX::FEMALE; - LOGIN_LOG("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n", - server[id].name, acc, - sex_to_char(sex), - ip); + LOGIN_LOG("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n"_fmt, + server[id].name, acc, + sex_to_char(sex), + ip); for (int j = 0; j < AUTH_FIFO_SIZE; j++) + { if (auth_fifo[j].account_id == acc) auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification) + } ad.sex = sex; - WBUFW(buf, 0) = 0x2723; - WBUFL(buf, 2) = acc; - WBUFB(buf, 6) = static_cast<uint8_t>(sex); - charif_sendallwos(nullptr, buf, 7); + + Packet_Fixed<0x2723> fixed_23; + fixed_23.account_id = acc; + fixed_23.sex = sex; + + for (Session *ss : iter_char_sessions()) + { + send_fpacket<0x2723, 7>(ss, fixed_23); + } } goto x2727_out; } } - LOGIN_LOG("Char-server '%s': Error of sex change (account: %d not found, sex would be reversed, ip: %s).\n", + LOGIN_LOG("Char-server '%s': Error of sex change (account: %d not found, sex would be reversed, ip: %s).\n"_fmt, server[id].name, acc, ip); x2727_out: - RFIFOSKIP(s, 6); + ; } - return; + break; + } case 0x2728: // We receive account_reg2 from a char-server, and we send them to other char-servers. - if (RFIFOREST(s) < 4 || RFIFOREST(s) < RFIFOW(s, 2)) - return; + { + Packet_Head<0x2728> head; + std::vector<Packet_Repeat<0x2728>> repeat; + rv = recv_vpacket<0x2728, 8, 36>(s, head, repeat); + if (rv != RecvResult::Complete) + break; + { - int acc, p; - acc = RFIFOL(s, 4); + AccountId acc = head.account_id; for (AuthData& ad : auth_data) { if (ad.account_id == acc) { - LOGIN_LOG("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n", - server[id].name, acc, ip); - size_t len = RFIFOW(s, 2); - int j; - for (p = 8, j = 0; - p < len && j < ACCOUNT_REG2_NUM; - p += 36, j++) + LOGIN_LOG("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n"_fmt, + server[id].name, acc, ip); + + const size_t count = std::min(ACCOUNT_REG2_NUM, repeat.size()); + for (size_t j = 0; j < count; ++j) { - ad.account_reg2[j].str = stringish<VarName>(RFIFO_STRING<32>(s, p).to_print()); - ad.account_reg2[j].value = RFIFOL(s, p + 32); + ad.account_reg2[j].str = repeat[j].name; + ad.account_reg2[j].value = repeat[j].value; } - ad.account_reg2_num = j; + ad.account_reg2_num = count; + // Sending information towards the other char-servers. - uint8_t buf[len]; - RFIFO_BUF_CLONE(s, buf, len); - WBUFW(buf, 0) = 0x2729; - charif_sendallwos(s, buf, WBUFW(buf, 2)); -// PRINTF("parse_fromchar: receiving (from the char-server) of account_reg2 (account id: %d).\n", acc); + Packet_Head<0x2729> head_29; + std::vector<Packet_Repeat<0x2729>> repeat_29(repeat.size()); + head_29.account_id = head.account_id; + for (size_t j = 0; j < count; ++j) + { + repeat_29[j].name = repeat[j].name; + repeat_29[j].value = repeat[j].value; + } + + for (Session *ss : iter_char_sessions()) + { + if (ss == s) + continue; + send_vpacket<0x2729, 8, 36>(ss, head_29, repeat_29); + } goto x2728_out; } } - LOGIN_LOG("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", + LOGIN_LOG("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n"_fmt, server[id].name, acc, ip); } x2728_out: - RFIFOSKIP(s, RFIFOW(s, 2)); break; + } case 0x272a: // Receiving of map-server via char-server a unban resquest (by Yor) - if (RFIFOREST(s) < 6) - return; + { + Packet_Fixed<0x272a> fixed; + rv = recv_fpacket<0x272a, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - int acc = RFIFOL(s, 2); + AccountId acc = fixed.account_id; for (AuthData& ad : auth_data) { if (ad.account_id == acc) @@ -1497,32 +1530,37 @@ void parse_fromchar(Session *s) if (ad.ban_until_time) { ad.ban_until_time = TimeT(); - LOGIN_LOG("Char-server '%s': UnBan request (account: %d, ip: %s).\n", - server[id].name, acc, ip); + LOGIN_LOG("Char-server '%s': UnBan request (account: %d, ip: %s).\n"_fmt, + server[id].name, acc, ip); } else { - LOGIN_LOG("Char-server '%s': Error of UnBan request (account: %d, no change for unban date, ip: %s).\n", - server[id].name, acc, ip); + LOGIN_LOG("Char-server '%s': Error of UnBan request (account: %d, no change for unban date, ip: %s).\n"_fmt, + server[id].name, acc, ip); } goto x272a_out; } } - LOGIN_LOG("Char-server '%s': Error of UnBan request (account: %d not found, ip: %s).\n", + LOGIN_LOG("Char-server '%s': Error of UnBan request (account: %d not found, ip: %s).\n"_fmt, server[id].name, acc, ip); x272a_out: - RFIFOSKIP(s, 6); + ; } - return; + break; + } // request from char-server to change account password case 0x2740: // 0x2740 <account_id>.L <actual_password>.24B <new_password>.24B - if (RFIFOREST(s) < 54) - return; + { + Packet_Fixed<0x2740> fixed; + rv = recv_fpacket<0x2740, 54>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - int acc = RFIFOL(s, 2); - AccountPass actual_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 6).to_print()); - AccountPass new_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 30).to_print()); + AccountId acc = fixed.account_id; + AccountPass actual_pass = stringish<AccountPass>(fixed.old_pass.to_print()); + AccountPass new_pass = stringish<AccountPass>(fixed.new_pass.to_print()); int status = 0; @@ -1538,30 +1576,30 @@ void parse_fromchar(Session *s) { status = 1; ad.pass = MD5_saltcrypt(new_pass, make_salt()); - LOGIN_LOG("Char-server '%s': Change pass success (account: %d (%s), ip: %s.\n", - server[id].name, acc, - ad.userid, ip); + LOGIN_LOG("Char-server '%s': Change pass success (account: %d (%s), ip: %s.\n"_fmt, + server[id].name, acc, + ad.userid, ip); } } else { status = 2; - LOGIN_LOG("Char-server '%s': Attempt to modify a pass failed, wrong password. (account: %d (%s), ip: %s).\n", - server[id].name, acc, - ad.userid, ip); + LOGIN_LOG("Char-server '%s': Attempt to modify a pass failed, wrong password. (account: %d (%s), ip: %s).\n"_fmt, + server[id].name, acc, + ad.userid, ip); } goto x2740_out; } } x2740_out: - WFIFOW(s, 0) = 0x2741; - WFIFOL(s, 2) = acc; - WFIFOB(s, 6) = status; // 0: acc not found, 1: success, 2: password mismatch, 3: pass too short - WFIFOSET(s, 7); + Packet_Fixed<0x2741> fixed_41; + fixed_41.account_id = acc; + fixed_41.status = status; + send_fpacket<0x2741, 7>(s, fixed_41); } - RFIFOSKIP(s, 54); break; + } default: { @@ -1571,53 +1609,24 @@ void parse_fromchar(Session *s) timestamp_milliseconds_buffer timestr; stamp_time(timestr); FPRINTF(logfp, - "%s: receiving of an unknown packet -> disconnection\n", - timestr); - FPRINTF(logfp, - "parse_fromchar: connection #%d (ip: %s), packet: 0x%x (with being read: %zu).\n", - s, ip, RFIFOW(s, 0), RFIFOREST(s)); - FPRINTF(logfp, "Detail (in hex):\n"); + "%s: receiving of an unknown packet -> disconnection\n"_fmt, + timestr); FPRINTF(logfp, - "---- 00-01-02-03-04-05-06-07 08-09-0A-0B-0C-0D-0E-0F\n"); - char tmpstr[16 + 1] {}; - int i; - for (i = 0; i < RFIFOREST(s); i++) - { - if ((i & 15) == 0) - FPRINTF(logfp, "%04X ", i); - FPRINTF(logfp, "%02x ", RFIFOB(s, i)); - if (RFIFOB(s, i) > 0x1f) - tmpstr[i % 16] = RFIFOB(s, i); - else - tmpstr[i % 16] = '.'; - if ((i - 7) % 16 == 0) // -8 + 1 - FPRINTF(logfp, " "); - else if ((i + 1) % 16 == 0) - { - FPRINTF(logfp, " %s\n", tmpstr); - std::fill(tmpstr + 0, tmpstr + 17, '\0'); - } - } - if (i % 16 != 0) - { - for (int j = i; j % 16 != 0; j++) - { - FPRINTF(logfp, " "); - if ((j - 7) % 16 == 0) // -8 + 1 - FPRINTF(logfp, " "); - } - FPRINTF(logfp, " %s\n", tmpstr); - } - FPRINTF(logfp, "\n"); + "parse_fromchar: connection #%d (ip: %s), packet: 0x%x (with being read: %zu).\n"_fmt, + s, ip, packet_id, packet_avail(s)); + FPRINTF(logfp, "Detail (in hex):\n"_fmt); + packet_dump(logfp, s); } - } - PRINTF("parse_fromchar: Unknown packet 0x%x (from a char-server)! -> disconnection.\n", - RFIFOW(s, 0)); + PRINTF("parse_fromchar: Unknown packet 0x%x (from a char-server)! -> disconnection.\n"_fmt, + packet_id); s->set_eof(); - PRINTF("Char-server has been disconnected (unknown packet).\n"); + PRINTF("Char-server has been disconnected (unknown packet).\n"_fmt); return; + } } } + if (rv == RecvResult::Error) + s->set_eof(); return; } @@ -1628,112 +1637,136 @@ static void parse_admin(Session *s) { IP4Address ip = s->client_ip; - - while (RFIFOREST(s) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id)) { if (display_parse_admin == 1) - PRINTF("parse_admin: connection #%d, packet: 0x%x (with being read: %zu).\n", - s, RFIFOW(s, 0), RFIFOREST(s)); + PRINTF("parse_admin: connection #%d, packet: 0x%x (with being read: %zu bytes).\n"_fmt, + s, packet_id, packet_avail(s)); - switch (RFIFOW(s, 0)) + switch (packet_id) { case 0x7530: // Request of the server version - LOGIN_LOG("'ladmin': Sending of the server version (ip: %s)\n", - ip); - WFIFOW(s, 0) = 0x7531; - WFIFO_STRUCT(s, 2, CURRENT_LOGIN_SERVER_VERSION); - WFIFOSET(s, 10); - RFIFOSKIP(s, 2); + { + Packet_Fixed<0x7530> fixed; + rv = recv_fpacket<0x7530, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + + LOGIN_LOG("'ladmin': Sending of the server version (ip: %s)\n"_fmt, + ip); + + Packet_Fixed<0x7531> fixed_31; + fixed_31.version = CURRENT_LOGIN_SERVER_VERSION; + send_fpacket<0x7531, 10>(s, fixed_31); break; + } case 0x7532: // Request of end of connection - LOGIN_LOG("'ladmin': End of connection (ip: %s)\n", - ip); - RFIFOSKIP(s, 2); + { + Packet_Fixed<0x7532> fixed; + rv = recv_fpacket<0x7532, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + + LOGIN_LOG("'ladmin': End of connection (ip: %s)\n"_fmt, + ip); s->set_eof(); - break; + return; + } case 0x7920: // Request of an accounts list - if (RFIFOREST(s) < 10) - return; + { + Packet_Fixed<0x7920> fixed; + rv = recv_fpacket<0x7920, 10>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - int st, ed, len; - st = RFIFOL(s, 2); - ed = RFIFOL(s, 6); - RFIFOSKIP(s, 10); - WFIFOW(s, 0) = 0x7921; - if (st < 0) - st = 0; - if (ed > END_ACCOUNT_NUM || ed < st || ed <= 0) + AccountId st = fixed.start_account_id; + AccountId ed = fixed.end_account_id; + if (!(ed < END_ACCOUNT_NUM) || ed < st || !ed) ed = END_ACCOUNT_NUM; - LOGIN_LOG("'ladmin': Sending an accounts list (ask: from %d to %d, ip: %s)\n", - st, ed, ip); + + LOGIN_LOG("'ladmin': Sending an accounts list (ask: from %d to %d, ip: %s)\n"_fmt, + st, ed, ip); + // Sending accounts information - len = 4; + std::vector<Packet_Repeat<0x7921>> repeat_21; + for (const AuthData& ad : auth_data) { - if (len >= 30000) - break; - int account_id = ad.account_id; - if (account_id >= st && account_id <= ed) + AccountId account_id = ad.account_id; + if (!(account_id < st) && !(ed < account_id)) { - WFIFOL(s, len) = account_id; - WFIFOB(s, len + 4) = isGM(account_id); - WFIFO_STRING(s, len + 5, ad.userid, 24); - WFIFOB(s, len + 29) = static_cast<uint8_t>(ad.sex); - WFIFOL(s, len + 30) = ad.logincount; + Packet_Repeat<0x7921> info; + info.account_id = account_id; + info.gm_level = isGM(account_id); + info.account_name = ad.userid; + info.sex = ad.sex; + info.login_count = ad.logincount; if (ad.state == 0 && ad.ban_until_time) // if no state and banished - WFIFOL(s, len + 34) = 7; // 6 = Your are Prohibited to log in until %s + info.status = 7; // 6 = Your are Prohibited to log in until %s else - WFIFOL(s, len + 34) = ad.state; - len += 38; + info.status = ad.state; + repeat_21.push_back(info); } } - WFIFOW(s, 2) = len; - WFIFOSET(s, len); + send_packet_repeatonly<0x7921, 4, 38>(s, repeat_21); } break; + } case 0x7924: { // [Fate] Itemfrob package: change item IDs - if (RFIFOREST(s) < 10) - return; - uint8_t buf[10]; - RFIFO_BUF_CLONE(s, buf, 10); - // forward package to char servers - charif_sendallwos(nullptr, buf, 10); - RFIFOSKIP(s, 10); - WFIFOW(s, 0) = 0x7925; - WFIFOSET(s, 2); + Packet_Fixed<0x7924> fixed; + rv = recv_fpacket<0x7924, 10>(s, fixed); + if (rv != RecvResult::Complete) + break; + + for (Session *ss : iter_char_sessions()) + { + send_fpacket<0x7924, 10>(ss, fixed); + } + + Packet_Fixed<0x7925> fixed_25; + send_fpacket<0x7925, 2>(s, fixed_25); break; } case 0x7930: // Request for an account creation - if (RFIFOREST(s) < 91) - return; + { + Packet_Fixed<0x7930> fixed; + rv = recv_fpacket<0x7930, 91>(s, fixed); + if (rv != RecvResult::Complete) + break; + { struct mmo_account ma; - ma.userid = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); - ma.passwd = stringish<AccountPass>(RFIFO_STRING<24>(s, 26).to_print()); - ma.lastlogin = stringish<timestamp_milliseconds_buffer>("-"); - ma.sex = sex_from_char(RFIFOB(s, 50)); - WFIFOW(s, 0) = 0x7931; - WFIFOL(s, 2) = -1; - WFIFO_STRING(s, 6, ma.userid, 24); + // TODO make this a 'return false' bit of the network_to_native + ma.userid = stringish<AccountName>(fixed.account_name.to_print()); + ma.passwd = stringish<AccountPass>(fixed.password.to_print()); + stamp_time(ma.lastlogin); + ma.sex = fixed.sex; + + Packet_Fixed<0x7931> fixed_31; + fixed_31.account_id = AccountId(); + fixed_31.account_name = ma.userid; if (ma.userid.size() < 4 || ma.passwd.size() < 4) { - LOGIN_LOG("'ladmin': Attempt to create an invalid account (account or pass is too short, ip: %s)\n", - ip); + LOGIN_LOG("'ladmin': Attempt to create an invalid account (account or pass is too short, ip: %s)\n"_fmt, + ip); } else if (ma.sex != SEX::FEMALE && ma.sex != SEX::MALE) { - LOGIN_LOG("'ladmin': Attempt to create an invalid account (account: %s, invalid sex, ip: %s)\n", - ma.userid, ip); + LOGIN_LOG("'ladmin': Attempt to create an invalid account (account: %s, invalid sex, ip: %s)\n"_fmt, + ma.userid, ip); } - else if (account_id_count > END_ACCOUNT_NUM) + else if (!(account_id_count < END_ACCOUNT_NUM)) { - LOGIN_LOG("'ladmin': Attempt to create an account, but there is no more available id number (account: %s, sex: %c, ip: %s)\n", - ma.userid, ma.sex, ip); + LOGIN_LOG("'ladmin': Attempt to create an account, but there is no more available id number (account: %s, sex: %c, ip: %s)\n"_fmt, + ma.userid, sex_to_char(ma.sex), ip); } else { @@ -1741,135 +1774,151 @@ void parse_admin(Session *s) { if (ad.userid == ma.userid) { - LOGIN_LOG("'ladmin': Attempt to create an already existing account (account: %s ip: %s)\n", - ad.userid, ip); + LOGIN_LOG("'ladmin': Attempt to create an already existing account (account: %s ip: %s)\n"_fmt, + ad.userid, ip); goto x7930_out; } } { - AccountEmail email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 51)); - int new_id = mmo_auth_new(&ma, ma.sex, email); - LOGIN_LOG("'ladmin': Account creation (account: %s (id: %d), sex: %c, email: %s, ip: %s)\n", - ma.userid, new_id, - ma.sex, auth_data.back().email, ip); - WFIFOL(s, 2) = new_id; + AccountEmail email = fixed.email; + AccountId new_id = mmo_auth_new(&ma, ma.sex, email); + LOGIN_LOG("'ladmin': Account creation (account: %s (id: %d), sex: %c, email: %s, ip: %s)\n"_fmt, + ma.userid, new_id, + sex_to_char(ma.sex), auth_data.back().email, ip); + fixed_31.account_id = new_id; } } x7930_out: - WFIFOSET(s, 30); - RFIFOSKIP(s, 91); + send_fpacket<0x7931, 30>(s, fixed_31); } break; + } case 0x7932: // Request for an account deletion - if (RFIFOREST(s) < 26) - return; { - WFIFOW(s, 0) = 0x7933; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); + Packet_Fixed<0x7932> fixed; + rv = recv_fpacket<0x7932, 26>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x7933> fixed_33; + fixed_33.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); AuthData *ad = search_account(account_name); if (ad) { // Char-server is notified of deletion (for characters deletion). - uint8_t buf[6]; - WBUFW(buf, 0) = 0x2730; - WBUFL(buf, 2) = ad->account_id; - charif_sendallwos(nullptr, buf, 6); + Packet_Fixed<0x2730> fixed_30; + fixed_30.account_id = ad->account_id; + + for (Session *ss : iter_char_sessions()) + { + send_fpacket<0x2730, 6>(ss, fixed_30); + } + // send answer - WFIFO_STRING(s, 6, ad->userid, 24); - WFIFOL(s, 2) = ad->account_id; + fixed_33.account_name = ad->userid; + fixed_33.account_id = ad->account_id; // save deleted account in log file - LOGIN_LOG("'ladmin': Account deletion (account: %s, id: %d, ip: %s) - saved in next line:\n", - ad->userid, ad->account_id, - ip); + LOGIN_LOG("'ladmin': Account deletion (account: %s, id: %d, ip: %s) - saved in next line:\n"_fmt, + ad->userid, ad->account_id, + ip); { AString buf2 = mmo_auth_tostr(ad); - LOGIN_LOG("%s\n", buf2); + LOGIN_LOG("%s\n"_fmt, buf2); } // delete account ad->userid = AccountName(); - ad->account_id = -1; + ad->account_id = AccountId(); } else { - WFIFO_STRING(s, 6, account_name, 24); - LOGIN_LOG("'ladmin': Attempt to delete an unknown account (account: %s, ip: %s)\n", - account_name, ip); + fixed_33.account_name = account_name; + LOGIN_LOG("'ladmin': Attempt to delete an unknown account (account: %s, ip: %s)\n"_fmt, + account_name, ip); } - WFIFOSET(s, 30); - } - RFIFOSKIP(s, 26); + send_fpacket<0x7933, 30>(s, fixed_33); break; + } case 0x7934: // Request to change a password - if (RFIFOREST(s) < 50) - return; { - WFIFOW(s, 0) = 0x7935; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); + Packet_Fixed<0x7934> fixed; + rv = recv_fpacket<0x7934, 50>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x7935> fixed_35; + fixed_35.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); AuthData *ad = search_account(account_name); if (ad) { - WFIFO_STRING(s, 6, ad->userid, 24); - AccountPass plain = stringish<AccountPass>(RFIFO_STRING<24>(s, 26)); + fixed_35.account_name = ad->userid; + AccountPass plain = stringish<AccountPass>(fixed.password); ad->pass = MD5_saltcrypt(plain, make_salt()); - WFIFOL(s, 2) = ad->account_id; - LOGIN_LOG("'ladmin': Modification of a password (account: %s, new password: %s, ip: %s)\n", - ad->userid, ad->pass, ip); + fixed_35.account_id = ad->account_id; + LOGIN_LOG("'ladmin': Modification of a password (account: %s, new password: %s, ip: %s)\n"_fmt, + ad->userid, ad->pass, ip); } else { - WFIFO_STRING(s, 6, account_name, 24); - LOGIN_LOG("'ladmin': Attempt to modify the password of an unknown account (account: %s, ip: %s)\n", - account_name, ip); + fixed_35.account_name = account_name; + LOGIN_LOG("'ladmin': Attempt to modify the password of an unknown account (account: %s, ip: %s)\n"_fmt, + account_name, ip); } - WFIFOSET(s, 30); - } - RFIFOSKIP(s, 50); + send_fpacket<0x7935, 30>(s, fixed_35); break; + } case 0x7936: // Request to modify a state - if (RFIFOREST(s) < 50) - return; + { + Packet_Fixed<0x7936> fixed; + rv = recv_fpacket<0x7936, 50>(s, fixed); + if (rv != RecvResult::Complete) + break; + { - WFIFOW(s, 0) = 0x7937; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); - int statut = RFIFOL(s, 26); - timestamp_seconds_buffer error_message = stringish<timestamp_seconds_buffer>(RFIFO_STRING<20>(s, 30).to_print()); + Packet_Fixed<0x7937> fixed_37; + fixed_37.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); + int statut = fixed.status; + timestamp_seconds_buffer error_message = stringish<timestamp_seconds_buffer>(fixed.error_message.to_print()); if (statut != 7 || !error_message) { // 7: // 6 = Your are Prohibited to log in until %s - error_message = stringish<timestamp_seconds_buffer>("-"); + error_message = stringish<timestamp_seconds_buffer>("-"_s); } AuthData *ad = search_account(account_name); if (ad) { - WFIFO_STRING(s, 6, ad->userid, 24); - WFIFOL(s, 2) = ad->account_id; + fixed_37.account_name = ad->userid; + fixed_37.account_id = ad->account_id; if (ad->state == statut && ad->error_message == error_message) - LOGIN_LOG("'ladmin': Modification of a state, but the state of the account is already the good state (account: %s, received state: %d, ip: %s)\n", - account_name, statut, ip); + LOGIN_LOG("'ladmin': Modification of a state, but the state of the account is already the good state (account: %s, received state: %d, ip: %s)\n"_fmt, + account_name, statut, ip); else { if (statut == 7) - LOGIN_LOG("'ladmin': Modification of a state (account: %s, new state: %d - prohibited to login until '%s', ip: %s)\n", - ad->userid, statut, - error_message, ip); + LOGIN_LOG("'ladmin': Modification of a state (account: %s, new state: %d - prohibited to login until '%s', ip: %s)\n"_fmt, + ad->userid, statut, + error_message, ip); else - LOGIN_LOG("'ladmin': Modification of a state (account: %s, new state: %d, ip: %s)\n", - ad->userid, statut, ip); + LOGIN_LOG("'ladmin': Modification of a state (account: %s, new state: %d, ip: %s)\n"_fmt, + ad->userid, statut, ip); if (ad->state == 0) { - unsigned char buf[16]; - WBUFW(buf, 0) = 0x2731; - WBUFL(buf, 2) = ad->account_id; - WBUFB(buf, 6) = 0; // 0: change of statut, 1: ban - WBUFL(buf, 7) = statut; // status or final date of a banishment - charif_sendallwos(nullptr, buf, 11); + Packet_Fixed<0x2731> fixed_31; + fixed_31.account_id = ad->account_id; + fixed_31.ban_not_status = 0; + fixed_31.status_or_ban_until = static_cast<time_t>(statut); + + for (Session *ss : iter_char_sessions()) + { + send_fpacket<0x2731, 11>(ss, fixed_31); + } + for (int j = 0; j < AUTH_FIFO_SIZE; j++) if (auth_fifo[j].account_id == ad->account_id) @@ -1881,87 +1930,98 @@ void parse_admin(Session *s) } else { - WFIFO_STRING(s, 6, account_name, 24); - LOGIN_LOG("'ladmin': Attempt to modify the state of an unknown account (account: %s, received state: %d, ip: %s)\n", - account_name, statut, ip); + fixed_37.account_name = account_name; + LOGIN_LOG("'ladmin': Attempt to modify the state of an unknown account (account: %s, received state: %d, ip: %s)\n"_fmt, + account_name, statut, ip); } - WFIFOL(s, 30) = statut; + fixed_37.status = statut; + send_fpacket<0x7937, 34>(s, fixed_37); } - WFIFOSET(s, 34); - RFIFOSKIP(s, 50); break; + } case 0x7938: // Request for servers list and # of online players - LOGIN_LOG("'ladmin': Sending of servers list (ip: %s)\n", ip); - server_num = 0; + { + Packet_Fixed<0x7938> fixed; + rv = recv_fpacket<0x7938, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + + LOGIN_LOG("'ladmin': Sending of servers list (ip: %s)\n"_fmt, ip); + std::vector<Packet_Repeat<0x7939>> repeat_39; for (int i = 0; i < MAX_SERVERS; i++) { if (server_session[i]) { - WFIFOIP(s, 4 + server_num * 32) = server[i].ip; - WFIFOW(s, 4 + server_num * 32 + 4) = server[i].port; - WFIFO_STRING(s, 4 + server_num * 32 + 6, server[i].name, 20); - WFIFOW(s, 4 + server_num * 32 + 26) = server[i].users; - WFIFOW(s, 4 + server_num * 32 + 28) = 0; //maintenance; - WFIFOW(s, 4 + server_num * 32 + 30) = 0; //is_new; - server_num++; + Packet_Repeat<0x7939> info; + info.ip = server[i].ip; + info.port = server[i].port; + info.name = server[i].name; + info.users = server[i].users; + info.maintenance = 0; + info.is_new = 0; + repeat_39.push_back(info); } } - WFIFOW(s, 0) = 0x7939; - WFIFOW(s, 2) = 4 + 32 * server_num; - WFIFOSET(s, 4 + 32 * server_num); - RFIFOSKIP(s, 2); + send_packet_repeatonly<0x7939, 4, 32>(s, repeat_39); break; + } case 0x793a: // Request to password check - if (RFIFOREST(s) < 50) - return; { - WFIFOW(s, 0) = 0x793b; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); + Packet_Fixed<0x793a> fixed; + rv = recv_fpacket<0x793a, 50>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x793b> fixed_3b; + fixed_3b.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); const AuthData *ad = search_account(account_name); if (ad) { - WFIFO_STRING(s, 6, ad->userid, 24); - AccountPass pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 26)); + fixed_3b.account_name = ad->userid; + AccountPass pass = stringish<AccountPass>(fixed.password); if (pass_ok(pass, ad->pass)) { - WFIFOL(s, 2) = ad->account_id; - LOGIN_LOG("'ladmin': Check of password OK (account: %s, password: %s, ip: %s)\n", - ad->userid, ad->pass, - ip); + fixed_3b.account_id = ad->account_id; + LOGIN_LOG("'ladmin': Check of password OK (account: %s, password: %s, ip: %s)\n"_fmt, + ad->userid, ad->pass, + ip); } else { - LOGIN_LOG("'ladmin': Failure of password check (account: %s, proposed pass: %s, ip: %s)\n", - ad->userid, pass.to_print(), ip); + LOGIN_LOG("'ladmin': Failure of password check (account: %s, proposed pass: %s, ip: %s)\n"_fmt, + ad->userid, pass.to_print(), ip); } } else { - WFIFO_STRING(s, 6, account_name, 24); - LOGIN_LOG("'ladmin': Attempt to check the password of an unknown account (account: %s, ip: %s)\n", - account_name, ip); + fixed_3b.account_name = account_name; + LOGIN_LOG("'ladmin': Attempt to check the password of an unknown account (account: %s, ip: %s)\n"_fmt, + account_name, ip); } - WFIFOSET(s, 30); - } - RFIFOSKIP(s, 50); + send_fpacket<0x793b, 30>(s, fixed_3b); break; + } case 0x793c: // Request to modify sex - if (RFIFOREST(s) < 27) - return; { - WFIFOW(s, 0) = 0x793d; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); - WFIFO_STRING(s, 6, account_name, 24); + Packet_Fixed<0x793c> fixed; + rv = recv_fpacket<0x793c, 27>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x793d> fixed_3d; + fixed_3d.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); + fixed_3d.account_name = account_name; + { - SEX sex = sex_from_char(RFIFOB(s, 26)); + SEX sex = fixed.sex; if (sex != SEX::FEMALE && sex != SEX::MALE) { - LOGIN_LOG("'ladmin': Attempt to give an invalid sex (account: %s, received sex: %c, ip: %s)\n", + LOGIN_LOG("'ladmin': Attempt to give an invalid sex (account: %s, received sex: %c, ip: %s)\n"_fmt, account_name, sex_to_char(sex), ip); } else @@ -1969,70 +2029,72 @@ void parse_admin(Session *s) AuthData *ad = search_account(account_name); if (ad) { - WFIFO_STRING(s, 6, ad->userid, 24); + fixed_3d.account_name = ad->userid; if (ad->sex != sex) { - unsigned char buf[16]; - WFIFOL(s, 2) = ad->account_id; + fixed_3d.account_id = ad->account_id; for (int j = 0; j < AUTH_FIFO_SIZE; j++) + { if (auth_fifo[j].account_id == ad->account_id) auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification) + } ad->sex = sex; - LOGIN_LOG("'ladmin': Modification of a sex (account: %s, new sex: %c, ip: %s)\n", - ad->userid, sex_to_char(sex), ip); + LOGIN_LOG("'ladmin': Modification of a sex (account: %s, new sex: %c, ip: %s)\n"_fmt, + ad->userid, sex_to_char(sex), ip); + // send to all char-server the change - WBUFW(buf, 0) = 0x2723; - WBUFL(buf, 2) = ad->account_id; - WBUFB(buf, 6) = static_cast<uint8_t>(ad->sex); - charif_sendallwos(nullptr, buf, 7); + Packet_Fixed<0x2723> fixed_23; + fixed_23.account_id = ad->account_id; + fixed_23.sex = ad->sex; + + for (Session *ss : iter_char_sessions()) + { + send_fpacket<0x2723, 7>(ss, fixed_23); + } } else { - LOGIN_LOG("'ladmin': Modification of a sex, but the sex is already the good sex (account: %s, sex: %c, ip: %s)\n", - ad->userid, sex_to_char(sex), ip); + LOGIN_LOG("'ladmin': Modification of a sex, but the sex is already the good sex (account: %s, sex: %c, ip: %s)\n"_fmt, + ad->userid, sex_to_char(sex), ip); } } else { - LOGIN_LOG("'ladmin': Attempt to modify the sex of an unknown account (account: %s, received sex: %c, ip: %s)\n", - account_name, sex_to_char(sex), ip); + LOGIN_LOG("'ladmin': Attempt to modify the sex of an unknown account (account: %s, received sex: %c, ip: %s)\n"_fmt, + account_name, sex_to_char(sex), ip); } } } - WFIFOSET(s, 30); - } - RFIFOSKIP(s, 27); + send_fpacket<0x793d, 30>(s, fixed_3d); break; + } case 0x793e: // Request to modify GM level - if (RFIFOREST(s) < 27) - return; { - WFIFOW(s, 0) = 0x793f; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); - WFIFO_STRING(s, 6, account_name, 24); + Packet_Fixed<0x793e> fixed; + rv = recv_fpacket<0x793e, 27>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x793f> fixed_3f; + fixed_3f.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); + fixed_3f.account_name = account_name; bool reread = false; { - char new_gm_level; - new_gm_level = RFIFOB(s, 26); - if (new_gm_level < 0 || new_gm_level > 99) - { - LOGIN_LOG("'ladmin': Attempt to give an invalid GM level (account: %s, received GM level: %d, ip: %s)\n", - account_name, new_gm_level, ip); - } - else + GmLevel new_gm_level = fixed.gm_level; { const AuthData *ad = search_account(account_name); if (ad) { - int acc = ad->account_id; - WFIFO_STRING(s, 6, ad->userid, 24); + AccountId acc = ad->account_id; + fixed_3f.account_name = ad->userid; if (isGM(acc) != new_gm_level) { // modification of the file - int GM_account, GM_level; + AccountId GM_account; + GmLevel GM_level; int modify_flag; io::WriteLock fp2(gm_account_filename); if (fp2.is_open()) @@ -2055,68 +2117,68 @@ void parse_admin(Session *s) fp2.put_line(line); else if (GM_account != acc) fp2.put_line(line); - else if (new_gm_level == 0) + else if (!new_gm_level) { FPRINTF(fp2, - "// %s: 'ladmin' GM level removed on account %d '%s' (previous level: %d)\n//%d %d\n", - tmpstr, - acc, - ad->userid, - GM_level, acc, - new_gm_level); + "// %s: 'ladmin' GM level removed on account %d '%s' (previous level: %d)\n//%d %d\n"_fmt, + tmpstr, + acc, + ad->userid, + GM_level, acc, + new_gm_level); modify_flag = 1; } else { FPRINTF(fp2, - "// %s: 'ladmin' GM level on account %d '%s' (previous level: %d)\n%d %d\n", - tmpstr, - acc, - ad->userid, - GM_level, acc, - new_gm_level); + "// %s: 'ladmin' GM level on account %d '%s' (previous level: %d)\n%d %d\n"_fmt, + tmpstr, + acc, + ad->userid, + GM_level, acc, + new_gm_level); modify_flag = 1; } } } if (modify_flag == 0) FPRINTF(fp2, - "// %s: 'ladmin' GM level on account %d '%s' (previous level: 0)\n%d %d\n", - tmpstr, acc, - ad->userid, acc, - new_gm_level); + "// %s: 'ladmin' GM level on account %d '%s' (previous level: 0)\n%d %d\n"_fmt, + tmpstr, acc, + ad->userid, acc, + new_gm_level); } else { - LOGIN_LOG("'ladmin': Attempt to modify of a GM level - impossible to read GM accounts file (account: %s (%d), received GM level: %d, ip: %s)\n", - ad->userid, acc, - new_gm_level, ip); + LOGIN_LOG("'ladmin': Attempt to modify of a GM level - impossible to read GM accounts file (account: %s (%d), received GM level: %d, ip: %s)\n"_fmt, + ad->userid, acc, + new_gm_level, ip); } - WFIFOL(s, 2) = acc; - LOGIN_LOG("'ladmin': Modification of a GM level (account: %s (%d), new GM level: %d, ip: %s)\n", - ad->userid, acc, - new_gm_level, ip); + fixed_3f.account_id = acc; + LOGIN_LOG("'ladmin': Modification of a GM level (account: %s (%d), new GM level: %d, ip: %s)\n"_fmt, + ad->userid, acc, + new_gm_level, ip); reread = true; } else { - LOGIN_LOG("'ladmin': Attempt to modify of a GM level - impossible to write GM accounts file (account: %s (%d), received GM level: %d, ip: %s)\n", - ad->userid, acc, - new_gm_level, ip); + LOGIN_LOG("'ladmin': Attempt to modify of a GM level - impossible to write GM accounts file (account: %s (%d), received GM level: %d, ip: %s)\n"_fmt, + ad->userid, acc, + new_gm_level, ip); } } else { - LOGIN_LOG("'ladmin': Attempt to modify of a GM level, but the GM level is already the good GM level (account: %s (%d), GM level: %d, ip: %s)\n", - ad->userid, acc, - new_gm_level, ip); + LOGIN_LOG("'ladmin': Attempt to modify of a GM level, but the GM level is already the good GM level (account: %s (%d), GM level: %d, ip: %s)\n"_fmt, + ad->userid, acc, + new_gm_level, ip); } } else { - LOGIN_LOG("'ladmin': Attempt to modify the GM level of an unknown account (account: %s, received GM level: %d, ip: %s)\n", - account_name, new_gm_level, - ip); + LOGIN_LOG("'ladmin': Attempt to modify the GM level of an unknown account (account: %s, received GM level: %d, ip: %s)\n"_fmt, + account_name, new_gm_level, + ip); } } } @@ -2126,199 +2188,213 @@ void parse_admin(Session *s) read_gm_account(); send_GM_accounts(); } - WFIFOSET(s, 30); - } - RFIFOSKIP(s, 27); + send_fpacket<0x793f, 30>(s, fixed_3f); break; + } case 0x7940: // Request to modify e-mail - if (RFIFOREST(s) < 66) - return; { - WFIFOW(s, 0) = 0x7941; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); - WFIFO_STRING(s, 6, account_name, 24); + Packet_Fixed<0x7940> fixed; + rv = recv_fpacket<0x7940, 66>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x7941> fixed_41; + fixed_41.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); + fixed_41.account_name = account_name; { - AccountEmail email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 26)); + AccountEmail email = stringish<AccountEmail>(fixed.email); if (!e_mail_check(email)) { - LOGIN_LOG("'ladmin': Attempt to give an invalid e-mail (account: %s, ip: %s)\n", - account_name, ip); + LOGIN_LOG("'ladmin': Attempt to give an invalid e-mail (account: %s, ip: %s)\n"_fmt, + account_name, ip); } else { AuthData *ad = search_account(account_name); if (ad) { - WFIFO_STRING(s, 6, ad->userid, 24); + fixed_41.account_name = ad->userid; ad->email = email; - WFIFOL(s, 2) = ad->account_id; - LOGIN_LOG("'ladmin': Modification of an email (account: %s, new e-mail: %s, ip: %s)\n", - ad->userid, email, ip); + fixed_41.account_id = ad->account_id; + LOGIN_LOG("'ladmin': Modification of an email (account: %s, new e-mail: %s, ip: %s)\n"_fmt, + ad->userid, email, ip); } else { - LOGIN_LOG("'ladmin': Attempt to modify the e-mail of an unknown account (account: %s, received e-mail: %s, ip: %s)\n", - account_name, email, ip); + LOGIN_LOG("'ladmin': Attempt to modify the e-mail of an unknown account (account: %s, received e-mail: %s, ip: %s)\n"_fmt, + account_name, email, ip); } } } - WFIFOSET(s, 30); - } - RFIFOSKIP(s, 66); + send_fpacket<0x7941, 30>(s, fixed_41); break; + } case 0x7942: // Request to modify memo field - if (RFIFOREST(s) < 28 - || RFIFOREST(s) < (28 + RFIFOW(s, 26))) - return; { - WFIFOW(s, 0) = 0x7943; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); + Packet_Head<0x7942> head; + AString repeat; + rv = recv_vpacket<0x7942, 28, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x7943> fixed_43; + fixed_43.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(head.account_name.to_print()); AuthData *ad = search_account(account_name); if (ad) { - WFIFO_STRING(s, 6, ad->userid, 24); - ad->memo = ""; - if (RFIFOW(s, 26) == 0) + fixed_43.account_name = ad->userid; + ad->memo = ""_s; + if (!repeat/*.startswith('!')*/) { - ad->memo = "!"; + ad->memo = "!"_s; } else { - size_t len = RFIFOW(s, 26); // may truncate - ad->memo = RFIFO_STRING(s, 28, len); + ad->memo = repeat; } ad->memo = ad->memo.to_print(); - WFIFOL(s, 2) = ad->account_id; - LOGIN_LOG("'ladmin': Modification of a memo field (account: %s, new memo: %s, ip: %s)\n", - ad->userid, ad->memo, ip); + fixed_43.account_id = ad->account_id; + LOGIN_LOG("'ladmin': Modification of a memo field (account: %s, new memo: %s, ip: %s)\n"_fmt, + ad->userid, ad->memo, ip); } else { - WFIFO_STRING(s, 6, account_name, 24); - LOGIN_LOG("'ladmin': Attempt to modify the memo field of an unknown account (account: %s, ip: %s)\n", - account_name, ip); + fixed_43.account_name = account_name; + LOGIN_LOG("'ladmin': Attempt to modify the memo field of an unknown account (account: %s, ip: %s)\n"_fmt, + account_name, ip); } - WFIFOSET(s, 30); - } - RFIFOSKIP(s, 28 + RFIFOW(s, 26)); + send_fpacket<0x7943, 30>(s, fixed_43); break; + } case 0x7944: // Request to found an account id - if (RFIFOREST(s) < 26) - return; { - WFIFOW(s, 0) = 0x7945; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); + Packet_Fixed<0x7944> fixed; + rv = recv_fpacket<0x7944, 26>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x7945> fixed_45; + fixed_45.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); const AuthData *ad = search_account(account_name); if (ad) { - WFIFO_STRING(s, 6, ad->userid, 24); - WFIFOL(s, 2) = ad->account_id; - LOGIN_LOG("'ladmin': Request (by the name) of an account id (account: %s, id: %d, ip: %s)\n", + fixed_45.account_name = ad->userid; + fixed_45.account_id = ad->account_id; + LOGIN_LOG("'ladmin': Request (by the name) of an account id (account: %s, id: %d, ip: %s)\n"_fmt, ad->userid, ad->account_id, ip); } else { - WFIFO_STRING(s, 6, account_name, 24); - LOGIN_LOG("'ladmin': ID request (by the name) of an unknown account (account: %s, ip: %s)\n", + fixed_45.account_name = account_name; + LOGIN_LOG("'ladmin': ID request (by the name) of an unknown account (account: %s, ip: %s)\n"_fmt, account_name, ip); } - WFIFOSET(s, 30); - } - RFIFOSKIP(s, 26); + send_fpacket<0x7945, 30>(s, fixed_45); break; + } case 0x7946: // Request to found an account name - if (RFIFOREST(s) < 6) - return; { - int account_id = RFIFOL(s, 2); - WFIFOW(s, 0) = 0x7947; - WFIFOL(s, 2) = account_id; - WFIFO_ZERO(s, 6, 24); + Packet_Fixed<0x7946> fixed; + rv = recv_fpacket<0x7946, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + Packet_Fixed<0x7947> fixed_47; + fixed_47.account_id = account_id; + fixed_47.account_name = {}; for (const AuthData& ad : auth_data) { if (ad.account_id == account_id) { - WFIFO_STRING(s, 6, ad.userid, 24); - LOGIN_LOG("'ladmin': Request (by id) of an account name (account: %s, id: %d, ip: %s)\n", + fixed_47.account_name = ad.userid; + LOGIN_LOG("'ladmin': Request (by id) of an account name (account: %s, id: %d, ip: %s)\n"_fmt, ad.userid, account_id, ip); goto x7946_out; } } - LOGIN_LOG("'ladmin': Name request (by id) of an unknown account (id: %d, ip: %s)\n", + LOGIN_LOG("'ladmin': Name request (by id) of an unknown account (id: %d, ip: %s)\n"_fmt, account_id, ip); - WFIFO_STRING(s, 6, "", 24); + fixed_47.account_name = stringish<AccountName>(""_s); x7946_out: - WFIFOSET(s, 30); - } - RFIFOSKIP(s, 6); + send_fpacket<0x7947, 30>(s, fixed_47); break; + } case 0x7948: // Request to change the validity limit (timestamp) (absolute value) - if (RFIFOREST(s) < 30) - return; + { + Packet_Fixed<0x7948> fixed; + rv = recv_fpacket<0x7948, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x7949> fixed_49; { - WFIFOW(s, 0) = 0x7949; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); - TimeT timestamp = static_cast<time_t>(RFIFOL(s, 26)); - timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("unlimited"); + fixed_49.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); + TimeT timestamp = fixed.valid_until; + timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("unlimited"_s); if (timestamp) stamp_time(tmpstr, ×tamp); AuthData *ad = search_account(account_name); if (ad) { - WFIFO_STRING(s, 6, ad->userid, 24); - LOGIN_LOG("'ladmin': Change of a validity limit (account: %s, new validity: %lld (%s), ip: %s)\n", + fixed_49.account_name = ad->userid; + LOGIN_LOG("'ladmin': Change of a validity limit (account: %s, new validity: %lld (%s), ip: %s)\n"_fmt, ad->userid, timestamp, tmpstr, ip); ad->connect_until_time = timestamp; - WFIFOL(s, 2) = ad->account_id; + fixed_49.account_id = ad->account_id; } else { - WFIFO_STRING(s, 6, account_name, 24); - LOGIN_LOG("'ladmin': Attempt to change the validity limit of an unknown account (account: %s, received validity: %lld (%s), ip: %s)\n", + fixed_49.account_name = account_name; + LOGIN_LOG("'ladmin': Attempt to change the validity limit of an unknown account (account: %s, received validity: %lld (%s), ip: %s)\n"_fmt, account_name, timestamp, tmpstr, ip); } - WFIFOL(s, 30) = static_cast<time_t>(timestamp); + fixed_49.valid_until = timestamp; } - WFIFOSET(s, 34); - RFIFOSKIP(s, 30); + send_fpacket<0x7949, 34>(s, fixed_49); break; + } case 0x794a: // Request to change the final date of a banishment (timestamp) (absolute value) - if (RFIFOREST(s) < 30) - return; + { + Packet_Fixed<0x794a> fixed; + rv = recv_fpacket<0x794a, 30>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x794b> fixed_4b; { - WFIFOW(s, 0) = 0x794b; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); - TimeT timestamp = static_cast<time_t>(RFIFOL(s, 26)); + fixed_4b.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); + TimeT timestamp = fixed.ban_until; if (timestamp <= TimeT::now()) timestamp = TimeT(); - timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("no banishment"); + timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("no banishment"_s); if (timestamp) stamp_time(tmpstr, ×tamp); AuthData *ad = search_account(account_name); if (ad) { - WFIFO_STRING(s, 6, ad->userid, 24); - WFIFOL(s, 2) = ad->account_id; - LOGIN_LOG("'ladmin': Change of the final date of a banishment (account: %s, new final date of banishment: %lld (%s), ip: %s)\n", + fixed_4b.account_name = ad->userid; + fixed_4b.account_id = ad->account_id; + LOGIN_LOG("'ladmin': Change of the final date of a banishment (account: %s, new final date of banishment: %lld (%s), ip: %s)\n"_fmt, ad->userid, timestamp, tmpstr, ip); @@ -2326,46 +2402,56 @@ void parse_admin(Session *s) { if (timestamp) { - unsigned char buf[16]; - WBUFW(buf, 0) = 0x2731; - WBUFL(buf, 2) = ad->account_id; - WBUFB(buf, 6) = 1; // 0: change of statut, 1: ban - WBUFL(buf, 7) = static_cast<time_t>(timestamp); // status or final date of a banishment - charif_sendallwos(nullptr, buf, 11); + Packet_Fixed<0x2731> fixed_31; + fixed_31.account_id = ad->account_id; + fixed_31.ban_not_status = 1; + fixed_31.status_or_ban_until = timestamp; + + for (Session *ss : iter_char_sessions()) + { + send_fpacket<0x2731, 11>(ss, fixed_31); + } + for (int j = 0; j < AUTH_FIFO_SIZE; j++) + { if (auth_fifo[j].account_id == ad->account_id) auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification) + } } ad->ban_until_time = timestamp; } } else { - WFIFO_STRING(s, 6, account_name, 24); - LOGIN_LOG("'ladmin': Attempt to change the final date of a banishment of an unknown account (account: %s, received final date of banishment: %lld (%s), ip: %s)\n", + fixed_4b.account_name = account_name; + LOGIN_LOG("'ladmin': Attempt to change the final date of a banishment of an unknown account (account: %s, received final date of banishment: %lld (%s), ip: %s)\n"_fmt, account_name, timestamp, tmpstr, ip); } - WFIFOL(s, 30) = static_cast<time_t>(timestamp); + fixed_4b.ban_until = timestamp; } - WFIFOSET(s, 34); - RFIFOSKIP(s, 30); + send_fpacket<0x794b, 34>(s, fixed_4b); break; + } case 0x794c: // Request to change the final date of a banishment (timestamp) (relative change) - if (RFIFOREST(s) < 38) - return; + { + Packet_Fixed<0x794c> fixed; + rv = recv_fpacket<0x794c, 38>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x794d> fixed_4d; { - WFIFOW(s, 0) = 0x794d; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); + fixed_4d.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); AuthData *ad = search_account(account_name); if (ad) { - WFIFOL(s, 2) = ad->account_id; - WFIFO_STRING(s, 6, ad->userid, 24); + fixed_4d.account_id = ad->account_id; + fixed_4d.account_name = ad->userid; TimeT timestamp; TimeT now = TimeT::now(); if (!ad->ban_until_time @@ -2374,8 +2460,7 @@ void parse_admin(Session *s) else timestamp = ad->ban_until_time; struct tm tmtime = timestamp; - HumanTimeDiff ban_diff; - RFIFO_STRUCT(s, 26, ban_diff); + HumanTimeDiff ban_diff = fixed.ban_add; tmtime.tm_year += ban_diff.year; tmtime.tm_mon += ban_diff.month; tmtime.tm_mday += ban_diff.day; @@ -2387,10 +2472,10 @@ void parse_admin(Session *s) { if (timestamp <= now) timestamp = TimeT(); - timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("no banishment"); + timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("no banishment"_s); if (timestamp) stamp_time(tmpstr, ×tamp); - LOGIN_LOG("'ladmin': Adjustment of a final date of a banishment (account: %s, (%+d y %+d m %+d d %+d h %+d mn %+d s) -> new validity: %lld (%s), ip: %s)\n", + LOGIN_LOG("'ladmin': Adjustment of a final date of a banishment (account: %s, (%+d y %+d m %+d d %+d h %+d mn %+d s) -> new validity: %lld (%s), ip: %s)\n"_fmt, ad->userid, ban_diff.year, ban_diff.month, ban_diff.day, ban_diff.hour, @@ -2402,26 +2487,32 @@ void parse_admin(Session *s) { if (timestamp) { - unsigned char buf[16]; - WBUFW(buf, 0) = 0x2731; - WBUFL(buf, 2) = ad->account_id; - WBUFB(buf, 6) = 1; // 0: change of statut, 1: ban - WBUFL(buf, 7) = static_cast<time_t>(timestamp); // status or final date of a banishment - charif_sendallwos(nullptr, buf, 11); + Packet_Fixed<0x2731> fixed_31; + fixed_31.account_id = ad->account_id; + fixed_31.ban_not_status = 1; + fixed_31.status_or_ban_until = timestamp; + + for (Session *ss : iter_char_sessions()) + { + send_fpacket<0x2731, 11>(ss, fixed_31); + } + for (int j = 0; j < AUTH_FIFO_SIZE; j++) + { if (auth_fifo[j].account_id == ad->account_id) auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification) + } } ad->ban_until_time = timestamp; } } else { - timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("no banishment"); + timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("no banishment"_s); if (ad->ban_until_time) stamp_time(tmpstr, &ad->ban_until_time); - LOGIN_LOG("'ladmin': Impossible to adjust the final date of a banishment (account: %s, %lld (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> ???, ip: %s)\n", + LOGIN_LOG("'ladmin': Impossible to adjust the final date of a banishment (account: %s, %lld (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> ???, ip: %s)\n"_fmt, ad->userid, ad->ban_until_time, tmpstr, @@ -2430,30 +2521,34 @@ void parse_admin(Session *s) ban_diff.minute, ban_diff.second, ip); } - WFIFOL(s, 30) = static_cast<time_t>(ad->ban_until_time); + fixed_4d.ban_until = ad->ban_until_time; } else { - WFIFO_STRING(s, 6, account_name, 24); - LOGIN_LOG("'ladmin': Attempt to adjust the final date of a banishment of an unknown account (account: %s, ip: %s)\n", + fixed_4d.account_name = account_name; + LOGIN_LOG("'ladmin': Attempt to adjust the final date of a banishment of an unknown account (account: %s, ip: %s)\n"_fmt, account_name, ip); - WFIFOL(s, 30) = 0; + fixed_4d.ban_until = TimeT(); } } - WFIFOSET(s, 34); - RFIFOSKIP(s, 38); + send_fpacket<0x794d, 34>(s, fixed_4d); break; + } case 0x794e: // Request to send a broadcast message - if (RFIFOREST(s) < 8 - || RFIFOREST(s) < (8 + RFIFOL(s, 4))) - return; - WFIFOW(s, 0) = 0x794f; - WFIFOW(s, 2) = -1; - if (RFIFOL(s, 4) < 1) + { + Packet_Head<0x794e> head; + AString repeat; + rv = recv_vpacket<0x794e, 8, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x794f> fixed_4f; + fixed_4f.error = -1; + if (!repeat) { - LOGIN_LOG("'ladmin': Receiving a message for broadcast, but message is void (ip: %s)\n", - ip); + LOGIN_LOG("'ladmin': Receiving a message for broadcast, but message is void (ip: %s)\n"_fmt, + ip); } else { @@ -2461,47 +2556,54 @@ void parse_admin(Session *s) for (int i = 0; i < MAX_SERVERS; i++) if (server_session[i]) goto x794e_have_server; - LOGIN_LOG("'ladmin': Receiving a message for broadcast, but no char-server is online (ip: %s)\n", + LOGIN_LOG("'ladmin': Receiving a message for broadcast, but no char-server is online (ip: %s)\n"_fmt, ip); goto x794e_have_no_server; { x794e_have_server: // overwrite the -1 - WFIFOW(s, 2) = 0; + fixed_4f.error = 0; - size_t len = RFIFOL(s, 4); - AString message = RFIFO_STRING(s, 8, len).to_print(); - LOGIN_LOG("'ladmin': Receiving a message for broadcast (message: %s, ip: %s)\n", + AString& message = repeat; + LOGIN_LOG("'ladmin': Receiving a message for broadcast (message: %s, ip: %s)\n"_fmt, message, ip); + // send same message to all char-servers (no answer) - uint8_t buf[len + 8]; - RFIFO_BUF_CLONE(s, buf, 8 + len); - WBUFW(buf, 0) = 0x2726; - charif_sendallwos(nullptr, buf, 8 + len); + Packet_Head<0x2726> head_26; + head_26.unused = head.unused; + + for (Session *ss : iter_char_sessions()) + { + send_vpacket<0x2726, 8, 1>(ss, head_26, message); + } } } x794e_have_no_server: - WFIFOSET(s, 4); - RFIFOSKIP(s, 8 + RFIFOL(s, 4)); + send_fpacket<0x794f, 4>(s, fixed_4f); break; + } case 0x7950: // Request to change the validity limite (timestamp) (relative change) - if (RFIFOREST(s) < 38) - return; + { + Packet_Fixed<0x7950> fixed; + rv = recv_fpacket<0x7950, 38>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x7951> fixed_51; { - WFIFOW(s, 0) = 0x7951; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); + fixed_51.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); AuthData *ad = search_account(account_name); if (ad) { - WFIFOL(s, 2) = ad->account_id; - WFIFO_STRING(s, 6, ad->userid, 24); + fixed_51.account_id = ad->account_id; + fixed_51.account_name = ad->userid; if (add_to_unlimited_account == 0 && !ad->connect_until_time) { - LOGIN_LOG("'ladmin': Attempt to adjust the validity limit of an unlimited account (account: %s, ip: %s)\n", - ad->userid, ip); - WFIFOL(s, 30) = 0; + LOGIN_LOG("'ladmin': Attempt to adjust the validity limit of an unlimited account (account: %s, ip: %s)\n"_fmt, + ad->userid, ip); + fixed_51.valid_until = TimeT(); } else { @@ -2510,8 +2612,7 @@ void parse_admin(Session *s) if (!timestamp || timestamp < now) timestamp = now; struct tm tmtime = timestamp; - HumanTimeDiff v_diff; - RFIFO_STRUCT(s, 26, v_diff); + HumanTimeDiff v_diff = fixed.valid_add; tmtime.tm_year += v_diff.year; tmtime.tm_mon += v_diff.month; tmtime.tm_mday += v_diff.day; @@ -2521,13 +2622,13 @@ void parse_admin(Session *s) timestamp = tmtime; if (timestamp.okay()) { - timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("unlimited"); - timestamp_seconds_buffer tmpstr2 = stringish<timestamp_seconds_buffer>("unlimited"); + timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("unlimited"_s); + timestamp_seconds_buffer tmpstr2 = stringish<timestamp_seconds_buffer>("unlimited"_s); if (ad->connect_until_time) stamp_time(tmpstr, &ad->connect_until_time); if (timestamp) stamp_time(tmpstr2, ×tamp); - LOGIN_LOG("'ladmin': Adjustment of a validity limit (account: %s, %lld (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> new validity: %lld (%s), ip: %s)\n", + LOGIN_LOG("'ladmin': Adjustment of a validity limit (account: %s, %lld (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> new validity: %lld (%s), ip: %s)\n"_fmt, ad->userid, ad->connect_until_time, tmpstr, @@ -2541,14 +2642,14 @@ void parse_admin(Session *s) tmpstr2, ip); ad->connect_until_time = timestamp; - WFIFOL(s, 30) = static_cast<time_t>(timestamp); + fixed_51.valid_until = timestamp; } else { - timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("unlimited"); + timestamp_seconds_buffer tmpstr = stringish<timestamp_seconds_buffer>("unlimited"_s); if (ad->connect_until_time) stamp_time(tmpstr, &ad->connect_until_time); - LOGIN_LOG("'ladmin': Impossible to adjust a validity limit (account: %s, %lld (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> ???, ip: %s)\n", + LOGIN_LOG("'ladmin': Impossible to adjust a validity limit (account: %s, %lld (%s) + (%+d y %+d m %+d d %+d h %+d mn %+d s) -> ???, ip: %s)\n"_fmt, ad->userid, ad->connect_until_time, tmpstr, @@ -2559,116 +2660,122 @@ void parse_admin(Session *s) v_diff.minute, v_diff.second, ip); - WFIFOL(s, 30) = 0; + fixed_51.valid_until = TimeT(); } } } else { - WFIFO_STRING(s, 6, account_name, 24); - LOGIN_LOG("'ladmin': Attempt to adjust the validity limit of an unknown account (account: %s, ip: %s)\n", - account_name, ip); - WFIFOL(s, 30) = 0; + fixed_51.account_name = account_name; + LOGIN_LOG("'ladmin': Attempt to adjust the validity limit of an unknown account (account: %s, ip: %s)\n"_fmt, + account_name, ip); + fixed_51.valid_until = TimeT(); } } - WFIFOSET(s, 34); - RFIFOSKIP(s, 38); + send_fpacket<0x7951, 34>(s, fixed_51); break; + } case 0x7952: // Request about informations of an account (by account name) - if (RFIFOREST(s) < 26) - return; { - WFIFOW(s, 0) = 0x7953; - WFIFOL(s, 2) = -1; - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); + Packet_Fixed<0x7952> fixed; + rv = recv_fpacket<0x7952, 26>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Head<0x7953> head_53; + head_53.account_id = AccountId(); + AccountName account_name = stringish<AccountName>(fixed.account_name.to_print()); const AuthData *ad = search_account(account_name); if (ad) { - WFIFOL(s, 2) = ad->account_id; - WFIFOB(s, 6) = isGM(ad->account_id); - WFIFO_STRING(s, 7, ad->userid, 24); - WFIFOB(s, 31) = static_cast<uint8_t>(ad->sex); - WFIFOL(s, 32) = ad->logincount; - WFIFOL(s, 36) = ad->state; - WFIFO_STRING(s, 40, ad->error_message, 20); - WFIFO_STRING(s, 60, ad->lastlogin, 24); - WFIFO_STRING(s, 84, convert_for_printf(ad->last_ip), 16); - WFIFO_STRING(s, 100, ad->email, 40); - WFIFOL(s, 140) = static_cast<time_t>(ad->connect_until_time); - WFIFOL(s, 144) = static_cast<time_t>(ad->ban_until_time); - size_t len = ad->memo.size() + 1; - WFIFOW(s, 148) = len; - WFIFO_STRING(s, 150, ad->memo, len); - LOGIN_LOG("'ladmin': Sending information of an account (request by the name; account: %s, id: %d, ip: %s)\n", - ad->userid, ad->account_id, - ip); - WFIFOSET(s, 150 + len); + head_53.account_id = ad->account_id; + head_53.gm_level = isGM(ad->account_id); + head_53.account_name = ad->userid; + head_53.sex = ad->sex; + head_53.login_count = ad->logincount; + head_53.state = ad->state; + head_53.error_message = ad->error_message; + head_53.last_login_string = ad->lastlogin; + head_53.ip_string = convert_for_printf(ad->last_ip); + head_53.email = ad->email; + head_53.connect_until = ad->connect_until_time; + head_53.ban_until = ad->ban_until_time; + + XString repeat_53 = ad->memo; + LOGIN_LOG("'ladmin': Sending information of an account (request by the name; account: %s, id: %d, ip: %s)\n"_fmt, + ad->userid, ad->account_id, + ip); + + send_vpacket<0x7953, 150, 1>(s, head_53, repeat_53); } else { - WFIFO_STRING(s, 7, account_name, 24); - WFIFOW(s, 148) = 0; - LOGIN_LOG("'ladmin': Attempt to obtain information (by the name) of an unknown account (account: %s, ip: %s)\n", - account_name, ip); - WFIFOSET(s, 150); + head_53.account_name = account_name; + LOGIN_LOG("'ladmin': Attempt to obtain information (by the name) of an unknown account (account: %s, ip: %s)\n"_fmt, + account_name, ip); + send_vpacket<0x7953, 150, 1>(s, head_53, ""_s); } - } - RFIFOSKIP(s, 26); break; + } case 0x7954: // Request about information of an account (by account id) - if (RFIFOREST(s) < 6) - return; { - int account_id = RFIFOL(s, 2); - WFIFOW(s, 0) = 0x7953; - WFIFOL(s, 2) = account_id; - WFIFO_ZERO(s, 7, 24); + Packet_Fixed<0x7954> fixed; + rv = recv_fpacket<0x7954, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + + AccountId account_id = fixed.account_id; + Packet_Head<0x7953> head_53; + head_53.account_id = account_id; + head_53.account_name = AccountName(); for (const AuthData& ad : auth_data) { if (ad.account_id == account_id) { - LOGIN_LOG("'ladmin': Sending information of an account (request by the id; account: %s, id: %d, ip: %s)\n", - ad.userid, RFIFOL(s, 2), ip); - WFIFOB(s, 6) = isGM(ad.account_id); - WFIFO_STRING(s, 7, ad.userid, 24); - WFIFOB(s, 31) = static_cast<uint8_t>(ad.sex); - WFIFOL(s, 32) = ad.logincount; - WFIFOL(s, 36) = ad.state; - WFIFO_STRING(s, 40, ad.error_message, 20); - WFIFO_STRING(s, 60, ad.lastlogin, 24); - WFIFO_STRING(s, 84, convert_for_printf(ad.last_ip), 16); - WFIFO_STRING(s, 100, ad.email, 40); - WFIFOL(s, 140) = static_cast<time_t>(ad.connect_until_time); - WFIFOL(s, 144) = static_cast<time_t>(ad.ban_until_time); - size_t len = ad.memo.size() + 1; - WFIFOW(s, 148) = len; - WFIFO_STRING(s, 150, ad.memo, len); - WFIFOSET(s, 150 + len); + LOGIN_LOG("'ladmin': Sending information of an account (request by the id; account: %s, id: %d, ip: %s)\n"_fmt, + ad.userid, account_id, ip); + head_53.gm_level = isGM(ad.account_id); + head_53.account_name = ad.userid; + head_53.sex = ad.sex; + head_53.login_count = ad.logincount; + head_53.state = ad.state; + head_53.error_message = ad.error_message; + head_53.last_login_string = ad.lastlogin; + head_53.ip_string = convert_for_printf(ad.last_ip); + head_53.email = ad.email; + head_53.connect_until = ad.connect_until_time; + head_53.ban_until = ad.ban_until_time; + XString repeat_53 = ad.memo; + send_vpacket<0x7953, 150, 1>(s, head_53, repeat_53); goto x7954_out; } } { - LOGIN_LOG("'ladmin': Attempt to obtain information (by the id) of an unknown account (id: %d, ip: %s)\n", - RFIFOL(s, 2), ip); - WFIFO_STRING(s, 7, "", 24); - WFIFOW(s, 148) = 0; - WFIFOSET(s, 150); + LOGIN_LOG("'ladmin': Attempt to obtain information (by the id) of an unknown account (id: %d, ip: %s)\n"_fmt, + account_id, ip); + head_53.account_name = stringish<AccountName>(""_s); + send_vpacket<0x7953, 150, 1>(s, head_53, ""_s); } - } x7954_out: - RFIFOSKIP(s, 6); break; + } case 0x7955: // Request to reload GM file (no answer) - LOGIN_LOG("'ladmin': Request to re-load GM configuration file (ip: %s).\n", - ip); + { + Packet_Fixed<0x7955> fixed; + rv = recv_fpacket<0x7955, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + + LOGIN_LOG("'ladmin': Request to re-load GM configuration file (ip: %s).\n"_fmt, + ip); read_gm_account(); // send GM accounts to all char-servers send_GM_accounts(); - RFIFOSKIP(s, 2); break; + } default: { @@ -2678,55 +2785,24 @@ void parse_admin(Session *s) timestamp_milliseconds_buffer timestr; stamp_time(timestr); FPRINTF(logfp, - "%s: receiving of an unknown packet -> disconnection\n", - timestr); - FPRINTF(logfp, - "parse_admin: connection #%d (ip: %s), packet: 0x%x (with being read: %zu).\n", - s, ip, RFIFOW(s, 0), RFIFOREST(s)); - FPRINTF(logfp, "Detail (in hex):\n"); + "%s: receiving of an unknown packet -> disconnection\n"_fmt, + timestr); FPRINTF(logfp, - "---- 00-01-02-03-04-05-06-07 08-09-0A-0B-0C-0D-0E-0F\n"); - char tmpstr[16 + 1] {}; - int i; - for (i = 0; i < RFIFOREST(s); i++) - { - if ((i & 15) == 0) - FPRINTF(logfp, "%04X ", i); - FPRINTF(logfp, "%02x ", RFIFOB (s, i)); - if (RFIFOB(s, i) > 0x1f) - tmpstr[i % 16] = RFIFOB(s, i); - else - tmpstr[i % 16] = '.'; - if ((i - 7) % 16 == 0) // -8 + 1 - FPRINTF(logfp, " "); - else if ((i + 1) % 16 == 0) - { - FPRINTF(logfp, " %s\n", tmpstr); - std::fill(tmpstr + 0, tmpstr + 17, '\0'); - } - } - if (i % 16 != 0) - { - for (int j = i; j % 16 != 0; j++) - { - FPRINTF(logfp, " "); - if ((j - 7) % 16 == 0) // -8 + 1 - FPRINTF(logfp, " "); - } - FPRINTF(logfp, " %s\n", tmpstr); - } - FPRINTF(logfp, "\n"); + "parse_admin: connection #%d (ip: %s), packet: 0x%x (with being read: %zu).\n"_fmt, + s, ip, packet_id, packet_avail(s)); + FPRINTF(logfp, "Detail (in hex):\n"_fmt); + packet_dump(logfp, s); } - } - LOGIN_LOG("'ladmin': End of connection, unknown packet (ip: %s)\n", - ip); + LOGIN_LOG("'ladmin': End of connection, unknown packet (ip: %s)\n"_fmt, + ip); s->set_eof(); - PRINTF("Remote administration has been disconnected (unknown packet).\n"); + PRINTF("Remote administration has been disconnected (unknown packet).\n"_fmt); return; + } } - //WFIFOW(fd,0) = 0x791f; - //WFIFOSET(fd,2); } + if (rv == RecvResult::Error) + s->set_eof(); return; } @@ -2738,8 +2814,8 @@ bool lan_ip_check(IP4Address p) { bool lancheck = lan_subnet.covers(p); - PRINTF("LAN test (result): %s.\n", - (lancheck) ? SGR_BOLD SGR_CYAN "LAN source" SGR_RESET : SGR_BOLD SGR_GREEN "WAN source" SGR_RESET); + PRINTF("LAN test (result): %s.\n"_fmt, + (lancheck) ? SGR_BOLD SGR_CYAN "LAN source" SGR_RESET ""_s : SGR_BOLD SGR_GREEN "WAN source" SGR_RESET ""_s); return lancheck; } @@ -2750,106 +2826,94 @@ static void parse_login(Session *s) { struct mmo_account account; - int result, j; + int result; IP4Address ip = s->client_ip; - - while (RFIFOREST(s) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id)) { if (display_parse_login == 1) { - if (RFIFOW(s, 0) == 0x64 || RFIFOW(s, 0) == 0x01dd) + if (packet_id == 0x64) { - if (RFIFOREST(s) >= ((RFIFOW(s, 0) == 0x64) ? 55 : 47)) - { - AccountName account_name = stringish<AccountName>(RFIFO_STRING<24>(s, 6)); - PRINTF("parse_login: connection #%d, packet: 0x%x (with being read: %zu), account: %s.\n", - s, RFIFOW(s, 0), RFIFOREST(s), - account_name); - } + // handled below to handle account name } - else if (RFIFOW(s, 0) == 0x2710) + else if (packet_id == 0x2710) { - if (RFIFOREST(s) >= 86) - { - ServerName server_name = stringish<ServerName>(RFIFO_STRING<20>(s, 60)); - PRINTF("parse_login: connection #%d, packet: 0x%x (with being read: %zu), server: %s.\n", - s, RFIFOW(s, 0), RFIFOREST(s), - server_name); - } + // handled below to handle server name } else - PRINTF("parse_login: connection #%d, packet: 0x%x (with being read: %zu).\n", - s, RFIFOW(s, 0), RFIFOREST(s)); + PRINTF("parse_login: connection #%d, packet: 0x%x (with being read: %zu).\n"_fmt, + s, packet_id, packet_avail(s)); } - switch (RFIFOW(s, 0)) + switch (packet_id) { - case 0x200: // New alive packet: structure: 0x200 <account.userid>.24B. used to verify if client is always alive. - if (RFIFOREST(s) < 26) - return; - RFIFOSKIP(s, 26); - break; - - case 0x204: // New alive packet: structure: 0x204 <encrypted.account.userid>.16B. (new ragexe from 22 june 2004) - if (RFIFOREST(s) < 18) - return; - RFIFOSKIP(s, 18); - break; - case 0x64: // Ask connection of a client - if (RFIFOREST(s) < 55) - return; + { + Packet_Fixed<0x0064> fixed; + rv = recv_fpacket<0x0064, 55>(s, fixed); + if (rv != RecvResult::Complete) + break; + + // formerly at top of while + { + AccountName account_name = fixed.account_name; + PRINTF("parse_login: connection #%d, packet: 0x%x (with being read: %zu), account: %s.\n"_fmt, + s, packet_id, packet_avail(s), + account_name); + } - account.userid = stringish<AccountName>(RFIFO_STRING<24>(s, 6).to_print()); - account.passwd = stringish<AccountPass>(RFIFO_STRING<24>(s, 30).to_print()); + account.userid = fixed.account_name; + account.passwd = fixed.account_pass; account.passwdenc = 0; - LOGIN_LOG("Request for connection (non encryption mode) of %s (ip: %s).\n", - account.userid, ip); + LOGIN_LOG("Request for connection (non encryption mode) of %s (ip: %s).\n"_fmt, + account.userid, ip); if (!check_ip(ip)) { - LOGIN_LOG("Connection refused: IP isn't authorised (deny/allow, ip: %s).\n", - ip); - WFIFOW(s, 0) = 0x6a; - WFIFOB(s, 2) = 0x03; - WFIFO_ZERO(s, 3, 20); - WFIFOSET(s, 23); - RFIFOSKIP(s, 55); + LOGIN_LOG("Connection refused: IP isn't authorised (deny/allow, ip: %s).\n"_fmt, + ip); + + Packet_Fixed<0x006a> fixed_6a; + fixed_6a.error_code = 0x03; + fixed_6a.error_message = {}; + send_fpacket<0x006a, 23>(s, fixed_6a); break; } result = mmo_auth(&account, s); if (result == -1) { - VERSION_2 version_2 = static_cast<VERSION_2>(RFIFOB(s, 54)); + VERSION_2 version_2 = fixed.version_2_flags; if (!bool(version_2 & VERSION_2::UPDATEHOST) || !bool(version_2 & VERSION_2::SERVERORDER)) result = 5; // client too old } if (result == -1) { - int gm_level = isGM(account.account_id); - if (min_level_to_connect > gm_level) + GmLevel gm_level = isGM(account.account_id); + if (!(gm_level.satisfies(min_level_to_connect))) { - LOGIN_LOG("Connection refused: the minimum GM level for connection is %d (account: %s, GM level: %d, ip: %s).\n", - min_level_to_connect, account.userid, - gm_level, ip); - WFIFOW(s, 0) = 0x81; - WFIFOB(s, 2) = 1; // 01 = Server closed - WFIFOSET(s, 3); + LOGIN_LOG("Connection refused: the minimum GM level for connection is %d (account: %s, GM level: %d, ip: %s).\n"_fmt, + min_level_to_connect, account.userid, + gm_level, ip); + Packet_Fixed<0x0081> fixed_81; + fixed_81.error_code = 1; // 01 = Server closed + send_fpacket<0x0081, 3>(s, fixed_81); } else { // int version_2 = RFIFOB(fd, 54); // version 2 if (gm_level) - PRINTF("Connection of the GM (level:%d) account '%s' accepted.\n", - gm_level, account.userid); + PRINTF("Connection of the GM (level:%d) account '%s' accepted.\n"_fmt, + gm_level, account.userid); else - PRINTF("Connection of the account '%s' accepted.\n", - account.userid); + PRINTF("Connection of the account '%s' accepted.\n"_fmt, + account.userid); /* * Add a 0x0063 packet, which contains the name of the update host. The packet will only @@ -2866,45 +2930,43 @@ void parse_login(Session *s) { if (update_host) { - size_t host_len = update_host.size() + 1; - WFIFOW(s, 0) = 0x63; - WFIFOW(s, 2) = 4 + host_len; - WFIFO_STRING(s, 4, update_host, host_len); - WFIFOSET(s, 4 + host_len); + send_packet_repeatonly<0x0063, 4, 1>(s, update_host); } } // Load list of char servers into outbound packet - server_num = 0; + std::vector<Packet_Repeat<0x0069>> repeat_69; // if (version_2 & VERSION_2_SERVERORDER) for (int i = 0; i < MAX_SERVERS; i++) { if (server_session[i]) { + Packet_Repeat<0x0069> info; if (lan_ip_check(ip)) - WFIFOIP(s, 47 + server_num * 32) = lan_char_ip; + info.ip = lan_char_ip; else - WFIFOIP(s, 47 + server_num * 32) = server[i].ip; - WFIFOW(s, 47 + server_num * 32 + 4) = server[i].port; - WFIFO_STRING(s, 47 + server_num * 32 + 6, server[i].name, 20); - WFIFOW(s, 47 + server_num * 32 + 26) = server[i].users; - WFIFOW(s, 47 + server_num * 32 + 28) = 0; //maintenance; - WFIFOW(s, 47 + server_num * 32 + 30) = 0; //is_new; - server_num++; + info.ip = server[i].ip; + info.port = server[i].port; + info.server_name = server[i].name; + info.users = server[i].users; + info.maintenance = 0; //maintenance; + info.is_new = 0; //is_new; + repeat_69.push_back(info); } } // if at least 1 char-server - if (server_num > 0) + if (repeat_69.size()) { - WFIFOW(s, 0) = 0x69; - WFIFOW(s, 2) = 47 + 32 * server_num; - WFIFOL(s, 4) = account.login_id1; - WFIFOL(s, 8) = account.account_id; - WFIFOL(s, 12) = account.login_id2; - WFIFOL(s, 16) = 0; // in old version, that was for ip (not more used) - WFIFO_STRING(s, 20, account.lastlogin, 24); // in old version, that was for name (not more used) - WFIFOB(s, 46) = static_cast<uint8_t>(account.sex); - WFIFOSET(s, 47 + 32 * server_num); + Packet_Head<0x0069> head_69; + head_69.login_id1 = account.login_id1; + head_69.account_id = account.account_id; + head_69.login_id2 = account.login_id2; + head_69.unused = 0; // in old version, that was for ip (not more used) + head_69.last_login_string = account.lastlogin; // in old version, that was for name (not more used) + head_69.unused2 = 0; + head_69.sex = account.sex; + send_vpacket<0x0069, 47, 32>(s, head_69, repeat_69); + if (auth_fifo_pos >= AUTH_FIFO_SIZE) auth_fifo_pos = 0; auth_fifo[auth_fifo_pos].account_id = @@ -2922,19 +2984,18 @@ void parse_login(Session *s) } else { - LOGIN_LOG("Connection refused: there is no char-server online (account: %s, ip: %s).\n", - account.userid, ip); - WFIFOW(s, 0) = 0x81; - WFIFOB(s, 2) = 1; // 01 = Server closed - WFIFOSET(s, 3); + LOGIN_LOG("Connection refused: there is no char-server online (account: %s, ip: %s).\n"_fmt, + account.userid, ip); + Packet_Fixed<0x0081> fixed_81; + fixed_81.error_code = 1; // 01 = Server closed + send_fpacket<0x0081, 3>(s, fixed_81); } } } else { - WFIFO_ZERO(s, 0, 23); - WFIFOW(s, 0) = 0x6a; - WFIFOB(s, 2) = result; + Packet_Fixed<0x006a> fixed_6a; + fixed_6a.error_code = result; if (result == 6) { // 6 = Your are Prohibited to log in until %s @@ -2946,37 +3007,49 @@ void parse_login(Session *s) // if account is banned, we send ban timestamp timestamp_seconds_buffer tmpstr; stamp_time(tmpstr, &ad->ban_until_time); - WFIFO_STRING(s, 3, tmpstr, 20); + fixed_6a.error_message = tmpstr; } else { // we send error message - WFIFO_STRING(s, 3, ad->error_message, 20); + fixed_6a.error_message = ad->error_message; } } } - WFIFOSET(s, 23); + send_fpacket<0x006a, 23>(s, fixed_6a); } - RFIFOSKIP(s, (RFIFOW(s, 0) == 0x64) ? 55 : 47); break; + } case 0x2710: // Connection request of a char-server - if (RFIFOREST(s) < 86) - return; + { + Packet_Fixed<0x2710> fixed; + rv = recv_fpacket<0x2710, 86>(s, fixed); + if (rv != RecvResult::Complete) + break; + + // formerly at top of while { - int len; - account.userid = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print()); - account.passwd = stringish<AccountPass>(RFIFO_STRING<24>(s, 26).to_print()); + ServerName server_name = stringish<ServerName>(fixed.server_name); + PRINTF("parse_login: connection #%d, packet: 0x%x (with being read: %zu), server: %s.\n"_fmt, + s, packet_id, packet_avail(s), + server_name); + } + + { + // TODO: this is exceptionally silly. Fix it. + account.userid = stringish<AccountName>(fixed.account_name.to_print()); + account.passwd = stringish<AccountPass>(fixed.account_pass.to_print()); account.passwdenc = 0; - ServerName server_name = stringish<ServerName>(RFIFO_STRING<20>(s, 60).to_print()); - LOGIN_LOG("Connection request of the char-server '%s' @ %s:%d (ip: %s)\n", - server_name, RFIFOIP(s, 54), RFIFOW(s, 58), ip); + ServerName server_name = stringish<ServerName>(fixed.server_name.to_print()); + LOGIN_LOG("Connection request of the char-server '%s' @ %s:%d (ip: %s)\n"_fmt, + server_name, fixed.ip, fixed.port, ip); if (account.userid == userid && account.passwd == passwd) { // If this is the main server, and we don't already have a main server if (!server_session[0] && server_name == main_server) { - account.account_id = 0; + account.account_id = wrap<AccountId>(0_u32); goto x2710_okay; } else @@ -2986,7 +3059,7 @@ void parse_login(Session *s) { if (!server_session[i]) { - account.account_id = i; + account.account_id = wrap<AccountId>(i); goto x2710_okay; } } @@ -2996,121 +3069,131 @@ void parse_login(Session *s) { x2710_okay: - LOGIN_LOG("Connection of the char-server '%s' accepted (account: %s, pass: %s, ip: %s)\n", - server_name, account.userid, - account.passwd, ip); - PRINTF("Connection of the char-server '%s' accepted.\n", - server_name); - server[account.account_id] = mmo_char_server{}; - server[account.account_id].ip = RFIFOIP(s, 54); - server[account.account_id].port = RFIFOW(s, 58); - server[account.account_id].name = server_name; - server[account.account_id].users = 0; + LOGIN_LOG("Connection of the char-server '%s' accepted (account: %s, pass: %s, ip: %s)\n"_fmt, + server_name, account.userid, + account.passwd, ip); + PRINTF("Connection of the char-server '%s' accepted.\n"_fmt, + server_name); + server[unwrap<AccountId>(account.account_id)] = mmo_char_server{}; + server[unwrap<AccountId>(account.account_id)].ip = fixed.ip; + server[unwrap<AccountId>(account.account_id)].port = fixed.port; + server[unwrap<AccountId>(account.account_id)].name = server_name; + server[unwrap<AccountId>(account.account_id)].users = 0; //maintenance = RFIFOW(fd, 82); //is_new = RFIFOW(fd, 84); - server_session[account.account_id] = s; + server_session[unwrap<AccountId>(account.account_id)] = s; if (anti_freeze_enable) - server_freezeflag[account.account_id] = 5; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed - WFIFOW(s, 0) = 0x2711; - WFIFOB(s, 2) = 0; - WFIFOSET(s, 3); - s->set_parsers(SessionParsers{func_parse: parse_fromchar, func_delete: delete_fromchar}); + server_freezeflag[unwrap<AccountId>(account.account_id)] = 5; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed + + Packet_Fixed<0x2711> fixed_11; + fixed_11.code = 0; + send_fpacket<0x2711, 3>(s, fixed_11); + + s->set_parsers(SessionParsers{.func_parse= parse_fromchar, .func_delete= delete_fromchar}); realloc_fifo(s, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); + // send GM account to char-server - len = 4; - WFIFOW(s, 0) = 0x2732; - for (const AuthData& ad : auth_data) - // send only existing accounts. We can not create a GM account when server is online. - if (uint8_t GM_value = isGM(ad.account_id)) - { - WFIFOL(s, len) = ad.account_id; - WFIFOB(s, len + 4) = GM_value; - len += 5; - } - WFIFOW(s, 2) = len; - WFIFOSET(s, len); + send_GM_accounts(s); goto x2710_done; } { x2710_refused: - LOGIN_LOG("Connexion of the char-server '%s' REFUSED (account: %s, pass: %s, ip: %s)\n", - server_name, account.userid, - account.passwd, ip); - WFIFOW(s, 0) = 0x2711; - WFIFOB(s, 2) = 3; - WFIFOSET(s, 3); + LOGIN_LOG("Connexion of the char-server '%s' REFUSED (account: %s, pass: %s, ip: %s)\n"_fmt, + server_name, account.userid, + account.passwd, ip); + Packet_Fixed<0x2711> fixed_11; + fixed_11.code = 3; + send_fpacket<0x2711, 3>(s, fixed_11); } } x2710_done: - RFIFOSKIP(s, 86); + // justification: we switching the packet parser + parse_fromchar(s); return; + } case 0x7530: // Request of the server version - LOGIN_LOG("Sending of the server version (ip: %s)\n", - ip); - WFIFOW(s, 0) = 0x7531; { + Packet_Fixed<0x7530> fixed; + rv = recv_fpacket<0x7530, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + + LOGIN_LOG("Sending of the server version (ip: %s)\n"_fmt, + ip); + + Packet_Fixed<0x7531> fixed_31; Version version = CURRENT_LOGIN_SERVER_VERSION; version.flags = new_account ? 1 : 0; - WFIFO_STRUCT(s, 2, version); - WFIFOSET(s, 10); - } - RFIFOSKIP(s, 2); + fixed_31.version = version; + send_fpacket<0x7531, 10>(s, fixed_31); break; + } case 0x7532: // Request to end connection - LOGIN_LOG("End of connection (ip: %s)\n", ip); + { + Packet_Fixed<0x7532> fixed; + rv = recv_fpacket<0x7532, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + + LOGIN_LOG("End of connection (ip: %s)\n"_fmt, ip); s->set_eof(); return; + } case 0x7918: // Request for administation login - if (RFIFOREST(s) < 4 - || RFIFOREST(s) < ((RFIFOW(s, 2) == 0) ? 28 : 20)) - return; - WFIFOW(s, 0) = 0x7919; - WFIFOB(s, 2) = 1; + { + Packet_Fixed<0x7918> fixed; + rv = recv_fpacket<0x7918, 28>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x7919> fixed_19; + fixed_19.error = 1; if (!check_ladminip(s->client_ip)) { - LOGIN_LOG("'ladmin'-login: Connection in administration mode refused: IP isn't authorised (ladmin_allow, ip: %s).\n", - ip); + LOGIN_LOG("'ladmin'-login: Connection in administration mode refused: IP isn't authorised (ladmin_allow, ip: %s).\n"_fmt, + ip); } else { - if (RFIFOW(s, 2) == 0) + if (fixed.encryption_zero == 0) { // non encrypted password - AccountPass password = stringish<AccountPass>(RFIFO_STRING<24>(s, 4).to_print()); + AccountPass password = stringish<AccountPass>(fixed.account_pass.to_print()); // If remote administration is enabled and password sent by client matches password read from login server configuration file if ((admin_state == 1) && (password == admin_pass)) { - LOGIN_LOG("'ladmin'-login: Connection in administration mode accepted (non encrypted password: %s, ip: %s)\n", - password, ip); - PRINTF("Connection of a remote administration accepted (non encrypted password).\n"); - WFIFOB(s, 2) = 0; - s->set_parsers(SessionParsers{func_parse: parse_admin, func_delete: delete_admin}); + LOGIN_LOG("'ladmin'-login: Connection in administration mode accepted (non encrypted password: %s, ip: %s)\n"_fmt, + password, ip); + PRINTF("Connection of a remote administration accepted (non encrypted password).\n"_fmt); + fixed_19.error = 0; + s->set_parsers(SessionParsers{.func_parse= parse_admin, .func_delete= delete_admin}); } else if (admin_state != 1) - LOGIN_LOG("'ladmin'-login: Connection in administration mode REFUSED - remote administration is disabled (non encrypted password: %s, ip: %s)\n", - password, ip); + LOGIN_LOG("'ladmin'-login: Connection in administration mode REFUSED - remote administration is disabled (non encrypted password: %s, ip: %s)\n"_fmt, + password, ip); else - LOGIN_LOG("'ladmin'-login: Connection in administration mode REFUSED - invalid password (non encrypted password: %s, ip: %s)\n", - password, ip); + LOGIN_LOG("'ladmin'-login: Connection in administration mode REFUSED - invalid password (non encrypted password: %s, ip: %s)\n"_fmt, + password, ip); } else { // encrypted password { - LOGIN_LOG("'ladmin'-login: Connection in administration mode REFUSED - encrypted login is disabled (ip: %s)\n", - ip); + LOGIN_LOG("'ladmin'-login: Connection in administration mode REFUSED - encrypted login is disabled (ip: %s)\n"_fmt, + ip); } } } - WFIFOSET(s, 3); - RFIFOSKIP(s, (RFIFOW(s, 2) == 0) ? 28 : 20); + send_fpacket<0x7919, 3>(s, fixed_19); break; + } default: + { if (save_unknown_packets) { io::AppendFile logfp(login_log_unknown_packets_filename); @@ -3119,55 +3202,24 @@ void parse_login(Session *s) timestamp_milliseconds_buffer timestr; stamp_time(timestr); FPRINTF(logfp, - "%s: receiving of an unknown packet -> disconnection\n", - timestr); - FPRINTF(logfp, - "parse_login: connection #%d (ip: %s), packet: 0x%x (with being read: %zu).\n", - s, ip, RFIFOW(s, 0), - RFIFOREST(s)); - FPRINTF(logfp, "Detail (in hex):\n"); + "%s: receiving of an unknown packet -> disconnection\n"_fmt, + timestr); FPRINTF(logfp, - "---- 00-01-02-03-04-05-06-07 08-09-0A-0B-0C-0D-0E-0F\n"); - - char tmpstr[16 + 1] {}; - - int i; - for (i = 0; i < RFIFOREST(s); i++) - { - if ((i & 15) == 0) - FPRINTF(logfp, "%04X ", i); - FPRINTF(logfp, "%02x ", RFIFOB(s, i)); - if (RFIFOB(s, i) > 0x1f) - tmpstr[i % 16] = RFIFOB(s, i); - else - tmpstr[i % 16] = '.'; - if ((i - 7) % 16 == 0) // -8 + 1 - FPRINTF(logfp, " "); - else if ((i + 1) % 16 == 0) - { - FPRINTF(logfp, " %s\n", tmpstr); - std::fill(tmpstr + 0, tmpstr + 17, '\0'); - } - } - if (i % 16 != 0) - { - for (j = i; j % 16 != 0; j++) - { - FPRINTF(logfp, " "); - if ((j - 7) % 16 == 0) // -8 + 1 - FPRINTF(logfp, " "); - } - FPRINTF(logfp, " %s\n", tmpstr); - } - FPRINTF(logfp, "\n"); + "parse_login: connection #%d (ip: %s), packet: 0x%x (with being read: %zu).\n"_fmt, + s, ip, packet_id, + packet_avail(s)); + FPRINTF(logfp, "Detail (in hex):\n"_fmt); + packet_dump(logfp, s); } } - LOGIN_LOG("End of connection, unknown packet (ip: %s)\n", ip); + LOGIN_LOG("End of connection, unknown packet (ip: %s)\n"_fmt, ip); s->set_eof(); return; + } } } - return; + if (rv == RecvResult::Error) + s->set_eof(); } //---------------------------------- @@ -3176,14 +3228,14 @@ void parse_login(Session *s) static bool login_lan_config(XString w1, ZString w2) { - struct hostent *h = NULL; + struct hostent *h = nullptr; { - if (w1 == "lan_char_ip") + if (w1 == "lan_char_ip"_s) { // Read Char-Server Lan IP Address h = gethostbyname(w2.c_str()); - if (h != NULL) + if (h != nullptr) { lan_char_ip = IP4Address({ static_cast<uint8_t>(h->h_addr[0]), @@ -3194,20 +3246,20 @@ bool login_lan_config(XString w1, ZString w2) } else { - PRINTF("Bad IP value: %s\n", w2); + PRINTF("Bad IP value: %s\n"_fmt, w2); return false; } - PRINTF("LAN IP of char-server: %s.\n", lan_char_ip); + PRINTF("LAN IP of char-server: %s.\n"_fmt, lan_char_ip); } - else if (w1 == "subnet" /*backward compatibility*/ - || w1 == "lan_subnet") + else if (w1 == "subnet"_s /*backward compatibility*/ + || w1 == "lan_subnet"_s) { if (!extract(w2, &lan_subnet)) { - PRINTF("Bad IP mask: %s\n", w2); + PRINTF("Bad IP mask: %s\n"_fmt, w2); return false; } - PRINTF("Sub-network of the char-server: %s.\n", + PRINTF("Sub-network of the char-server: %s.\n"_fmt, lan_subnet); } else @@ -3222,18 +3274,18 @@ static bool lan_check() { // log the LAN configuration - LOGIN_LOG("The LAN configuration of the server is set:\n"); - LOGIN_LOG("- with LAN IP of char-server: %s.\n", lan_char_ip); - LOGIN_LOG("- with the sub-network of the char-server: %s.\n", + LOGIN_LOG("The LAN configuration of the server is set:\n"_fmt); + LOGIN_LOG("- with LAN IP of char-server: %s.\n"_fmt, lan_char_ip); + LOGIN_LOG("- with the sub-network of the char-server: %s.\n"_fmt, lan_subnet); // sub-network check of the char-server { - PRINTF("LAN test of LAN IP of the char-server: "); + PRINTF("LAN test of LAN IP of the char-server: "_fmt); if (!lan_ip_check(lan_char_ip)) { - PRINTF(SGR_BOLD SGR_RED "***ERROR: LAN IP of the char-server doesn't belong to the specified Sub-network" SGR_RESET "\n"); - LOGIN_LOG("***ERROR: LAN IP of the char-server doesn't belong to the specified Sub-network.\n"); + PRINTF(SGR_BOLD SGR_RED "***ERROR: LAN IP of the char-server doesn't belong to the specified Sub-network"_fmt SGR_RESET "\n"); + LOGIN_LOG("***ERROR: LAN IP of the char-server doesn't belong to the specified Sub-network.\n"_fmt); return false; } } @@ -3248,24 +3300,24 @@ static bool login_config(XString w1, ZString w2) { { - if (w1 == "admin_state") + if (w1 == "admin_state"_s) { admin_state = config_switch(w2); } - else if (w1 == "admin_pass") + else if (w1 == "admin_pass"_s) { admin_pass = stringish<AccountPass>(w2); } - else if (w1 == "ladminallowip") + else if (w1 == "ladminallowip"_s) { - if (w2 == "clear") + if (w2 == "clear"_s) { access_ladmin.clear(); } else { // a.b.c.d/0.0.0.0 (canonically, 0.0.0.0/0) covers all - if (w2 == "all") + if (w2 == "all"_s) { // reset all previous values access_ladmin.clear(); @@ -3280,104 +3332,104 @@ bool login_config(XString w1, ZString w2) IP4Mask n; if (!extract(w2, &n)) { - PRINTF("Bad IP mask: %s\n", w2); + PRINTF("Bad IP mask: %s\n"_fmt, w2); return false; } access_ladmin.push_back(n); } } } - else if (w1 == "gm_pass") + else if (w1 == "gm_pass"_s) { gm_pass = w2; } - else if (w1 == "level_new_gm") + else if (w1 == "level_new_gm"_s) { - level_new_gm = atoi(w2.c_str()); + level_new_gm = GmLevel::from(static_cast<uint32_t>(atoi(w2.c_str()))); } - else if (w1 == "new_account") + else if (w1 == "new_account"_s) { new_account = config_switch(w2); } - else if (w1 == "login_port") + else if (w1 == "login_port"_s) { login_port = atoi(w2.c_str()); } - else if (w1 == "account_filename") + else if (w1 == "account_filename"_s) { account_filename = w2; } - else if (w1 == "gm_account_filename") + else if (w1 == "gm_account_filename"_s) { gm_account_filename = w2; } - else if (w1 == "gm_account_filename_check_timer") + else if (w1 == "gm_account_filename_check_timer"_s) { gm_account_filename_check_timer = std::chrono::seconds(atoi(w2.c_str())); } - else if (w1 == "login_log_filename") + else if (w1 == "login_log_filename"_s) { login_log_filename = w2; } - else if (w1 == "login_log_unknown_packets_filename") + else if (w1 == "login_log_unknown_packets_filename"_s) { login_log_unknown_packets_filename = w2; } - else if (w1 == "save_unknown_packets") + else if (w1 == "save_unknown_packets"_s) { save_unknown_packets = config_switch(w2); } - else if (w1 == "display_parse_login") + else if (w1 == "display_parse_login"_s) { display_parse_login = config_switch(w2); // 0: no, 1: yes } - else if (w1 == "display_parse_admin") + else if (w1 == "display_parse_admin"_s) { display_parse_admin = config_switch(w2); // 0: no, 1: yes } - else if (w1 == "display_parse_fromchar") + else if (w1 == "display_parse_fromchar"_s) { display_parse_fromchar = config_switch(w2); // 0: no, 1: yes (without packet 0x2714), 2: all packets } - else if (w1 == "min_level_to_connect") + else if (w1 == "min_level_to_connect"_s) { - min_level_to_connect = atoi(w2.c_str()); + min_level_to_connect = GmLevel::from(static_cast<uint32_t>(atoi(w2.c_str()))); } - else if (w1 == "add_to_unlimited_account") + else if (w1 == "add_to_unlimited_account"_s) { add_to_unlimited_account = config_switch(w2); } - else if (w1 == "start_limited_time") + else if (w1 == "start_limited_time"_s) { start_limited_time = atoi(w2.c_str()); } - else if (w1 == "check_ip_flag") + else if (w1 == "check_ip_flag"_s) { check_ip_flag = config_switch(w2); } - else if (w1 == "order") + else if (w1 == "order"_s) { - if (w2 == "deny,allow" || w2 == "deny, allow") + if (w2 == "deny,allow"_s || w2 == "deny, allow"_s) access_order = ACO::DENY_ALLOW; - else if (w2 == "allow,deny" || w2 == "allow, deny") + else if (w2 == "allow,deny"_s || w2 == "allow, deny"_s) access_order = ACO::ALLOW_DENY; - else if (w2 == "mutual-failture" || w2 == "mutual-failure") + else if (w2 == "mutual-failture"_s || w2 == "mutual-failure"_s) access_order = ACO::MUTUAL_FAILURE; else { - PRINTF("Bad order: %s\n", w2); + PRINTF("Bad order: %s\n"_fmt, w2); return false; } } - else if (w1 == "allow") + else if (w1 == "allow"_s) { - if (w2 == "clear") + if (w2 == "clear"_s) { access_allow.clear(); } else { - if (w2 == "all") + if (w2 == "all"_s) { // reset all previous values access_allow.clear(); @@ -3392,22 +3444,22 @@ bool login_config(XString w1, ZString w2) IP4Mask n; if (!extract(w2, &n)) { - PRINTF("Bad IP mask: %s\n", w2); + PRINTF("Bad IP mask: %s\n"_fmt, w2); return false; } access_allow.push_back(n); } } } - else if (w1 == "deny") + else if (w1 == "deny"_s) { - if (w2 == "clear") + if (w2 == "clear"_s) { access_deny.clear(); } else { - if (w2 == "all") + if (w2 == "all"_s) { // reset all previous values access_deny.clear(); @@ -3422,36 +3474,36 @@ bool login_config(XString w1, ZString w2) IP4Mask n; if (!extract(w2, &n)) { - PRINTF("Bad IP mask: %s\n", w2); + PRINTF("Bad IP mask: %s\n"_fmt, w2); return false; } access_deny.push_back(n); } } } - else if (w1 == "anti_freeze_enable") + else if (w1 == "anti_freeze_enable"_s) { anti_freeze_enable = config_switch(w2); } - else if (w1 == "anti_freeze_interval") + else if (w1 == "anti_freeze_interval"_s) { anti_freeze_interval = std::max( std::chrono::seconds(atoi(w2.c_str())), - std::chrono::seconds(5)); + 5_s); } - else if (w1 == "update_host") + else if (w1 == "update_host"_s) { update_host = w2; } - else if (w1 == "main_server") + else if (w1 == "main_server"_s) { main_server = stringish<ServerName>(w2); } - else if (w1 == "userid") + else if (w1 == "userid"_s) { userid = stringish<AccountName>(w2); } - else if (w1 == "passwd") + else if (w1 == "passwd"_s) { passwd = stringish<AccountPass>(w2); } @@ -3473,7 +3525,7 @@ bool display_conf_warnings(void) bool rv = true; if (admin_state != 0 && admin_state != 1) { - PRINTF("***WARNING: Invalid value for admin_state parameter -> set to 0 (no remote admin).\n"); + PRINTF("***WARNING: Invalid value for admin_state parameter -> set to 0 (no remote admin).\n"_fmt); admin_state = 0; rv = false; } @@ -3482,132 +3534,108 @@ bool display_conf_warnings(void) { if (!admin_pass) { - PRINTF("***WARNING: Administrator password is void (admin_pass).\n"); + PRINTF("***WARNING: Administrator password is void (admin_pass).\n"_fmt); rv = false; } - else if (admin_pass == stringish<AccountPass>("admin")) + else if (admin_pass == stringish<AccountPass>("admin"_s)) { - PRINTF("***WARNING: You are using the default administrator password (admin_pass).\n"); - PRINTF(" We highly recommend that you change it.\n"); + PRINTF("***WARNING: You are using the default administrator password (admin_pass).\n"_fmt); + PRINTF(" We highly recommend that you change it.\n"_fmt); } } if (!gm_pass) { - PRINTF("***WARNING: 'To GM become' password is void (gm_pass).\n"); - PRINTF(" We highly recommend that you set one password.\n"); + PRINTF("***WARNING: 'To GM become' password is void (gm_pass).\n"_fmt); + PRINTF(" We highly recommend that you set one password.\n"_fmt); rv = false; } - else if (gm_pass == "gm") - { - PRINTF("***WARNING: You are using the default GM password (gm_pass).\n"); - PRINTF(" We highly recommend that you change it.\n"); - } - - if (level_new_gm < 0 || level_new_gm > 99) + else if (gm_pass == "gm"_s) { - PRINTF("***WARNING: Invalid value for level_new_gm parameter -> set to 60 (default).\n"); - level_new_gm = 60; - rv = false; + PRINTF("***WARNING: You are using the default GM password (gm_pass).\n"_fmt); + PRINTF(" We highly recommend that you change it.\n"_fmt); } if (new_account != 0 && new_account != 1) { - PRINTF("***WARNING: Invalid value for new_account parameter -> set to 0 (no new account).\n"); + PRINTF("***WARNING: Invalid value for new_account parameter -> set to 0 (no new account).\n"_fmt); new_account = 0; rv = false; } if (login_port < 1024 || login_port > 65535) { - PRINTF("***WARNING: Invalid value for login_port parameter -> set to 6900 (default).\n"); + PRINTF("***WARNING: Invalid value for login_port parameter -> set to 6900 (default).\n"_fmt); login_port = 6900; rv = false; } if (gm_account_filename_check_timer.count() < 0) { - PRINTF("***WARNING: Invalid value for gm_account_filename_check_timer parameter.\n"); - PRINTF(" -> set to 15 sec (default).\n"); - gm_account_filename_check_timer = std::chrono::seconds(15); + PRINTF("***WARNING: Invalid value for gm_account_filename_check_timer parameter.\n"_fmt); + PRINTF(" -> set to 15 sec (default).\n"_fmt); + gm_account_filename_check_timer = 15_s; rv = false; } - else if (gm_account_filename_check_timer == std::chrono::seconds(1)) + else if (gm_account_filename_check_timer == 1_s) { - PRINTF("***WARNING: Invalid value for gm_account_filename_check_timer parameter.\n"); - PRINTF(" -> set to 2 sec (minimum value).\n"); - gm_account_filename_check_timer = std::chrono::seconds(2); + PRINTF("***WARNING: Invalid value for gm_account_filename_check_timer parameter.\n"_fmt); + PRINTF(" -> set to 2 sec (minimum value).\n"_fmt); + gm_account_filename_check_timer = 2_s; rv = false; } if (save_unknown_packets != 0 && save_unknown_packets != 1) { - PRINTF("WARNING: Invalid value for save_unknown_packets parameter -> set to 0-no save.\n"); + PRINTF("WARNING: Invalid value for save_unknown_packets parameter -> set to 0-no save.\n"_fmt); save_unknown_packets = 0; rv = false; } if (display_parse_login != 0 && display_parse_login != 1) { // 0: no, 1: yes - PRINTF("***WARNING: Invalid value for display_parse_login parameter\n"); - PRINTF(" -> set to 0 (no display).\n"); + PRINTF("***WARNING: Invalid value for display_parse_login parameter\n"_fmt); + PRINTF(" -> set to 0 (no display).\n"_fmt); display_parse_login = 0; rv = false; } if (display_parse_admin != 0 && display_parse_admin != 1) { // 0: no, 1: yes - PRINTF("***WARNING: Invalid value for display_parse_admin parameter\n"); - PRINTF(" -> set to 0 (no display).\n"); + PRINTF("***WARNING: Invalid value for display_parse_admin parameter\n"_fmt); + PRINTF(" -> set to 0 (no display).\n"_fmt); display_parse_admin = 0; rv = false; } if (display_parse_fromchar < 0 || display_parse_fromchar > 2) { // 0: no, 1: yes (without packet 0x2714), 2: all packets - PRINTF("***WARNING: Invalid value for display_parse_fromchar parameter\n"); - PRINTF(" -> set to 0 (no display).\n"); + PRINTF("***WARNING: Invalid value for display_parse_fromchar parameter\n"_fmt); + PRINTF(" -> set to 0 (no display).\n"_fmt); display_parse_fromchar = 0; rv = false; } - if (min_level_to_connect < 0) - { // 0: all players, 1-99 at least gm level x - PRINTF("***WARNING: Invalid value for min_level_to_connect (%d) parameter\n", - min_level_to_connect); - PRINTF(" -> set to 0 (any player).\n"); - min_level_to_connect = 0; - rv = false; - } - else if (min_level_to_connect > 99) - { // 0: all players, 1-99 at least gm level x - PRINTF("***WARNING: Invalid value for min_level_to_connect (%d) parameter\n", - min_level_to_connect); - PRINTF(" -> set to 99 (only GM level 99).\n"); - min_level_to_connect = 99; - rv = false; - } - if (add_to_unlimited_account != 0 && add_to_unlimited_account != 1) { // 0: no, 1: yes - PRINTF("***WARNING: Invalid value for add_to_unlimited_account parameter\n"); - PRINTF(" -> set to 0 (impossible to add a time to an unlimited account).\n"); + PRINTF("***WARNING: Invalid value for add_to_unlimited_account parameter\n"_fmt); + PRINTF(" -> set to 0 (impossible to add a time to an unlimited account).\n"_fmt); add_to_unlimited_account = 0; rv = false; } if (start_limited_time < -1) { // -1: create unlimited account, 0 or more: additionnal sec from now to create limited time - PRINTF("***WARNING: Invalid value for start_limited_time parameter\n"); - PRINTF(" -> set to -1 (new accounts are created with unlimited time).\n"); + PRINTF("***WARNING: Invalid value for start_limited_time parameter\n"_fmt); + PRINTF(" -> set to -1 (new accounts are created with unlimited time).\n"_fmt); start_limited_time = -1; rv = false; } if (check_ip_flag != 0 && check_ip_flag != 1) { // 0: no, 1: yes - PRINTF("***WARNING: Invalid value for check_ip_flag parameter\n"); - PRINTF(" -> set to 1 (check players ip between login-server & char-server).\n"); + PRINTF("***WARNING: Invalid value for check_ip_flag parameter\n"_fmt); + PRINTF(" -> set to 1 (check players ip between login-server & char-server).\n"_fmt); check_ip_flag = 1; rv = false; } @@ -3616,8 +3644,8 @@ bool display_conf_warnings(void) { if (access_deny.size() == 1 && access_deny.front().mask() == IP4Address()) { - PRINTF("***WARNING: The IP security order is 'deny,allow' (allow if not deny).\n"); - PRINTF(" And you refuse ALL IP.\n"); + PRINTF("***WARNING: The IP security order is 'deny,allow' (allow if not deny).\n"_fmt); + PRINTF(" And you refuse ALL IP.\n"_fmt); rv = false; } } @@ -3625,8 +3653,8 @@ bool display_conf_warnings(void) { if (access_allow.empty()) { - PRINTF("***WARNING: The IP security order is 'allow,deny' (deny if not allow).\n"); - PRINTF(" But, NO IP IS AUTHORISED!\n"); + PRINTF("***WARNING: The IP security order is 'allow,deny' (deny if not allow).\n"_fmt); + PRINTF(" But, NO IP IS AUTHORISED!\n"_fmt); rv = false; } } @@ -3635,16 +3663,16 @@ bool display_conf_warnings(void) // ACO::MUTUAL_FAILURE if (access_allow.empty()) { - PRINTF("***WARNING: The IP security order is 'mutual-failture'\n"); - PRINTF(" (allow if in the allow list and not in the deny list).\n"); - PRINTF(" But, NO IP IS AUTHORISED!\n"); + PRINTF("***WARNING: The IP security order is 'mutual-failture'\n"_fmt); + PRINTF(" (allow if in the allow list and not in the deny list).\n"_fmt); + PRINTF(" But, NO IP IS AUTHORISED!\n"_fmt); rv = false; } else if (access_deny.size() == 1 && access_deny.front().mask() == IP4Address()) { - PRINTF("***WARNING: The IP security order is mutual-failture\n"); - PRINTF(" (allow if in the allow list and not in the deny list).\n"); - PRINTF(" But, you refuse ALL IP!\n"); + PRINTF("***WARNING: The IP security order is mutual-failture\n"_fmt); + PRINTF(" (allow if in the allow list and not in the deny list).\n"_fmt); + PRINTF(" But, you refuse ALL IP!\n"_fmt); rv = false; } } @@ -3658,168 +3686,166 @@ static void save_config_in_log(void) { // a newline in the log... - LOGIN_LOG(""); - LOGIN_LOG("The login-server starting...\n"); + LOGIN_LOG(""_fmt); + LOGIN_LOG("The login-server starting...\n"_fmt); // save configuration in log file - LOGIN_LOG("The configuration of the server is set:\n"); + LOGIN_LOG("The configuration of the server is set:\n"_fmt); if (admin_state != 1) - LOGIN_LOG("- with no remote administration.\n"); + LOGIN_LOG("- with no remote administration.\n"_fmt); else if (!admin_pass) - LOGIN_LOG("- with a remote administration with a VOID password.\n"); - else if (admin_pass == stringish<AccountPass>("admin")) - LOGIN_LOG("- with a remote administration with the DEFAULT password.\n"); + LOGIN_LOG("- with a remote administration with a VOID password.\n"_fmt); + else if (admin_pass == stringish<AccountPass>("admin"_s)) + LOGIN_LOG("- with a remote administration with the DEFAULT password.\n"_fmt); else - LOGIN_LOG("- with a remote administration with the password of %zu character(s).\n", + LOGIN_LOG("- with a remote administration with the password of %zu character(s).\n"_fmt, admin_pass.size()); if (access_ladmin.empty() || (access_ladmin.size() == 1 && access_ladmin.front().mask() == IP4Address())) { - LOGIN_LOG("- to accept any IP for remote administration\n"); + LOGIN_LOG("- to accept any IP for remote administration\n"_fmt); } else { - LOGIN_LOG("- to accept following IP for remote administration:\n"); + LOGIN_LOG("- to accept following IP for remote administration:\n"_fmt); for (const IP4Mask& ae : access_ladmin) - LOGIN_LOG(" %s\n", ae); + LOGIN_LOG(" %s\n"_fmt, ae); } if (!gm_pass) - LOGIN_LOG("- with a VOID 'To GM become' password (gm_pass).\n"); - else if (gm_pass == "gm") - LOGIN_LOG("- with the DEFAULT 'To GM become' password (gm_pass).\n"); + LOGIN_LOG("- with a VOID 'To GM become' password (gm_pass).\n"_fmt); + else if (gm_pass == "gm"_s) + LOGIN_LOG("- with the DEFAULT 'To GM become' password (gm_pass).\n"_fmt); else - LOGIN_LOG("- with a 'To GM become' password (gm_pass) of %zu character(s).\n", + LOGIN_LOG("- with a 'To GM become' password (gm_pass) of %zu character(s).\n"_fmt, gm_pass.size()); - if (level_new_gm == 0) - LOGIN_LOG("- to refuse any creation of GM with @gm.\n"); + if (!level_new_gm) + LOGIN_LOG("- to refuse any creation of GM with @gm.\n"_fmt); else - LOGIN_LOG("- to create GM with level '%d' when @gm is used.\n", - level_new_gm); + LOGIN_LOG("- to create GM with level '%d' when @gm is used.\n"_fmt, + level_new_gm); if (new_account == 1) - LOGIN_LOG("- to ALLOW new users (with _F/_M).\n"); + LOGIN_LOG("- to ALLOW new users (with _F/_M).\n"_fmt); else - LOGIN_LOG("- to NOT ALLOW new users (with _F/_M).\n"); - LOGIN_LOG("- with port: %d.\n", login_port); - LOGIN_LOG("- with the accounts file name: '%s'.\n", - account_filename); - LOGIN_LOG("- with the GM accounts file name: '%s'.\n", - gm_account_filename); + LOGIN_LOG("- to NOT ALLOW new users (with _F/_M).\n"_fmt); + LOGIN_LOG("- with port: %d.\n"_fmt, login_port); + LOGIN_LOG("- with the accounts file name: '%s'.\n"_fmt, + account_filename); + LOGIN_LOG("- with the GM accounts file name: '%s'.\n"_fmt, + gm_account_filename); if (gm_account_filename_check_timer == interval_t::zero()) - LOGIN_LOG("- to NOT check GM accounts file modifications.\n"); + LOGIN_LOG("- to NOT check GM accounts file modifications.\n"_fmt); else - LOGIN_LOG("- to check GM accounts file modifications every %lld seconds.\n", - maybe_cast<long long>(gm_account_filename_check_timer.count())); + LOGIN_LOG("- to check GM accounts file modifications every %lld seconds.\n"_fmt, + maybe_cast<long long>(gm_account_filename_check_timer.count())); // not necessary to log the 'login_log_filename', we are inside :) - LOGIN_LOG("- with the unknown packets file name: '%s'.\n", - login_log_unknown_packets_filename); + LOGIN_LOG("- with the unknown packets file name: '%s'.\n"_fmt, + login_log_unknown_packets_filename); if (save_unknown_packets) - LOGIN_LOG("- to SAVE all unkown packets.\n"); + LOGIN_LOG("- to SAVE all unkown packets.\n"_fmt); else - LOGIN_LOG("- to SAVE only unkown packets sending by a char-server or a remote administration.\n"); + LOGIN_LOG("- to SAVE only unkown packets sending by a char-server or a remote administration.\n"_fmt); if (display_parse_login) - LOGIN_LOG("- to display normal parse packets on console.\n"); + LOGIN_LOG("- to display normal parse packets on console.\n"_fmt); else - LOGIN_LOG("- to NOT display normal parse packets on console.\n"); + LOGIN_LOG("- to NOT display normal parse packets on console.\n"_fmt); if (display_parse_admin) - LOGIN_LOG("- to display administration parse packets on console.\n"); + LOGIN_LOG("- to display administration parse packets on console.\n"_fmt); else - LOGIN_LOG("- to NOT display administration parse packets on console.\n"); + LOGIN_LOG("- to NOT display administration parse packets on console.\n"_fmt); if (display_parse_fromchar) - LOGIN_LOG("- to display char-server parse packets on console.\n"); + LOGIN_LOG("- to display char-server parse packets on console.\n"_fmt); else - LOGIN_LOG("- to NOT display char-server parse packets on console.\n"); + LOGIN_LOG("- to NOT display char-server parse packets on console.\n"_fmt); - if (min_level_to_connect == 0) // 0: all players, 1-99 at least gm level x - LOGIN_LOG("- with no minimum level for connection.\n"); - else if (min_level_to_connect == 99) - LOGIN_LOG("- to accept only GM with level 99.\n"); + if (!min_level_to_connect) // 0: all players, 1-99 at least gm level x + LOGIN_LOG("- with no minimum level for connection.\n"_fmt); else - LOGIN_LOG("- to accept only GM with level %d or more.\n", - min_level_to_connect); + LOGIN_LOG("- to accept only GM with level %d or more.\n"_fmt, + min_level_to_connect); if (add_to_unlimited_account) - LOGIN_LOG("- to authorize adjustment (with timeadd ladmin) on an unlimited account.\n"); + LOGIN_LOG("- to authorize adjustment (with timeadd ladmin) on an unlimited account.\n"_fmt); else - LOGIN_LOG("- to refuse adjustment (with timeadd ladmin) on an unlimited account. You must use timeset (ladmin command) before.\n"); + LOGIN_LOG("- to refuse adjustment (with timeadd ladmin) on an unlimited account. You must use timeset (ladmin command) before.\n"_fmt); if (start_limited_time < 0) - LOGIN_LOG("- to create new accounts with an unlimited time.\n"); + LOGIN_LOG("- to create new accounts with an unlimited time.\n"_fmt); else if (start_limited_time == 0) - LOGIN_LOG("- to create new accounts with a limited time: time of creation.\n"); + LOGIN_LOG("- to create new accounts with a limited time: time of creation.\n"_fmt); else - LOGIN_LOG("- to create new accounts with a limited time: time of creation + %d second(s).\n", - start_limited_time); + LOGIN_LOG("- to create new accounts with a limited time: time of creation + %d second(s).\n"_fmt, + start_limited_time); if (check_ip_flag) - LOGIN_LOG("- with control of players IP between login-server and char-server.\n"); + LOGIN_LOG("- with control of players IP between login-server and char-server.\n"_fmt); else - LOGIN_LOG("- to not check players IP between login-server and char-server.\n"); + LOGIN_LOG("- to not check players IP between login-server and char-server.\n"_fmt); if (access_order == ACO::DENY_ALLOW) { if (access_deny.empty()) { - LOGIN_LOG("- with the IP security order: 'deny,allow' (allow if not deny). You refuse no IP.\n"); + LOGIN_LOG("- with the IP security order: 'deny,allow' (allow if not deny). You refuse no IP.\n"_fmt); } else if (access_deny.size() == 1 && access_deny.front().mask() == IP4Address()) { - LOGIN_LOG("- with the IP security order: 'deny,allow' (allow if not deny). You refuse ALL IP.\n"); + LOGIN_LOG("- with the IP security order: 'deny,allow' (allow if not deny). You refuse ALL IP.\n"_fmt); } else { - LOGIN_LOG("- with the IP security order: 'deny,allow' (allow if not deny). Refused IP are:\n"); + LOGIN_LOG("- with the IP security order: 'deny,allow' (allow if not deny). Refused IP are:\n"_fmt); for (IP4Mask ae : access_deny) - LOGIN_LOG(" %s\n", ae); + LOGIN_LOG(" %s\n"_fmt, ae); } } else if (access_order == ACO::ALLOW_DENY) { if (access_allow.empty()) { - LOGIN_LOG("- with the IP security order: 'allow,deny' (deny if not allow). But, NO IP IS AUTHORISED!\n"); + LOGIN_LOG("- with the IP security order: 'allow,deny' (deny if not allow). But, NO IP IS AUTHORISED!\n"_fmt); } else if (access_allow.size() == 1 && access_allow.front().mask() == IP4Address()) { - LOGIN_LOG("- with the IP security order: 'allow,deny' (deny if not allow). You authorise ALL IP.\n"); + LOGIN_LOG("- with the IP security order: 'allow,deny' (deny if not allow). You authorise ALL IP.\n"_fmt); } else { - LOGIN_LOG("- with the IP security order: 'allow,deny' (deny if not allow). Authorised IP are:\n"); + LOGIN_LOG("- with the IP security order: 'allow,deny' (deny if not allow). Authorised IP are:\n"_fmt); for (IP4Mask ae : access_allow) - LOGIN_LOG(" %s\n", ae); + LOGIN_LOG(" %s\n"_fmt, ae); } } else { // ACO_MUTUAL_FAILTURE - LOGIN_LOG("- with the IP security order: 'mutual-failture' (allow if in the allow list and not in the deny list).\n"); + LOGIN_LOG("- with the IP security order: 'mutual-failture' (allow if in the allow list and not in the deny list).\n"_fmt); if (access_allow.empty()) { - LOGIN_LOG(" But, NO IP IS AUTHORISED!\n"); + LOGIN_LOG(" But, NO IP IS AUTHORISED!\n"_fmt); } else if (access_deny.size() == 1 && access_deny.front().mask() == IP4Address()) { - LOGIN_LOG(" But, you refuse ALL IP!\n"); + LOGIN_LOG(" But, you refuse ALL IP!\n"_fmt); } else { if (access_allow.size() == 1 && access_allow.front().mask() == IP4Address()) { - LOGIN_LOG(" You authorise ALL IP.\n"); + LOGIN_LOG(" You authorise ALL IP.\n"_fmt); } else { - LOGIN_LOG(" Authorised IP are:\n"); + LOGIN_LOG(" Authorised IP are:\n"_fmt); for (IP4Mask ae : access_allow) - LOGIN_LOG(" %s\n", ae); + LOGIN_LOG(" %s\n"_fmt, ae); } - LOGIN_LOG(" Refused IP are:\n"); + LOGIN_LOG(" Refused IP are:\n"_fmt); for (IP4Mask ae : access_deny) - LOGIN_LOG(" %s\n", ae); + LOGIN_LOG(" %s\n"_fmt, ae); } } } @@ -3841,7 +3867,7 @@ void term_func(void) } delete_session(login_session); - LOGIN_LOG("----End of login-server (normal end with closing of all files).\n"); + LOGIN_LOG("----End of login-server (normal end with closing of all files).\n"_fmt); } static @@ -3867,20 +3893,20 @@ int do_init(Slice<ZString> argv) ZString argvi = argv.pop_front(); if (argvi.startswith('-')) { - if (argvi == "--help") + if (argvi == "--help"_s) { - PRINTF("Usage: %s [--help] [--version] [files...]\n", + PRINTF("Usage: %s [--help] [--version] [files...]\n"_fmt, argv0); exit(0); } - else if (argvi == "--version") + else if (argvi == "--version"_s) { - PRINTF("%s\n", CURRENT_VERSION_STRING); + PRINTF("%s\n"_fmt, CURRENT_VERSION_STRING); exit(0); } else { - FPRINTF(stderr, "Unknown argument: %s\n", argvi); + FPRINTF(stderr, "Unknown argument: %s\n"_fmt, argvi); runflag = false; } } @@ -3892,7 +3918,7 @@ int do_init(Slice<ZString> argv) } if (!loaded_config_yet) - runflag &= load_config_file("conf/tmwa-login.conf", login_confs); + runflag &= load_config_file("conf/tmwa-login.conf"_s, login_confs); // not in login_config_read, because we can use 'import' option, and display same message twice or more // (why is that bad?) @@ -3910,17 +3936,17 @@ int do_init(Slice<ZString> argv) read_gm_account(); mmo_auth_init(); // set_termfunc (mmo_auth_sync); - login_session = make_listen_port(login_port, SessionParsers{func_parse: parse_login, func_delete: delete_login}); + login_session = make_listen_port(login_port, SessionParsers{.func_parse= parse_login, .func_delete= delete_login}); - Timer(gettick() + std::chrono::minutes(5), + Timer(gettick() + 5_min, check_auth_sync, - std::chrono::minutes(5) + 5_min ).detach(); if (anti_freeze_enable > 0) { - Timer(gettick() + std::chrono::seconds(1), + Timer(gettick() + 1_s, char_anti_freeze_system, anti_freeze_interval ).detach(); @@ -3929,16 +3955,17 @@ int do_init(Slice<ZString> argv) // add timer to check GM accounts file modification std::chrono::seconds j = gm_account_filename_check_timer; if (j == interval_t::zero()) - j = std::chrono::minutes(1); + j = 1_min; Timer(gettick() + j, check_GM_file, j).detach(); - LOGIN_LOG("The login-server is ready (Server is listening on the port %d).\n", - login_port); + LOGIN_LOG("The login-server is ready (Server is listening on the port %d).\n"_fmt, + login_port); - PRINTF("The login-server is " SGR_BOLD SGR_GREEN "ready" SGR_RESET " (Server is listening on the port %d).\n\n", - login_port); + PRINTF("The login-server is " SGR_BOLD SGR_GREEN "ready" SGR_RESET " (Server is listening on the port %d).\n\n"_fmt, + login_port); return 0; } +} // namespace tmwa diff --git a/src/login/login.hpp b/src/login/login.hpp index 3458dab..92f3c76 100644 --- a/src/login/login.hpp +++ b/src/login/login.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_LOGIN_LOGIN_HPP -#define TMWA_LOGIN_LOGIN_HPP +#pragma once // login.hpp - dummy header to make Make dependencies work. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,6 +18,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -#endif // TMWA_LOGIN_LOGIN_HPP +#include "login.t.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/map/magic-interpreter-aux.hpp b/src/login/login.t.hpp index 1369b38..f2c775a 100644 --- a/src/map/magic-interpreter-aux.hpp +++ b/src/login/login.t.hpp @@ -1,7 +1,7 @@ -#ifndef TMWA_MAP_MAGIC_INTERPRETER_AUX_HPP -#define TMWA_MAP_MAGIC_INTERPRETER_AUX_HPP -// magic-interpreter-aux.hpp - Edge of the magic system. +#pragma once +// login.t.hpp - externally useful types from login // +// Copyright © ????-2004 Athena Dev Teams // Copyright © 2004-2011 The Mana World Development Team // Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> // @@ -20,14 +20,25 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "magic-interpreter.t.hpp" +#include <cstdint> -template<class T> -bool CHECK_TYPE(T *v, TYPE t) +#include "../generic/enum.hpp" + + +namespace tmwa +{ +namespace e { - return v->ty == t; +enum class VERSION_2 : uint8_t +{ + /// client supports updatehost + UPDATEHOST = 0x01, + /// send servers in forward order + SERVERORDER = 0x02, +}; +ENUM_BITWISE_OPERATORS(VERSION_2) } - -#endif // TMWA_MAP_MAGIC_INTERPRETER_AUX_HPP +using e::VERSION_2; +} // namespace tmwa diff --git a/src/login/main.cpp b/src/login/main.cpp index 5d51212..b1eb8dd 100644 --- a/src/login/main.cpp +++ b/src/login/main.cpp @@ -1,4 +1,3 @@ -#include "login.hpp" // login/main.cpp - dummy file to make Make dependencies work // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -18,4 +17,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include "login.hpp" + #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/main-gdb-head.py b/src/main-gdb-head.py index 8c6fe08..d8f2001 100644 --- a/src/main-gdb-head.py +++ b/src/main-gdb-head.py @@ -5,7 +5,7 @@ # gdb sticks everything in one scope. # This lets us enumerate what *we* added. -initial_globals = {id(v):v for v in globals().itervalues()} +initial_globals = {id(v):v for v in globals().values()} import re @@ -32,8 +32,8 @@ def get_basic_type(type_): def finish(): global finish, initial_globals, FastPrinters - final_globals = {id(v):v for v in globals().itervalues()} - diff = final_globals.viewkeys() - initial_globals.viewkeys() \ + final_globals = {id(v):v for v in globals().values()} + diff = final_globals.keys() - initial_globals.keys() \ - {'finish', 'initial_globals', 'FastPrinters'} fp = FastPrinters() @@ -67,7 +67,7 @@ class FastPrinters(object): @property def subprinters(self): - return self.printers.values() + return list(self.printers.values()) def strip_templates(self, name, __pattern=re.compile('<[^<>]*>')): # TODO what about '<' and '>' as non-type template parameters? diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 240df8b..11f6eb1 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -20,10 +20,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <cmath> -#include <cstring> #include <ctime> +#include <algorithm> + #include "../conf/version.hpp" #include "../compat/nullpo.hpp" @@ -35,19 +35,23 @@ #include "../strings/xstring.hpp" #include "../strings/vstring.hpp" +#include "../generic/db.hpp" #include "../generic/random.hpp" #include "../io/cxxstdio.hpp" #include "../io/read.hpp" #include "../io/write.hpp" +#include "../net/socket.hpp" +#include "../net/timer.hpp" + #include "../mmo/config_parse.hpp" #include "../mmo/core.hpp" #include "../mmo/extract.hpp" #include "../mmo/human_time_diff.hpp" +#include "../mmo/ids.hpp" #include "../mmo/mmo.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" +#include "../mmo/utils.hpp" #include "../mmo/version.hpp" #include "battle.hpp" @@ -60,7 +64,6 @@ #include "npc.hpp" #include "party.hpp" #include "pc.hpp" -#include "script.hpp" #include "skill.hpp" #include "storage.hpp" #include "tmw.hpp" @@ -69,6 +72,8 @@ #include "../poison.hpp" +namespace tmwa +{ enum class ATCE { OKAY, @@ -81,12 +86,12 @@ enum class ATCE struct AtCommandInfo { ZString args; - int level; + GmLevel level; ATCE (*proc)(Session *s, dumb_ptr<map_session_data> sd, ZString message); ZString help; - AtCommandInfo(ZString a, int l, ATCE (*p)(Session *s, dumb_ptr<map_session_data>, ZString), ZString h) - : args(a), level(l), proc(p), help(h) + AtCommandInfo(ZString a, uint32_t l, ATCE (*p)(Session *s, dumb_ptr<map_session_data>, ZString), ZString h) + : args(a), level(GmLevel::from(l)), proc(p), help(h) {} }; @@ -121,23 +126,23 @@ void atcommand_config_write(ZString cfgName) if (!out.is_open()) { - FPRINTF(stderr, "Failed to write atcommand config: %s\n", cfgName); + FPRINTF(stderr, "Failed to write atcommand config: %s\n"_fmt, cfgName); return; } - FPRINTF(out, "// Generated by %s\n", CURRENT_VERSION_STRING); + FPRINTF(out, "// Generated by %s\n"_fmt, CURRENT_VERSION_STRING); for (const auto& pair : atcommand_info) { // This XString is really a ZString, but not declared as one // in order to allow non-heterogenous lookup by XString. - const char *cmd = &*pair.first.begin(); + auto cmd = ZString(strings::really_construct_from_a_pointer, &*pair.first.begin(), nullptr); const AtCommandInfo& info = pair.second; FPRINTF(out, "\n" "// %s\n" "// Usage: @%s %s\n" - "%s: %d\n", + "%s: %d\n"_fmt, info.help, cmd, info.args, cmd, info.level); @@ -198,8 +203,8 @@ void log_atcommand(dumb_ptr<map_session_data> sd, ZString cmd) stamp_time(tmpstr); MapName map = (sd->bl_m ? sd->bl_m->name_ - : stringish<MapName>("undefined.gat")); - FPRINTF(*fp, "[%s] %s(%d,%d) %s(%d) : %s\n", + : stringish<MapName>("undefined.gat"_s)); + FPRINTF(*fp, "[%s] %s(%d,%d) %s(%d) : %s\n"_fmt, tmpstr, map, sd->bl_x, sd->bl_y, sd->status_key.name, sd->status_key.account_id, @@ -211,7 +216,7 @@ AString gm_log; io::AppendFile *get_gm_log() { if (!gm_log) - return NULL; + return nullptr; struct tm ctime = TimeT::now(); @@ -225,7 +230,7 @@ io::AppendFile *get_gm_log() return gm_logfile.get(); last_logfile_nr = logfile_nr; - AString fullname = STRPRINTF("%s.%04d-%02d", + AString fullname = STRPRINTF("%s.%04d-%02d"_fmt, gm_log, year, month); if (gm_logfile) @@ -242,7 +247,7 @@ io::AppendFile *get_gm_log() } bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd, - ZString message, int gmlvl) + ZString message, GmLevel gmlvl) { nullpo_retr(false, sd); @@ -259,22 +264,22 @@ bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd, gmlvl = pc_isGM(sd); if (battle_config.atcommand_gm_only != 0 && !gmlvl) { - AString output = STRPRINTF("GM command is level 0, but this server disables level 0 commands: %s", + AString output = STRPRINTF("GM command is level 0, but this server disables level 0 commands: %s"_fmt, AString(command)); clif_displaymessage(s, output); return true; } if (!info) { - AString output = STRPRINTF("GM command not found: %s", + AString output = STRPRINTF("GM command not found: %s"_fmt, AString(command)); clif_displaymessage(s, output); return true; // don't show in chat } - if (info->level > gmlvl) + if (!(gmlvl.satisfies(info->level))) { - AString output = STRPRINTF("GM command is level %d, but you are level %d: %s", + AString output = STRPRINTF("GM command is level %d, but you are level %d: %s"_fmt, info->level, gmlvl, AString(command)); clif_displaymessage(s, output); @@ -292,17 +297,17 @@ bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd, log_atcommand(sd, message); break; case ATCE::USAGE: - clif_displaymessage(s, "Command failed: usage error"); - clif_displaymessage(s, STRPRINTF("Usage: %s %s", AString(command), info->args)); + clif_displaymessage(s, "Command failed: usage error"_s); + clif_displaymessage(s, STRPRINTF("Usage: %s %s"_fmt, AString(command), info->args)); break; case ATCE::EXIST: - clif_displaymessage(s, "Command failed: something does not exist (or already exists)"); + clif_displaymessage(s, "Command failed: something does not exist (or already exists)"_s); break; case ATCE::RANGE: - clif_displaymessage(s, "Command failed: value out of range"); + clif_displaymessage(s, "Command failed: value out of range"_s); break; case ATCE::PERM: - clif_displaymessage(s, "Command failed: permission denied"); + clif_displaymessage(s, "Command failed: permission denied"_s); break; default: abort(); @@ -331,7 +336,7 @@ void atkillmonster_sub(dumb_ptr<block_list> bl, int flag) dumb_ptr<mob_data> md = bl->is_mob(); if (flag) - mob_damage(NULL, md, md->hp, 2); + mob_damage(nullptr, md, md->hp, 2); else mob_delete(md); } @@ -347,7 +352,7 @@ bool atcommand_config_read(ZString cfgName) io::ReadFile in(cfgName); if (!in.is_open()) { - PRINTF("At commands configuration file not found: %s\n", cfgName); + PRINTF("At commands configuration file not found: %s\n"_fmt, cfgName); return false; } @@ -361,24 +366,20 @@ bool atcommand_config_read(ZString cfgName) ZString w2; if (!config_split(line, &w1, &w2)) { - PRINTF("Bad config line: %s\n", line); + PRINTF("Bad config line: %s\n"_fmt, line); rv = false; continue; } AtCommandInfo *p = get_atcommandinfo_byname(w1); - if (p != NULL) + if (p != nullptr) { - p->level = atoi(w2.c_str()); - if (p->level > 100) - p->level = 100; - else if (p->level < 0) - p->level = 0; + p->level = GmLevel::from(static_cast<uint32_t>(atoi(w2.c_str()))); } - else if (w1 == "import") + else if (w1 == "import"_s) rv &= atcommand_config_read(w2); else { - PRINTF("%s: bad line: %s\n", cfgName, line); + PRINTF("%s: bad line: %s\n"_fmt, cfgName, line); rv = false; } } @@ -389,14 +390,16 @@ bool atcommand_config_read(ZString cfgName) /// @ command processing functions static -void atc_do_help(Session *s, const char *cmd, const AtCommandInfo& info) +void atc_do_help(Session *s, ZString cmd, const AtCommandInfo& info) { - auto msg = STRPRINTF("\u2007\u2007%d: @%s %s", info.level, cmd, info.args); + // TODO convert to hex or something + uint32_t level = info.level.get_all_bits(); + auto msg = STRPRINTF("\u2007\u2007%d: @%s %s"_fmt, info.level, cmd, info.args); // manually padding because *space* size_t ll = 1; - if (info.level >= 10) + if (level >= 10) ++ll; - if (info.level >= 100) + if (level >= 100) ++ll; clif_displaymessage(s, msg.xslice_t((ll - 1) * 3)); } @@ -407,9 +410,9 @@ ATCE atcommand_help(Session *s, dumb_ptr<map_session_data>, { if (!message) { - clif_displaymessage(s, "There is too much help to display it all at once"); - clif_displaymessage(s, "Try @help <@command> or @help <category> or @help <level[-level]>"); - clif_displaymessage(s, "Right now the only category is 'all'"); + clif_displaymessage(s, "There is too much help to display it all at once"_s); + clif_displaymessage(s, "Try @help <@command> or @help <category> or @help <level[-level]>"_s); + clif_displaymessage(s, "Right now the only category is 'all'"_s); return ATCE::OKAY; } @@ -419,37 +422,51 @@ ATCE atcommand_help(Session *s, dumb_ptr<map_session_data>, const AtCommandInfo *info = atcommand_info.search(cmd); if (!info) return ATCE::EXIST; - clif_displaymessage(s, STRPRINTF("Usage: @%s %s", cmd, info->args)); + clif_displaymessage(s, STRPRINTF("Usage: @%s %s"_fmt, cmd, info->args)); clif_displaymessage(s, info->help); return ATCE::OKAY; } - if (message == "all") + if (message == "all"_s) { - clif_displaymessage(s, "Synopses of GM commands in category 'all':"); + clif_displaymessage(s, "Synopses of GM commands in category 'all':"_s); for (const auto& pair : atcommand_info) { - const char *cmd = &*pair.first.begin(); + auto cmd = ZString(strings::really_construct_from_a_pointer, &*pair.first.begin(), nullptr); const AtCommandInfo& info = pair.second; atc_do_help(s, cmd, info); } return ATCE::OKAY; } - int low = 0, high; + // previous logic is silly + // + // @help N: list all commands available at level N + // @help M-N: list all commands available at level N that were not at level M + GmLevel low, high; + bool pass; if (extract(message, &high)) - ++high; - else if (!extract(message, record<'-'>(&low, &high))) + { + pass = true; + } + else if (extract(message, record<'-'>(&low, &high))) + { + pass = false; + } + else return ATCE::USAGE; - if (low < 0 || high > 100 || low >= high) + if (low.obsoletes(high)) return ATCE::RANGE; - clif_displaymessage(s, STRPRINTF("Synopses of GM commands in level [%d, %d):", low, high)); + if (pass) + clif_displaymessage(s, STRPRINTF("Synopses of GM commands available at level %u:"_fmt, high)); + else + clif_displaymessage(s, STRPRINTF("Synopses of GM commands available at level %u, but not at level %u:"_fmt, high, low)); for (const auto& pair : atcommand_info) { - const char *cmd = &*pair.first.begin(); + auto cmd = ZString(strings::really_construct_from_a_pointer, &*pair.first.begin(), nullptr); const AtCommandInfo& info = pair.second; - if (low <= info.level && info.level < high) + if ((!low.satisfies(info.level) || pass) && high.satisfies(info.level)) atc_do_help(s, cmd, info); } return ATCE::OKAY; @@ -467,25 +484,25 @@ ATCE atcommand_setup(Session *s, dumb_ptr<map_session_data> sd, level--; AString buf; - buf = STRPRINTF("-255 %s", character); + buf = STRPRINTF("-255 %s"_fmt, character); atcommand_character_baselevel(s, sd, buf); - buf = STRPRINTF("%d %s", level, character); + buf = STRPRINTF("%d %s"_fmt, level, character); atcommand_character_baselevel(s, sd, buf); // Emote skill - buf = STRPRINTF("1 1 %s", character); + buf = STRPRINTF("1 1 %s"_fmt, character); atcommand_skill_learn(s, sd, buf); // Trade skill - buf = STRPRINTF("2 1 %s", character); + buf = STRPRINTF("2 1 %s"_fmt, character); atcommand_skill_learn(s, sd, buf); // Party skill - STRPRINTF("2 2 %s", character); + STRPRINTF("2 2 %s"_fmt, character); atcommand_skill_learn(s, sd, buf); - STRPRINTF("018-1.gat 24 98 %s", character); + STRPRINTF("018-1.gat 24 98 %s"_fmt, character); atcommand_charwarp(s, sd, buf); return ATCE::OKAY; @@ -510,52 +527,52 @@ ATCE atcommand_charwarp(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); if (pl_sd) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can rura+ only lower or same GM level if (x > 0 && x < 800 && y > 0 && y < 800) { map_local *m = map_mapname2mapid(map_name); if (m != nullptr && m->flag.get(MapFlag::NOWARPTO) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))) { clif_displaymessage(s, - "You are not authorised to warp someone to this map."); + "You are not authorised to warp someone to this map."_s); return ATCE::PERM; } if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARP) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp this player from its actual map."); + "You are not authorised to warp this player from its actual map."_s); return ATCE::PERM; } if (pc_setpos(pl_sd, map_name, x, y, BeingRemoveWhy::WARPED) == 0) { - clif_displaymessage(pl_sd->sess, "Warped."); - clif_displaymessage(s, "Player warped (message sends to player too)."); + clif_displaymessage(pl_sd->sess, "Warped."_s); + clif_displaymessage(s, "Player warped (message sends to player too)."_s); } else { - clif_displaymessage(s, "Map not found."); + clif_displaymessage(s, "Map not found."_s); return ATCE::EXIST; } } else { - clif_displaymessage(s, "Coordinates out of range."); + clif_displaymessage(s, "Coordinates out of range."_s); return ATCE::RANGE; } } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -573,7 +590,7 @@ ATCE atcommand_warp(Session *s, dumb_ptr<map_session_data> sd, || !extract(message, record<' ', 1>(&map_name, &x, &y))) { clif_displaymessage(s, - "Please, enter a map (usage: @warp <mapname> <x> <y>)."); + "Please, enter a map (usage: @warp <mapname> <x> <y>)."_s); return ATCE::USAGE; } @@ -586,30 +603,30 @@ ATCE atcommand_warp(Session *s, dumb_ptr<map_session_data> sd, { map_local *m = map_mapname2mapid(map_name); if (m != nullptr && m->flag.get(MapFlag::NOWARPTO) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp you to this map."); + "You are not authorised to warp you to this map."_s); return ATCE::PERM; } if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARP) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp you from your actual map."); + "You are not authorised to warp you from your actual map."_s); return ATCE::PERM; } if (pc_setpos(sd, map_name, x, y, BeingRemoveWhy::WARPED) == 0) - clif_displaymessage(s, "Warped."); + clif_displaymessage(s, "Warped."_s); else { - clif_displaymessage(s, "Map not found."); + clif_displaymessage(s, "Map not found."_s); return ATCE::EXIST; } } else { - clif_displaymessage(s, "Coordinates out of range."); + clif_displaymessage(s, "Coordinates out of range."_s); return ATCE::RANGE; } @@ -624,20 +641,20 @@ ATCE atcommand_where(Session *s, dumb_ptr<map_session_data> sd, extract(message, &character); dumb_ptr<map_session_data> pl_sd = character.to__actual() ? map_nick2sd(character) : sd; - if (pl_sd != NULL && + if (pl_sd != nullptr && !((battle_config.hide_GM_session || bool(pl_sd->status.option & Option::HIDE)) - && (pc_isGM(pl_sd) > pc_isGM(sd)))) + && !(pc_isGM(sd).detects(pc_isGM(pl_sd))))) { // you can look only lower or same level - AString output = STRPRINTF("%s: %s (%d,%d)", + AString output = STRPRINTF("%s: %s (%d,%d)"_fmt, pl_sd->status_key.name, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y); clif_displaymessage(s, output); } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -653,34 +670,34 @@ ATCE atcommand_goto(Session *s, dumb_ptr<map_session_data> sd, if (!asplit(message, &character)) { clif_displaymessage(s, - "Please, enter a player name (usage: @jumpto/@warpto/@goto <char name>)."); + "Please, enter a player name (usage: @jumpto/@warpto/@goto <char name>)."_s); return ATCE::USAGE; } dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARPTO) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp you to the map of this player."); + "You are not authorised to warp you to the map of this player."_s); return ATCE::PERM; } if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARP) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp you from your actual map."); + "You are not authorised to warp you from your actual map."_s); return ATCE::PERM; } pc_setpos(sd, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y, BeingRemoveWhy::WARPED); - AString output = STRPRINTF("Jump to %s", character); + AString output = STRPRINTF("Jump to %s"_fmt, character); clif_displaymessage(s, output); } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -702,26 +719,26 @@ ATCE atcommand_jump(Session *s, dumb_ptr<map_session_data> sd, if (x > 0 && x < 800 && y > 0 && y < 800) { if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARPTO) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp you to your actual map."); + "You are not authorised to warp you to your actual map."_s); return ATCE::PERM; } if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARP) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp you from your actual map."); + "You are not authorised to warp you from your actual map."_s); return ATCE::PERM; } pc_setpos(sd, sd->mapname_, x, y, BeingRemoveWhy::WARPED); - AString output = STRPRINTF("Jump to %d %d", x, y); + AString output = STRPRINTF("Jump to %d %d"_fmt, x, y); clif_displaymessage(s, output); } else { - clif_displaymessage(s, "Coordinates out of range."); + clif_displaymessage(s, "Coordinates out of range."_s); return ATCE::RANGE; } @@ -733,12 +750,11 @@ ATCE atcommand_who(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - int pl_GM_level, GM_level; VString<23> match_text = message; match_text = match_text.to_lower(); count = 0; - GM_level = pc_isGM(sd); + GmLevel gm_level = pc_isGM(sd); for (io::FD i : iter_fds()) { Session *s2 = get_session(i); @@ -747,11 +763,11 @@ ATCE atcommand_who(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); if (pl_sd && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); + GmLevel pl_gm_level = pc_isGM(pl_sd); if (! ((battle_config.hide_GM_session || bool(pl_sd->status.option & Option::HIDE)) - && (pl_GM_level > GM_level))) + && !(gm_level.detects(pl_gm_level)))) { // you can look only lower or same level VString<23> player_name = pl_sd->status_key.name.to__lower(); @@ -759,14 +775,14 @@ ATCE atcommand_who(Session *s, dumb_ptr<map_session_data> sd, { // search with no case sensitive AString output; - if (pl_GM_level > 0) + if (pl_gm_level) output = STRPRINTF( - "Name: %s (GM:%d) | Location: %s %d %d", - pl_sd->status_key.name, pl_GM_level, + "Name: %s (GM:%u) | Location: %s %d %d"_fmt, + pl_sd->status_key.name, pl_gm_level, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y); else output = STRPRINTF( - "Name: %s | Location: %s %d %d", + "Name: %s | Location: %s %d %d"_fmt, pl_sd->status_key.name, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y); clif_displaymessage(s, output); @@ -777,12 +793,12 @@ ATCE atcommand_who(Session *s, dumb_ptr<map_session_data> sd, } if (count == 0) - clif_displaymessage(s, "No player found."); + clif_displaymessage(s, "No player found."_s); else if (count == 1) - clif_displaymessage(s, "1 player found."); + clif_displaymessage(s, "1 player found."_s); else { - AString output = STRPRINTF("%d players found.", count); + AString output = STRPRINTF("%d players found."_fmt, count); clif_displaymessage(s, output); } @@ -794,14 +810,13 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - int pl_GM_level, GM_level; - struct party *p; + PartyPair p; VString<23> match_text = message; match_text = match_text.to_lower(); count = 0; - GM_level = pc_isGM(sd); + GmLevel gm_level = pc_isGM(sd); for (io::FD i : iter_fds()) { Session *s2 = get_session(i); @@ -810,11 +825,11 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); if (pl_sd && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); + GmLevel pl_gm_level = pc_isGM(pl_sd); if (! ((battle_config.hide_GM_session || bool(pl_sd->status.option & Option::HIDE)) - && (pl_GM_level > GM_level))) + && (!(gm_level.detects(pl_gm_level))))) { // you can look only lower or same level VString<23> player_name = pl_sd->status_key.name.to__lower(); @@ -822,12 +837,12 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd, { // search with no case sensitive p = party_search(pl_sd->status.party_id); - PartyName temp0 = p ? p->name : stringish<PartyName>("None"); + PartyName temp0 = p ? p->name : stringish<PartyName>("None"_s); AString output; - if (pl_GM_level > 0) + if (pl_gm_level) output = STRPRINTF( - "Name: %s (GM:%d) | Party: '%s'", - pl_sd->status_key.name, pl_GM_level, temp0); + "Name: %s (GM:%d) | Party: '%s'"_fmt, + pl_sd->status_key.name, pl_gm_level, temp0); clif_displaymessage(s, output); count++; } @@ -836,12 +851,12 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd, } if (count == 0) - clif_displaymessage(s, "No player found."); + clif_displaymessage(s, "No player found."_s); else if (count == 1) - clif_displaymessage(s, "1 player found."); + clif_displaymessage(s, "1 player found."_s); else { - AString output = STRPRINTF("%d players found.", count); + AString output = STRPRINTF("%d players found."_fmt, count); clif_displaymessage(s, output); } @@ -853,7 +868,6 @@ ATCE atcommand_whomap(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - int pl_GM_level, GM_level; map_local *map_id; { @@ -865,7 +879,7 @@ ATCE atcommand_whomap(Session *s, dumb_ptr<map_session_data> sd, } count = 0; - GM_level = pc_isGM(sd); + GmLevel gm_level = pc_isGM(sd); for (io::FD i : iter_fds()) { Session *s2 = get_session(i); @@ -874,24 +888,24 @@ ATCE atcommand_whomap(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); if (pl_sd && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); + GmLevel pl_gm_level = pc_isGM(pl_sd); if (! ((battle_config.hide_GM_session || bool(pl_sd->status.option & Option::HIDE)) - && (pl_GM_level > GM_level))) + && (!(gm_level.detects(pl_gm_level))))) { // you can look only lower or same level if (pl_sd->bl_m == map_id) { AString output; - if (pl_GM_level > 0) + if (pl_gm_level) output = STRPRINTF( - "Name: %s (GM:%d) | Location: %s %d %d", - pl_sd->status_key.name, pl_GM_level, + "Name: %s (GM:%d) | Location: %s %d %d"_fmt, + pl_sd->status_key.name, pl_gm_level, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y); else output = STRPRINTF( - "Name: %s | Location: %s %d %d", + "Name: %s | Location: %s %d %d"_fmt, pl_sd->status_key.name, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y); clif_displaymessage(s, output); @@ -901,7 +915,7 @@ ATCE atcommand_whomap(Session *s, dumb_ptr<map_session_data> sd, } } - AString output = STRPRINTF("%d players found in map '%s'.", + AString output = STRPRINTF("%d players found in map '%s'."_fmt, count, map_id->name_); clif_displaymessage(s, output); @@ -913,8 +927,7 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - int pl_GM_level, GM_level; - struct party *p; + PartyPair p; map_local *map_id; { @@ -926,7 +939,7 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd, } count = 0; - GM_level = pc_isGM(sd); + GmLevel gm_level = pc_isGM(sd); for (io::FD i : iter_fds()) { Session *s2 = get_session(i); @@ -935,23 +948,23 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); if (pl_sd && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); + GmLevel pl_gm_level = pc_isGM(pl_sd); if (! ((battle_config.hide_GM_session || bool(pl_sd->status.option & Option::HIDE)) - && (pl_GM_level > GM_level))) + && (!(gm_level.detects(pl_gm_level))))) { // you can look only lower or same level if (pl_sd->bl_m == map_id) { p = party_search(pl_sd->status.party_id); - PartyName temp0 = p ? p->name : stringish<PartyName>("None"); + PartyName temp0 = p ? p->name : stringish<PartyName>("None"_s); AString output; - if (pl_GM_level > 0) - output = STRPRINTF("Name: %s (GM:%d) | Party: '%s'", - pl_sd->status_key.name, pl_GM_level, temp0); + if (pl_gm_level) + output = STRPRINTF("Name: %s (GM:%d) | Party: '%s'"_fmt, + pl_sd->status_key.name, pl_gm_level, temp0); else - output = STRPRINTF("Name: %s | Party: '%s'", + output = STRPRINTF("Name: %s | Party: '%s'"_fmt, pl_sd->status_key.name, temp0); clif_displaymessage(s, output); count++; @@ -962,12 +975,12 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd, AString output; if (count == 0) - output = STRPRINTF("No player found in map '%s'.", map_id->name_); + output = STRPRINTF("No player found in map '%s'."_fmt, map_id->name_); else if (count == 1) - output = STRPRINTF("1 player found in map '%s'.", map_id->name_); + output = STRPRINTF("1 player found in map '%s'."_fmt, map_id->name_); else { - output = STRPRINTF("%d players found in map '%s'.", count, map_id->name_); + output = STRPRINTF("%d players found in map '%s'."_fmt, count, map_id->name_); } clif_displaymessage(s, output); @@ -979,14 +992,13 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - int pl_GM_level, GM_level; - struct party *p; + PartyPair p; VString<23> match_text = message; match_text = match_text.to_lower(); count = 0; - GM_level = pc_isGM(sd); + GmLevel gm_level = pc_isGM(sd); for (io::FD i : iter_fds()) { Session *s2 = get_session(i); @@ -995,13 +1007,13 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); if (pl_sd && pl_sd->state.auth) { - pl_GM_level = pc_isGM(pl_sd); - if (pl_GM_level > 0) + GmLevel pl_gm_level = pc_isGM(pl_sd); + if (pl_gm_level) { if (! ((battle_config.hide_GM_session || bool(pl_sd->status.option & Option::HIDE)) - && (pl_GM_level > GM_level))) + && (!(gm_level.detects(pl_gm_level))))) { // you can look only lower or same level VString<23> player_name = pl_sd->status_key.name.to__lower(); @@ -1010,20 +1022,20 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd, // search with no case sensitive AString output; output = STRPRINTF( - "Name: %s (GM:%d) | Location: %s %d %d", - pl_sd->status_key.name, pl_GM_level, + "Name: %s (GM:%d) | Location: %s %d %d"_fmt, + pl_sd->status_key.name, pl_gm_level, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y); clif_displaymessage(s, output); output = STRPRINTF( - " BLvl: %d | Job: %s (Lvl: %d)", + " BLvl: %d | Job: %s (Lvl: %d)"_fmt, pl_sd->status.base_level, - "Novice/Human", + "Novice/Human"_s, pl_sd->status.job_level); clif_displaymessage(s, output); p = party_search(pl_sd->status.party_id); - PartyName temp0 = p ? p->name : stringish<PartyName>("None"); + PartyName temp0 = p ? p->name : stringish<PartyName>("None"_s); output = STRPRINTF( - " Party: '%s'", + " Party: '%s'"_fmt, temp0); clif_displaymessage(s, output); count++; @@ -1034,12 +1046,12 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd, } if (count == 0) - clif_displaymessage(s, "No GM found."); + clif_displaymessage(s, "No GM found."_s); else if (count == 1) - clif_displaymessage(s, "1 GM found."); + clif_displaymessage(s, "1 GM found."_s); else { - AString output = STRPRINTF("%d GMs found.", count); + AString output = STRPRINTF("%d GMs found."_fmt, count); clif_displaymessage(s, output); } @@ -1053,7 +1065,7 @@ ATCE atcommand_save(Session *s, dumb_ptr<map_session_data> sd, pc_setsavepoint(sd, sd->mapname_, sd->bl_x, sd->bl_y); pc_makesavestatus(sd); chrif_save(sd); - clif_displaymessage(s, "Character data respawn point saved."); + clif_displaymessage(s, "Character data respawn point saved."_s); return ATCE::OKAY; } @@ -1064,17 +1076,17 @@ ATCE atcommand_load(Session *s, dumb_ptr<map_session_data> sd, { map_local *m = map_mapname2mapid(sd->status.save_point.map_); if (m != nullptr && m->flag.get(MapFlag::NOWARPTO) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp you to your save map."); + "You are not authorised to warp you to your save map."_s); return ATCE::PERM; } if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARP) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp you from your actual map."); + "You are not authorised to warp you from your actual map."_s); return ATCE::PERM; } @@ -1089,7 +1101,7 @@ ATCE atcommand_load(Session *s, dumb_ptr<map_session_data> sd, pc_setpos(sd, sd->status.save_point.map_, sd->status.save_point.x, sd->status.save_point.y, BeingRemoveWhy::GONE); } - clif_displaymessage(s, "Warping to respawn point."); + clif_displaymessage(s, "Warping to respawn point."_s); return ATCE::OKAY; } @@ -1101,7 +1113,7 @@ ATCE atcommand_speed(Session *s, dumb_ptr<map_session_data> sd, if (!message) { AString output = STRPRINTF( - "Please, enter a speed value (usage: @speed <%d-%d>).", + "Please, enter a speed value (usage: @speed <%d-%d>)."_fmt, static_cast<uint32_t>(MIN_WALK_SPEED.count()), static_cast<uint32_t>(MAX_WALK_SPEED.count())); clif_displaymessage(s, output); @@ -1115,12 +1127,12 @@ ATCE atcommand_speed(Session *s, dumb_ptr<map_session_data> sd, //sd->walktimer = x; //この文を追加 by れ clif_updatestatus(sd, SP::SPEED); - clif_displaymessage(s, "Speed changed."); + clif_displaymessage(s, "Speed changed."_s); } else { AString output = STRPRINTF( - "Please, enter a valid speed value (usage: @speed <%d-%d>).", + "Please, enter a valid speed value (usage: @speed <%d-%d>)."_fmt, static_cast<uint32_t>(MIN_WALK_SPEED.count()), static_cast<uint32_t>(MAX_WALK_SPEED.count())); clif_displaymessage(s, output); @@ -1134,18 +1146,18 @@ static ATCE atcommand_storage(Session *s, dumb_ptr<map_session_data> sd, ZString) { - struct storage *stor; + Storage *stor; if (sd->state.storage_open) { - clif_displaymessage(s, "msg_table[250]"); + clif_displaymessage(s, "msg_table[250]"_s); return ATCE::EXIST; } - if ((stor = account2storage2(sd->status_key.account_id)) != NULL + if ((stor = account2storage2(sd->status_key.account_id)) != nullptr && stor->storage_status == 1) { - clif_displaymessage(s, "msg_table[250]"); + clif_displaymessage(s, "msg_table[250]"_s); return ATCE::EXIST; } @@ -1171,7 +1183,7 @@ ATCE atcommand_option(Session *s, dumb_ptr<map_session_data> sd, clif_changeoption(sd); pc_calcstatus(sd, 0); - clif_displaymessage(s, "Options changed."); + clif_displaymessage(s, "Options changed."_s); return ATCE::OKAY; } @@ -1183,12 +1195,12 @@ ATCE atcommand_hide(Session *s, dumb_ptr<map_session_data> sd, if (bool(sd->status.option & Option::HIDE)) { sd->status.option &= ~Option::HIDE; - clif_displaymessage(s, "Invisible: Off."); + clif_displaymessage(s, "Invisible: Off."_s); } else { sd->status.option |= Option::HIDE; - clif_displaymessage(s, "Invisible: On."); + clif_displaymessage(s, "Invisible: On."_s); } clif_changeoption(sd); @@ -1199,8 +1211,8 @@ static ATCE atcommand_die(Session *s, dumb_ptr<map_session_data> sd, ZString) { - pc_damage(NULL, sd, sd->status.hp + 1); - clif_displaymessage(s, "A pity! You've died."); + pc_damage(nullptr, sd, sd->status.hp + 1); + clif_displaymessage(s, "A pity! You've died."_s); return ATCE::OKAY; } @@ -1215,23 +1227,23 @@ ATCE atcommand_kill(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can kill only lower or same level - pc_damage(NULL, pl_sd, pl_sd->status.hp + 1); - clif_displaymessage(s, "Character killed."); + pc_damage(nullptr, pl_sd, pl_sd->status.hp + 1); + clif_displaymessage(s, "Character killed."_s); } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -1250,7 +1262,7 @@ ATCE atcommand_alive(Session *s, dumb_ptr<map_session_data> sd, clif_updatestatus(sd, SP::HP); clif_updatestatus(sd, SP::SP); clif_resurrection(sd, 1); - clif_displaymessage(s, "You've been revived! It's a miracle!"); + clif_displaymessage(s, "You've been revived! It's a miracle!"_s); return ATCE::OKAY; } @@ -1304,13 +1316,13 @@ ATCE atcommand_heal(Session *s, dumb_ptr<map_session_data> sd, { pc_heal(sd, hp, sp); if (hp >= 0 && sp >= 0) - clif_displaymessage(s, "HP, SP recovered."); + clif_displaymessage(s, "HP, SP recovered."_s); else - clif_displaymessage(s, "HP or/and SP modified."); + clif_displaymessage(s, "HP or/and SP modified."_s); } else { - clif_displaymessage(s, "HP and SP are already with the good value."); + clif_displaymessage(s, "HP and SP are already with the good value."_s); return ATCE::RANGE; } @@ -1322,29 +1334,29 @@ ATCE atcommand_item(Session *s, dumb_ptr<map_session_data> sd, ZString message) { XString item_name; - int number = 0, item_id; - struct item_data *item_data = NULL; + int number = 0; + ItemNameId item_id; + struct item_data *item_data = nullptr; int get_count, i; if (!extract(message, record<' ', 1>(&item_name, &number))) { clif_displaymessage(s, - "Please, enter an item name/id (usage: @item <item name or ID> [quantity])."); + "Please, enter an item name/id (usage: @item <item name or ID> [quantity])."_s); return ATCE::USAGE; } if (number <= 0) number = 1; - item_id = 0; - if ((item_data = itemdb_searchname(item_name)) != NULL) + if ((item_data = itemdb_searchname(item_name)) != nullptr) item_id = item_data->nameid; - else if (extract(item_name, &item_id) && (item_data = itemdb_exists(item_id)) != NULL) + else if (extract(item_name, &item_id) && (item_data = itemdb_exists(item_id)) != nullptr) item_id = item_data->nameid; else - item_id = 0; + return ATCE::EXIST; - if (item_id >= 500) + if (item_id) { get_count = number; if (item_data->type == ItemType::WEAPON @@ -1356,18 +1368,18 @@ ATCE atcommand_item(Session *s, dumb_ptr<map_session_data> sd, } for (i = 0; i < number; i += get_count) { - struct item item_tmp {}; + Item item_tmp {}; item_tmp.nameid = item_id; PickupFail flag; if ((flag = pc_additem(sd, &item_tmp, get_count)) != PickupFail::OKAY) - clif_additem(sd, 0, 0, flag); + clif_additem(sd, IOff0::from(0), 0, flag); } - clif_displaymessage(s, "Item created."); + clif_displaymessage(s, "Item created."_s); } else { - clif_displaymessage(s, "Invalid item ID or name."); + clif_displaymessage(s, "Invalid item ID or name."_s); return ATCE::EXIST; } @@ -1378,15 +1390,13 @@ static ATCE atcommand_itemreset(Session *s, dumb_ptr<map_session_data> sd, ZString) { - int i; - - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == EPOS::ZERO) pc_delitem(sd, i, sd->status.inventory[i].amount, 0); } - clif_displaymessage(s, "All of your items have been removed."); + clif_displaymessage(s, "All of your items have been removed."_s); return ATCE::OKAY; } @@ -1409,7 +1419,7 @@ ATCE atcommand_baselevelup(Session *s, dumb_ptr<map_session_data> sd, if (!extract(message, &level) || !level) { clif_displaymessage(s, - "Please, enter a level adjustement (usage: @blvl <number of levels>)."); + "Please, enter a level adjustement (usage: @blvl <number of levels>)."_s); return ATCE::USAGE; } @@ -1417,7 +1427,7 @@ ATCE atcommand_baselevelup(Session *s, dumb_ptr<map_session_data> sd, { if (sd->status.base_level == battle_config.maximum_level) { - clif_displaymessage(s, "Base level can't go any higher."); + clif_displaymessage(s, "Base level can't go any higher."_s); return ATCE::RANGE; } if (level > battle_config.maximum_level || level > (battle_config.maximum_level - sd->status.base_level)) @@ -1432,13 +1442,13 @@ ATCE atcommand_baselevelup(Session *s, dumb_ptr<map_session_data> sd, pc_calcstatus(sd, 0); pc_heal(sd, sd->status.max_hp, sd->status.max_sp); clif_misceffect(sd, 0); - clif_displaymessage(s, "Base level raised."); + clif_displaymessage(s, "Base level raised."_s); } else { if (sd->status.base_level == 1) { - clif_displaymessage(s, "Base level can't go any lower."); + clif_displaymessage(s, "Base level can't go any lower."_s); return ATCE::USAGE; } if (level < -battle_config.maximum_level || level < (1 - sd->status.base_level)) @@ -1458,7 +1468,7 @@ ATCE atcommand_baselevelup(Session *s, dumb_ptr<map_session_data> sd, clif_updatestatus(sd, SP::BASELEVEL); clif_updatestatus(sd, SP::NEXTBASEEXP); pc_calcstatus(sd, 0); - clif_displaymessage(s, "Base level lowered."); + clif_displaymessage(s, "Base level lowered."_s); } return ATCE::OKAY; @@ -1481,7 +1491,7 @@ ATCE atcommand_joblevelup(Session *s, dumb_ptr<map_session_data> sd, { if (sd->status.job_level == up_level) { - clif_displaymessage(s, "Job level can't go any higher."); + clif_displaymessage(s, "Job level can't go any higher."_s); return ATCE::RANGE; } if (level > up_level || level > (up_level - sd->status.job_level)) @@ -1494,13 +1504,13 @@ ATCE atcommand_joblevelup(Session *s, dumb_ptr<map_session_data> sd, clif_updatestatus(sd, SP::SKILLPOINT); pc_calcstatus(sd, 0); clif_misceffect(sd, 1); - clif_displaymessage(s, "Job level raised."); + clif_displaymessage(s, "Job level raised."_s); } else { if (sd->status.job_level == 1) { - clif_displaymessage(s, "Job level can't go any lower."); + clif_displaymessage(s, "Job level can't go any lower."_s); return ATCE::RANGE; } if (level < -up_level || level < (1 - sd->status.job_level)) @@ -1518,7 +1528,7 @@ ATCE atcommand_joblevelup(Session *s, dumb_ptr<map_session_data> sd, } // to add: remove status points from skills pc_calcstatus(sd, 0); - clif_displaymessage(s, "Job level lowered."); + clif_displaymessage(s, "Job level lowered."_s); } return ATCE::OKAY; @@ -1534,7 +1544,7 @@ ATCE atcommand_gm(Session *s, dumb_ptr<map_session_data> sd, if (pc_isGM(sd)) { // a GM can not use this function. only a normal player (become gm is not for gm!) - clif_displaymessage(s, "You already have some GM powers."); + clif_displaymessage(s, "You already have some GM powers."_s); return ATCE::PERM; } else @@ -1550,7 +1560,7 @@ ATCE atcommand_pvpoff(Session *s, dumb_ptr<map_session_data> sd, if (battle_config.pk_mode) { //disable command if server is in PK mode [Valaris] - clif_displaymessage(s, "This option cannot be used in PK Mode."); + clif_displaymessage(s, "This option cannot be used in PK Mode."_s); return ATCE::EXIST; } @@ -1571,11 +1581,11 @@ ATCE atcommand_pvpoff(Session *s, dumb_ptr<map_session_data> sd, } } } - clif_displaymessage(s, "PvP: Off."); + clif_displaymessage(s, "PvP: Off."_s); } else { - clif_displaymessage(s, "PvP is already Off."); + clif_displaymessage(s, "PvP is already Off."_s); return ATCE::EXIST; } @@ -1589,7 +1599,7 @@ ATCE atcommand_pvpon(Session *s, dumb_ptr<map_session_data> sd, if (battle_config.pk_mode) { //disable command if server is in PK mode [Valaris] - clif_displaymessage(s, "This option cannot be used in PK Mode."); + clif_displaymessage(s, "This option cannot be used in PK Mode."_s); return ATCE::EXIST; } @@ -1606,7 +1616,7 @@ ATCE atcommand_pvpon(Session *s, dumb_ptr<map_session_data> sd, { if (sd->bl_m == pl_sd->bl_m && !pl_sd->pvp_timer) { - pl_sd->pvp_timer = Timer(gettick() + std::chrono::milliseconds(200), + pl_sd->pvp_timer = Timer(gettick() + 200_ms, std::bind(pc_calc_pvprank_timer, ph::_1, ph::_2, pl_sd->bl_id)); pl_sd->pvp_rank = 0; pl_sd->pvp_lastusers = 0; @@ -1614,11 +1624,11 @@ ATCE atcommand_pvpon(Session *s, dumb_ptr<map_session_data> sd, } } } - clif_displaymessage(s, "PvP: On."); + clif_displaymessage(s, "PvP: On."_s); } else { - clif_displaymessage(s, "PvP is already On."); + clif_displaymessage(s, "PvP is already On."_s); return ATCE::EXIST; } @@ -1642,7 +1652,7 @@ ATCE atcommand_model(Session *s, dumb_ptr<map_session_data> sd, pc_changelook(sd, LOOK::HAIR, hair_style); pc_changelook(sd, LOOK::HAIR_COLOR, hair_color); pc_changelook(sd, LOOK::CLOTHES_COLOR, cloth_color); - clif_displaymessage(s, "Appearence changed."); + clif_displaymessage(s, "Appearence changed."_s); } } else @@ -1664,7 +1674,7 @@ ATCE atcommand_dye(Session *s, dumb_ptr<map_session_data> sd, { { pc_changelook(sd, LOOK::CLOTHES_COLOR, cloth_color); - clif_displaymessage(s, "Appearence changed."); + clif_displaymessage(s, "Appearence changed."_s); } } else @@ -1686,7 +1696,7 @@ ATCE atcommand_hair_style(Session *s, dumb_ptr<map_session_data> sd, { { pc_changelook(sd, LOOK::HAIR, hair_style); - clif_displaymessage(s, "Appearence changed."); + clif_displaymessage(s, "Appearence changed."_s); } } else @@ -1708,7 +1718,7 @@ ATCE atcommand_hair_color(Session *s, dumb_ptr<map_session_data> sd, { { pc_changelook(sd, LOOK::HAIR_COLOR, hair_color); - clif_displaymessage(s, "Appearence changed."); + clif_displaymessage(s, "Appearence changed."_s); } } else @@ -1722,22 +1732,21 @@ ATCE atcommand_spawn(Session *s, dumb_ptr<map_session_data> sd, ZString message) { MobName monster; - int mob_id; + Species mob_id; int number = 0; int x = 0, y = 0; int count; - int i, j, k; int mx, my, range; if (!extract(message, record<' ', 1>(&monster, &number, &x, &y))) return ATCE::USAGE; // If monster identifier/name argument is a name - if ((mob_id = mobdb_searchname(monster)) == 0) + if ((mob_id = mobdb_searchname(monster)) == Species()) // check name first (to avoid possible name begining by a number) - mob_id = mobdb_checkid(atoi(monster.c_str())); + mob_id = mobdb_checkid(wrap<Species>(atoi(monster.c_str()))); - if (mob_id == 0) + if (mob_id == Species()) return ATCE::EXIST; if (number <= 0) @@ -1749,18 +1758,18 @@ ATCE atcommand_spawn(Session *s, dumb_ptr<map_session_data> sd, number = battle_config.atcommand_spawn_quantity_limit; if (battle_config.etc_log) - PRINTF("@spawn monster='%s' id=%d count=%d (%d,%d)\n", + PRINTF("@spawn monster='%s' id=%d count=%d (%d,%d)\n"_fmt, monster, mob_id, number, x, y); count = 0; range = sqrt(number) / 2; range = range * 2 + 5; // calculation of an odd number (+ 4 area around) - for (i = 0; i < number; i++) + for (int i = 0; i < number; i++) { - j = 0; - k = 0; - while (j++ < 8 && k == 0) + int j = 0; + BlockId k; + while (j++ < 8 && !k) { // try 8 times to spawn the monster (needed for close area) if (x <= 0) @@ -1773,21 +1782,21 @@ ATCE atcommand_spawn(Session *s, dumb_ptr<map_session_data> sd, my = y; k = mob_once_spawn(sd, MOB_THIS_MAP, mx, my, MobName(), mob_id, 1, NpcEvent()); } - count += (k != 0) ? 1 : 0; + count += k ? 1 : 0; } if (count != 0) if (number == count) - clif_displaymessage(s, "All monster summoned!"); + clif_displaymessage(s, "All monster summoned!"_s); else { - AString output = STRPRINTF("%d monster(s) summoned!", + AString output = STRPRINTF("%d monster(s) summoned!"_fmt, count); clif_displaymessage(s, output); } else { - clif_displaymessage(s, "Invalid monster ID or name."); + clif_displaymessage(s, "Invalid monster ID or name."_s); return ATCE::EXIST; } @@ -1813,7 +1822,7 @@ void atcommand_killmonster_sub(Session *s, dumb_ptr<map_session_data> sd, map_id->xs, map_id->ys, BL::MOB); - clif_displaymessage(s, "All monsters killed!"); + clif_displaymessage(s, "All monsters killed!"_s); } static @@ -1830,7 +1839,7 @@ void atlist_nearby_sub(dumb_ptr<block_list> bl, Session *s) { nullpo_retv(bl); - AString buf = STRPRINTF(" - \"%s\"", + AString buf = STRPRINTF(" - \"%s\""_fmt, bl->is_player()->status_key.name); clif_displaymessage(s, buf); } @@ -1839,7 +1848,7 @@ static ATCE atcommand_list_nearby(Session *s, dumb_ptr<map_session_data> sd, ZString) { - clif_displaymessage(s, "Nearby players:"); + clif_displaymessage(s, "Nearby players:"_s); map_foreachinarea(std::bind(atlist_nearby_sub, ph::_1, s), sd->bl_m, sd->bl_x - 1, sd->bl_y - 1, @@ -1867,7 +1876,7 @@ ATCE atcommand_gat(Session *s, dumb_ptr<map_session_data> sd, for (y = 2; y >= -2; y--) { AString output = STRPRINTF( - "%s (x= %d, y= %d) %02X %02X %02X %02X %02X", + "%s (x= %d, y= %d) %02X %02X %02X %02X %02X"_fmt, sd->bl_m->name_, sd->bl_x - 2, sd->bl_y + y, map_getcell(sd->bl_m, sd->bl_x - 2, sd->bl_y + y), map_getcell(sd->bl_m, sd->bl_x - 1, sd->bl_y + y), @@ -1916,7 +1925,7 @@ ATCE atcommand_statuspoint(Session *s, dumb_ptr<map_session_data> sd, { sd->status.status_point = new_status_point; clif_updatestatus(sd, SP::STATUSPOINT); - clif_displaymessage(s, "Number of status points changed!"); + clif_displaymessage(s, "Number of status points changed!"_s); } else return ATCE::RANGE; @@ -1945,7 +1954,7 @@ ATCE atcommand_skillpoint(Session *s, dumb_ptr<map_session_data> sd, { sd->status.skill_point = new_skill_point; clif_updatestatus(sd, SP::SKILLPOINT); - clif_displaymessage(s, "Number of skill points changed!"); + clif_displaymessage(s, "Number of skill points changed!"_s); } else return ATCE::RANGE; @@ -1974,7 +1983,7 @@ ATCE atcommand_zeny(Session *s, dumb_ptr<map_session_data> sd, { sd->status.zeny = new_zeny; clif_updatestatus(sd, SP::ZENY); - clif_displaymessage(s, "Number of zenys changed!"); + clif_displaymessage(s, "Number of zenys changed!"_s); } else return ATCE::RANGE; @@ -2006,7 +2015,7 @@ ATCE atcommand_param(Session *s, dumb_ptr<map_session_data> sd, clif_updatestatus(sd, attr_to_sp(attr)); clif_updatestatus(sd, attr_to_usp(attr)); pc_calcstatus(sd, 0); - clif_displaymessage(s, "Stat changed."); + clif_displaymessage(s, "Stat changed."_s); } else return ATCE::RANGE; @@ -2047,7 +2056,7 @@ ATCE atcommand_all_stats(Session *s, dumb_ptr<map_session_data> sd, if (count > 0) // if at least 1 stat modified - clif_displaymessage(s, "All stats changed!"); + clif_displaymessage(s, "All stats changed!"_s); else return ATCE::RANGE; @@ -2064,38 +2073,38 @@ ATCE atcommand_recall(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can recall only lower or same level if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARPTO) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp somenone to your actual map."); + "You are not authorised to warp somenone to your actual map."_s); return ATCE::PERM; } if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARP) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp this player from its actual map."); + "You are not authorised to warp this player from its actual map."_s); return ATCE::PERM; } pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); - AString output = STRPRINTF("%s recalled!", character); + AString output = STRPRINTF("%s recalled!"_fmt, character); clif_displaymessage(s, output); } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -2112,7 +2121,7 @@ ATCE atcommand_revive(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { pl_sd->status.hp = pl_sd->status.max_hp; pc_setstand(pl_sd); @@ -2121,11 +2130,11 @@ ATCE atcommand_revive(Session *s, dumb_ptr<map_session_data> sd, clif_updatestatus(pl_sd, SP::HP); clif_updatestatus(pl_sd, SP::SP); clif_resurrection(pl_sd, 1); - clif_displaymessage(s, "Character revived."); + clif_displaymessage(s, "Character revived."_s); } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -2142,41 +2151,41 @@ ATCE atcommand_character_stats(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { AString output; - output = STRPRINTF("'%s' stats:", pl_sd->status_key.name); + output = STRPRINTF("'%s' stats:"_fmt, pl_sd->status_key.name); clif_displaymessage(s, output); - output = STRPRINTF("Base Level - %d", pl_sd->status.base_level), + output = STRPRINTF("Base Level - %d"_fmt, pl_sd->status.base_level); clif_displaymessage(s, output); - output = STRPRINTF("Job - Novice/Human (level %d)", pl_sd->status.job_level); + output = STRPRINTF("Job - Novice/Human (level %d)"_fmt, pl_sd->status.job_level); clif_displaymessage(s, output); - output = STRPRINTF("Hp - %d", pl_sd->status.hp); + output = STRPRINTF("Hp - %d"_fmt, pl_sd->status.hp); clif_displaymessage(s, output); - output = STRPRINTF("MaxHp - %d", pl_sd->status.max_hp); + output = STRPRINTF("MaxHp - %d"_fmt, pl_sd->status.max_hp); clif_displaymessage(s, output); - output = STRPRINTF("Sp - %d", pl_sd->status.sp); + output = STRPRINTF("Sp - %d"_fmt, pl_sd->status.sp); clif_displaymessage(s, output); - output = STRPRINTF("MaxSp - %d", pl_sd->status.max_sp); + output = STRPRINTF("MaxSp - %d"_fmt, pl_sd->status.max_sp); clif_displaymessage(s, output); - output = STRPRINTF("Str - %3d", pl_sd->status.attrs[ATTR::STR]); + output = STRPRINTF("Str - %3d"_fmt, pl_sd->status.attrs[ATTR::STR]); clif_displaymessage(s, output); - output = STRPRINTF("Agi - %3d", pl_sd->status.attrs[ATTR::AGI]); + output = STRPRINTF("Agi - %3d"_fmt, pl_sd->status.attrs[ATTR::AGI]); clif_displaymessage(s, output); - output = STRPRINTF("Vit - %3d", pl_sd->status.attrs[ATTR::VIT]); + output = STRPRINTF("Vit - %3d"_fmt, pl_sd->status.attrs[ATTR::VIT]); clif_displaymessage(s, output); - output = STRPRINTF("Int - %3d", pl_sd->status.attrs[ATTR::INT]); + output = STRPRINTF("Int - %3d"_fmt, pl_sd->status.attrs[ATTR::INT]); clif_displaymessage(s, output); - output = STRPRINTF("Dex - %3d", pl_sd->status.attrs[ATTR::DEX]); + output = STRPRINTF("Dex - %3d"_fmt, pl_sd->status.attrs[ATTR::DEX]); clif_displaymessage(s, output); - output = STRPRINTF("Luk - %3d", pl_sd->status.attrs[ATTR::LUK]); + output = STRPRINTF("Luk - %3d"_fmt, pl_sd->status.attrs[ATTR::LUK]); clif_displaymessage(s, output); - output = STRPRINTF("Zeny - %d", pl_sd->status.zeny); + output = STRPRINTF("Zeny - %d"_fmt, pl_sd->status.zeny); clif_displaymessage(s, output); } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -2199,41 +2208,41 @@ ATCE atcommand_character_stats_all(Session *s, dumb_ptr<map_session_data>, if (pl_sd && pl_sd->state.auth) { AString gmlevel; - if (pc_isGM(pl_sd) > 0) - gmlevel = STRPRINTF("| GM Lvl: %d", pc_isGM(pl_sd)); + if (GmLevel pl_gm_level = pc_isGM(pl_sd)) + gmlevel = STRPRINTF("| GM Lvl: %d"_fmt, pl_gm_level); else - gmlevel = " "; + gmlevel = " "_s; AString output; output = STRPRINTF( - "Name: %s | BLvl: %d | Job: Novice/Human (Lvl: %d) | HP: %d/%d | SP: %d/%d", + "Name: %s | BLvl: %d | Job: Novice/Human (Lvl: %d) | HP: %d/%d | SP: %d/%d"_fmt, pl_sd->status_key.name, pl_sd->status.base_level, pl_sd->status.job_level, pl_sd->status.hp, pl_sd->status.max_hp, pl_sd->status.sp, pl_sd->status.max_sp); clif_displaymessage(s, output); - output = STRPRINTF("STR: %d | AGI: %d | VIT: %d | INT: %d | DEX: %d | LUK: %d | Zeny: %d %s", - pl_sd->status.attrs[ATTR::STR], - pl_sd->status.attrs[ATTR::AGI], - pl_sd->status.attrs[ATTR::VIT], - pl_sd->status.attrs[ATTR::INT], - pl_sd->status.attrs[ATTR::DEX], - pl_sd->status.attrs[ATTR::LUK], - pl_sd->status.zeny, - gmlevel); + output = STRPRINTF("STR: %d | AGI: %d | VIT: %d | INT: %d | DEX: %d | LUK: %d | Zeny: %d %s"_fmt, + pl_sd->status.attrs[ATTR::STR], + pl_sd->status.attrs[ATTR::AGI], + pl_sd->status.attrs[ATTR::VIT], + pl_sd->status.attrs[ATTR::INT], + pl_sd->status.attrs[ATTR::DEX], + pl_sd->status.attrs[ATTR::LUK], + pl_sd->status.zeny, + gmlevel); clif_displaymessage(s, output); - clif_displaymessage(s, "--------"); + clif_displaymessage(s, "--------"_s); count++; } } if (count == 0) - clif_displaymessage(s, "No player found."); + clif_displaymessage(s, "No player found."_s); else if (count == 1) - clif_displaymessage(s, "1 player found."); + clif_displaymessage(s, "1 player found."_s); else { - AString output = STRPRINTF("%d players found.", count); + AString output = STRPRINTF("%d players found."_fmt, count); clif_displaymessage(s, output); } @@ -2252,9 +2261,9 @@ ATCE atcommand_character_option(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can change option only to lower or same level pl_sd->opt1 = opt1; @@ -2263,17 +2272,17 @@ ATCE atcommand_character_option(Session *s, dumb_ptr<map_session_data> sd, clif_changeoption(pl_sd); pc_calcstatus(pl_sd, 0); - clif_displaymessage(s, "Character's options changed."); + clif_displaymessage(s, "Character's options changed."_s); } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -2292,7 +2301,7 @@ ATCE atcommand_char_change_sex(Session *s, dumb_ptr<map_session_data> sd, { chrif_char_ask_name(sd->status_key.account_id, character, 5, HumanTimeDiff()); // type: 5 - changesex - clif_displaymessage(s, "Character name sends to char-server to ask it."); + clif_displaymessage(s, "Character name sends to char-server to ask it."_s); } return ATCE::OKAY; @@ -2310,7 +2319,7 @@ ATCE atcommand_char_block(Session *s, dumb_ptr<map_session_data> sd, { chrif_char_ask_name(sd->status_key.account_id, character, 1, HumanTimeDiff()); // type: 1 - block - clif_displaymessage(s, "Character name sends to char-server to ask it."); + clif_displaymessage(s, "Character name sends to char-server to ask it."_s); } return ATCE::OKAY; @@ -2330,7 +2339,7 @@ ATCE atcommand_char_ban(Session *s, dumb_ptr<map_session_data> sd, { chrif_char_ask_name(sd->status_key.account_id, character, 2, modif); // type: 2 - ban - clif_displaymessage(s, "Character name sends to char-server to ask it."); + clif_displaymessage(s, "Character name sends to char-server to ask it."_s); } return ATCE::OKAY; @@ -2349,7 +2358,7 @@ ATCE atcommand_char_unblock(Session *s, dumb_ptr<map_session_data> sd, // send answer to login server via char-server chrif_char_ask_name(sd->status_key.account_id, character, 3, HumanTimeDiff()); // type: 3 - unblock - clif_displaymessage(s, "Character name sends to char-server to ask it."); + clif_displaymessage(s, "Character name sends to char-server to ask it."_s); } return ATCE::OKAY; @@ -2368,7 +2377,7 @@ ATCE atcommand_char_unban(Session *s, dumb_ptr<map_session_data> sd, // send answer to login server via char-server chrif_char_ask_name(sd->status_key.account_id, character, 4, HumanTimeDiff()); // type: 4 - unban - clif_displaymessage(s, "Character name sends to char-server to ask it."); + clif_displaymessage(s, "Character name sends to char-server to ask it."_s); } return ATCE::OKAY; @@ -2387,39 +2396,39 @@ ATCE atcommand_character_save(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can change save point only to lower or same gm level map_local *m = map_mapname2mapid(map_name); if (m == nullptr) { - clif_displaymessage(s, "Map not found."); + clif_displaymessage(s, "Map not found."_s); return ATCE::EXIST; } else { if (m != nullptr && m->flag.get(MapFlag::NOWARPTO) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to set this map as a save map."); + "You are not authorised to set this map as a save map."_s); return ATCE::PERM; } pc_setsavepoint(pl_sd, map_name, x, y); - clif_displaymessage(s, "Character's respawn point changed."); + clif_displaymessage(s, "Character's respawn point changed."_s); } } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -2438,14 +2447,14 @@ ATCE atcommand_doom(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); if (pl_sd && pl_sd->state.auth && s2 != s - && pc_isGM(sd) >= pc_isGM(pl_sd)) + && pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can doom only lower or same gm level - pc_damage(NULL, pl_sd, pl_sd->status.hp + 1); - clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement."); + pc_damage(nullptr, pl_sd, pl_sd->status.hp + 1); + clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement."_s); } } - clif_displaymessage(s, "Judgement was made."); + clif_displaymessage(s, "Judgement was made."_s); return ATCE::OKAY; } @@ -2462,14 +2471,14 @@ ATCE atcommand_doommap(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); if (pl_sd && pl_sd->state.auth && s2 != s && sd->bl_m == pl_sd->bl_m - && pc_isGM(sd) >= pc_isGM(pl_sd)) + && pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can doom only lower or same gm level - pc_damage(NULL, pl_sd, pl_sd->status.hp + 1); - clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement."); + pc_damage(nullptr, pl_sd, pl_sd->status.hp + 1); + clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement."_s); } } - clif_displaymessage(s, "Judgement was made."); + clif_displaymessage(s, "Judgement was made."_s); return ATCE::OKAY; } @@ -2485,7 +2494,7 @@ void atcommand_raise_sub(dumb_ptr<map_session_data> sd) clif_updatestatus(sd, SP::HP); clif_updatestatus(sd, SP::SP); clif_resurrection(sd, 1); - clif_displaymessage(sd->sess, "Mercy has been shown."); + clif_displaymessage(sd->sess, "Mercy has been shown."_s); } } @@ -2501,7 +2510,7 @@ ATCE atcommand_raise(Session *s, dumb_ptr<map_session_data>, dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); atcommand_raise_sub(pl_sd); } - clif_displaymessage(s, "Mercy has been granted."); + clif_displaymessage(s, "Mercy has been granted."_s); return ATCE::OKAY; } @@ -2520,7 +2529,7 @@ ATCE atcommand_raisemap(Session *s, dumb_ptr<map_session_data> sd, && pl_sd->state.auth && sd->bl_m == pl_sd->bl_m) atcommand_raise_sub(pl_sd); } - clif_displaymessage(s, "Mercy has been granted."); + clif_displaymessage(s, "Mercy has been granted."_s); return ATCE::OKAY; } @@ -2537,16 +2546,16 @@ ATCE atcommand_character_baselevel(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can change base level only lower or same gm level if (level > 0) { if (pl_sd->status.base_level == battle_config.maximum_level) { - clif_displaymessage(s, "Character's base level can't go any higher."); + clif_displaymessage(s, "Character's base level can't go any higher."_s); return ATCE::RANGE; } if (level > battle_config.maximum_level || level > (battle_config.maximum_level - pl_sd->status.base_level)) @@ -2564,13 +2573,13 @@ ATCE atcommand_character_baselevel(Session *s, dumb_ptr<map_session_data> sd, pc_calcstatus(pl_sd, 0); pc_heal(pl_sd, pl_sd->status.max_hp, pl_sd->status.max_sp); clif_misceffect(pl_sd, 0); - clif_displaymessage(s, "Character's base level raised."); + clif_displaymessage(s, "Character's base level raised."_s); } else { if (pl_sd->status.base_level == 1) { - clif_displaymessage(s, "Character's base level can't go any lower."); + clif_displaymessage(s, "Character's base level can't go any lower."_s); return ATCE::RANGE; } if (level < -battle_config.maximum_level || level < (1 - pl_sd->status.base_level)) @@ -2592,20 +2601,20 @@ ATCE atcommand_character_baselevel(Session *s, dumb_ptr<map_session_data> sd, clif_updatestatus(pl_sd, SP::NEXTBASEEXP); clif_updatestatus(pl_sd, SP::BASEEXP); pc_calcstatus(pl_sd, 0); - clif_displaymessage(s, "Character's base level lowered."); + clif_displaymessage(s, "Character's base level lowered."_s); } // Reset their stat points to prevent extra points from stacking atcommand_charstreset(s, sd, character.to__actual()); } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -2624,9 +2633,9 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can change job level only lower or same gm level max_level -= 40; @@ -2635,7 +2644,7 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd, { if (pl_sd->status.job_level == max_level) { - clif_displaymessage(s, "Character's job level can't go any higher."); + clif_displaymessage(s, "Character's job level can't go any higher."_s); return ATCE::RANGE; } if (pl_sd->status.job_level + level > max_level) @@ -2647,13 +2656,13 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd, clif_updatestatus(pl_sd, SP::SKILLPOINT); pc_calcstatus(pl_sd, 0); clif_misceffect(pl_sd, 1); - clif_displaymessage(s, "character's job level raised."); + clif_displaymessage(s, "character's job level raised."_s); } else { if (pl_sd->status.job_level == 1) { - clif_displaymessage(s, "Character's job level can't go any lower."); + clif_displaymessage(s, "Character's job level can't go any lower."_s); return ATCE::RANGE; } if (pl_sd->status.job_level + level < 1) @@ -2670,18 +2679,18 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd, } // to add: remove status points from skills pc_calcstatus(pl_sd, 0); - clif_displaymessage(s, "Character's job level lowered."); + clif_displaymessage(s, "Character's job level lowered."_s); } } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -2698,20 +2707,20 @@ ATCE atcommand_kick(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) // you can kick only lower or same gm level clif_GM_kick(sd, pl_sd, 1); else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -2729,7 +2738,7 @@ ATCE atcommand_kickall(Session *s, dumb_ptr<map_session_data> sd, continue; dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); if (pl_sd - && pl_sd->state.auth && pc_isGM(sd) >= pc_isGM(pl_sd)) + && pl_sd->state.auth && pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can kick only lower or same gm level if (sd->status_key.account_id != pl_sd->status_key.account_id) @@ -2737,7 +2746,7 @@ ATCE atcommand_kickall(Session *s, dumb_ptr<map_session_data> sd, } } - clif_displaymessage(s, "All players have been kicked!"); + clif_displaymessage(s, "All players have been kicked!"_s); return ATCE::OKAY; } @@ -2758,23 +2767,23 @@ ATCE atcommand_questskill(Session *s, dumb_ptr<map_session_data> sd, if (pc_checkskill(sd, skill_id) == 0) { pc_skill(sd, skill_id, 1, 0); - clif_displaymessage(s, "You have learned the skill."); + clif_displaymessage(s, "You have learned the skill."_s); } else { - clif_displaymessage(s, "You already have this quest skill."); + clif_displaymessage(s, "You already have this quest skill."_s); return ATCE::EXIST; } } else { - clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."); + clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."_s); return ATCE::RANGE; } } else { - clif_displaymessage(s, "This skill number doesn't exist."); + clif_displaymessage(s, "This skill number doesn't exist."_s); return ATCE::RANGE; } @@ -2796,34 +2805,34 @@ ATCE atcommand_charquestskill(Session *s, dumb_ptr<map_session_data>, if (skill_get_inf2(skill_id) & 0x01) { dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { if (pc_checkskill(pl_sd, skill_id) == 0) { pc_skill(pl_sd, skill_id, 1, 0); - clif_displaymessage(s, "This player has learned the skill."); + clif_displaymessage(s, "This player has learned the skill."_s); } else { - clif_displaymessage(s, "This player already has this quest skill."); + clif_displaymessage(s, "This player already has this quest skill."_s); return ATCE::EXIST; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } } else { - clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."); + clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."_s); return ATCE::RANGE; } } else { - clif_displaymessage(s, "This skill number doesn't exist."); + clif_displaymessage(s, "This skill number doesn't exist."_s); return ATCE::RANGE; } @@ -2848,23 +2857,23 @@ ATCE atcommand_lostskill(Session *s, dumb_ptr<map_session_data> sd, sd->status.skill[skill_id].lv = 0; sd->status.skill[skill_id].flags = SkillFlags::ZERO; clif_skillinfoblock(sd); - clif_displaymessage(s, "You have forgotten the skill."); + clif_displaymessage(s, "You have forgotten the skill."_s); } else { - clif_displaymessage(s, "You don't have this quest skill."); + clif_displaymessage(s, "You don't have this quest skill."_s); return ATCE::EXIST; } } else { - clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."); + clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."_s); return ATCE::RANGE; } } else { - clif_displaymessage(s, "This skill number doesn't exist."); + clif_displaymessage(s, "This skill number doesn't exist."_s); return ATCE::RANGE; } @@ -2886,36 +2895,36 @@ ATCE atcommand_charlostskill(Session *s, dumb_ptr<map_session_data>, if (skill_get_inf2(skill_id) & 0x01) { dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { if (pc_checkskill(pl_sd, skill_id) > 0) { pl_sd->status.skill[skill_id].lv = 0; pl_sd->status.skill[skill_id].flags = SkillFlags::ZERO; clif_skillinfoblock(pl_sd); - clif_displaymessage(s, "This player has forgotten the skill."); + clif_displaymessage(s, "This player has forgotten the skill."_s); } else { - clif_displaymessage(s, "This player doesn't have this quest skill."); + clif_displaymessage(s, "This player doesn't have this quest skill."_s); return ATCE::EXIST; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } } else { - clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."); + clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."_s); return ATCE::RANGE; } } else { - clif_displaymessage(s, "This skill number doesn't exist."); + clif_displaymessage(s, "This skill number doesn't exist."_s); return ATCE::RANGE; } @@ -2964,26 +2973,26 @@ ATCE atcommand_idsearch(Session *s, dumb_ptr<map_session_data>, ZString message) { ItemName item_name; - int i, match; + int match; struct item_data *item; if (!extract(message, &item_name) || !item_name) return ATCE::USAGE; - AString output = STRPRINTF("The reference result of '%s' (name: id):", item_name); + AString output = STRPRINTF("The reference result of '%s' (name: id):"_fmt, item_name); clif_displaymessage(s, output); match = 0; - for (i = 0; i < 20000; i++) + for (ItemNameId i = wrap<ItemNameId>(0); i < wrap<ItemNameId>(-1); i = next(i)) { - if ((item = itemdb_exists(i)) != NULL + if ((item = itemdb_exists(i)) != nullptr && item->jname.contains_seq(item_name)) { match++; - output = STRPRINTF("%s: %d", item->jname, item->nameid); + output = STRPRINTF("%s: %d"_fmt, item->jname, item->nameid); clif_displaymessage(s, output); } } - output = STRPRINTF("It is %d affair above.", match); + output = STRPRINTF("It is %d affair above."_fmt, match); clif_displaymessage(s, output); return ATCE::OKAY; @@ -2999,25 +3008,25 @@ ATCE atcommand_charskreset(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can reset skill points only lower or same gm level pc_resetskill(pl_sd); AString output = STRPRINTF( - "'%s' skill points reseted!", character); + "'%s' skill points reseted!"_fmt, character); clif_displaymessage(s, output); } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -3034,26 +3043,26 @@ ATCE atcommand_charstreset(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can reset stats points only lower or same gm level pc_resetstate(pl_sd); AString output = STRPRINTF( - "'%s' stats points reseted!", + "'%s' stats points reseted!"_fmt, character); clif_displaymessage(s, output); } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -3070,30 +3079,30 @@ ATCE atcommand_charreset(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can reset a character only for lower or same GM level pc_resetstate(pl_sd); pc_resetskill(pl_sd); - pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_FLAGS"), 0); + pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_FLAGS"_s), 0); // [Fate] Reset magic quest variables - pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_EXP"), 0); + pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_EXP"_s), 0); // [Fate] Reset magic experience AString output = STRPRINTF( - "'%s' skill and stats points reseted!", character); + "'%s' skill and stats points reseted!"_fmt, character); clif_displaymessage(s, output); } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -3110,12 +3119,11 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can reset a character only for lower or same GM level - int i; // Reset base level pl_sd->status.base_level = 1; @@ -3136,7 +3144,7 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd, clif_updatestatus(pl_sd, SP::ZENY); // Clear inventory - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (sd->status.inventory[i].amount) { @@ -3147,33 +3155,33 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd, } // Give knife and shirt - struct item item; - item.nameid = 1201; + Item item; + item.nameid = wrap<ItemNameId>(1201); pc_additem(pl_sd, &item, 1); - item.nameid = 1202; + item.nameid = wrap<ItemNameId>(1202); pc_additem(pl_sd, &item, 1); // Reset stats and skills pc_calcstatus(pl_sd, 0); pc_resetstate(pl_sd); pc_resetskill(pl_sd); - pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_FLAGS"), 0); + pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_FLAGS"_s), 0); // [Fate] Reset magic quest variables - pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_EXP"), 0); + pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_EXP"_s), 0); // [Fate] Reset magic experience - AString output = STRPRINTF("%s: wiped.", character); + AString output = STRPRINTF("%s: wiped."_fmt, character); clif_displaymessage(s, output); } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -3191,7 +3199,7 @@ ATCE atcommand_charmodel(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE && hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR && @@ -3201,7 +3209,7 @@ ATCE atcommand_charmodel(Session *s, dumb_ptr<map_session_data>, pc_changelook(pl_sd, LOOK::HAIR, hair_style); pc_changelook(pl_sd, LOOK::HAIR_COLOR, hair_color); pc_changelook(pl_sd, LOOK::CLOTHES_COLOR, cloth_color); - clif_displaymessage(s, "Appearence changed."); + clif_displaymessage(s, "Appearence changed."_s); } } else @@ -3209,7 +3217,7 @@ ATCE atcommand_charmodel(Session *s, dumb_ptr<map_session_data>, } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -3229,7 +3237,7 @@ ATCE atcommand_charskpoint(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { new_skill_point = pl_sd->status.skill_point + point; if (point > 0 && (point > 0x7FFF || new_skill_point > 0x7FFF)) @@ -3242,14 +3250,14 @@ ATCE atcommand_charskpoint(Session *s, dumb_ptr<map_session_data>, { pl_sd->status.skill_point = new_skill_point; clif_updatestatus(pl_sd, SP::SKILLPOINT); - clif_displaymessage(s, "Character's number of skill points changed!"); + clif_displaymessage(s, "Character's number of skill points changed!"_s); } else return ATCE::RANGE; } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -3269,7 +3277,7 @@ ATCE atcommand_charstpoint(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { new_status_point = pl_sd->status.status_point + point; if (point > 0 && (point > 0x7FFF || new_status_point > 0x7FFF)) @@ -3282,14 +3290,14 @@ ATCE atcommand_charstpoint(Session *s, dumb_ptr<map_session_data>, { pl_sd->status.status_point = new_status_point; clif_updatestatus(pl_sd, SP::STATUSPOINT); - clif_displaymessage(s, "Character's number of status points changed!"); + clif_displaymessage(s, "Character's number of status points changed!"_s); } else return ATCE::RANGE; } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -3307,7 +3315,7 @@ ATCE atcommand_charzeny(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { new_zeny = pl_sd->status.zeny + zeny; if (zeny > 0 && (zeny > MAX_ZENY || new_zeny > MAX_ZENY)) @@ -3320,14 +3328,14 @@ ATCE atcommand_charzeny(Session *s, dumb_ptr<map_session_data>, { pl_sd->status.zeny = new_zeny; clif_updatestatus(pl_sd, SP::ZENY); - clif_displaymessage(s, "Character's number of zenys changed!"); + clif_displaymessage(s, "Character's number of zenys changed!"_s); } else return ATCE::RANGE; } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -3341,10 +3349,10 @@ ATCE atcommand_recallall(Session *s, dumb_ptr<map_session_data> sd, int count; if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARPTO) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp somenone to your actual map."); + "You are not authorised to warp somenone to your actual map."_s); return ATCE::PERM; } @@ -3358,22 +3366,22 @@ ATCE atcommand_recallall(Session *s, dumb_ptr<map_session_data> sd, if (pl_sd && pl_sd->state.auth && sd->status_key.account_id != pl_sd->status_key.account_id - && pc_isGM(sd) >= pc_isGM(pl_sd)) + && pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can recall only lower or same level if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARP) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) count++; else pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); } } - clif_displaymessage(s, "All characters recalled!"); + clif_displaymessage(s, "All characters recalled!"_s); if (count) { AString output = STRPRINTF( - "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", + "Because you are not authorised to warp from some maps, %d player(s) have not been recalled."_fmt, count); clif_displaymessage(s, output); } @@ -3386,23 +3394,23 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr<map_session_data> sd, ZString message) { PartyName party_name; - struct party *p; + PartyPair p; int count; if (!extract(message, &party_name) || !party_name) return ATCE::USAGE; if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARPTO) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp somenone to your actual map."); + "You are not authorised to warp somenone to your actual map."_s); return ATCE::PERM; } - if ((p = party_searchname(party_name)) != NULL || + if ((p = party_searchname(party_name)) || // name first to avoid error when name begin with a number - (p = party_search(atoi(message.c_str()))) != NULL) + (p = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str())))))) { count = 0; for (io::FD i : iter_fds()) @@ -3413,28 +3421,28 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); if (pl_sd && pl_sd->state.auth && sd->status_key.account_id != pl_sd->status_key.account_id - && pl_sd->status.party_id == p->party_id) + && pl_sd->status.party_id == p.party_id) { if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARP) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) count++; else pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); } } - AString output = STRPRINTF("All online characters of the %s party are near you.", p->name); + AString output = STRPRINTF("All online characters of the %s party are near you."_fmt, p->name); clif_displaymessage(s, output); if (count) { output = STRPRINTF( - "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.", + "Because you are not authorised to warp from some maps, %d player(s) have not been recalled."_fmt, count); clif_displaymessage(s, output); } } else { - clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."); + clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); return ATCE::EXIST; } @@ -3445,9 +3453,9 @@ static ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd, ZString message) { - dumb_ptr<npc_data> nd = NULL; + dumb_ptr<npc_data> nd = nullptr; MapName map_name; - const char *direction = NULL; + LString direction = ""_s; int list = 0; extract(message, record<' '>(&list, &map_name)); @@ -3462,35 +3470,35 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd, if (m_id != nullptr) return ATCE::EXIST; - clif_displaymessage(s, "------ Map Info ------"); - AString output = STRPRINTF("Map Name: %s", map_name); + clif_displaymessage(s, "------ Map Info ------"_s); + AString output = STRPRINTF("Map Name: %s"_fmt, map_name); clif_displaymessage(s, output); - output = STRPRINTF("Players In Map: %d", m_id->users); + output = STRPRINTF("Players In Map: %d"_fmt, m_id->users); clif_displaymessage(s, output); - output = STRPRINTF("NPCs In Map: %d", m_id->npc_num); + output = STRPRINTF("NPCs In Map: %d"_fmt, m_id->npc_num); clif_displaymessage(s, output); - clif_displaymessage(s, "------ Map Flags ------"); - output = STRPRINTF("Player vs Player: %s | No Party: %s", - (m_id->flag.get(MapFlag::PVP)) ? "True" : "False", - (m_id->flag.get(MapFlag::PVP_NOPARTY)) ? "True" : "False"); + clif_displaymessage(s, "------ Map Flags ------"_s); + output = STRPRINTF("Player vs Player: %s | No Party: %s"_fmt, + (m_id->flag.get(MapFlag::PVP)) ? "True"_s : "False"_s, + (m_id->flag.get(MapFlag::PVP_NOPARTY)) ? "True"_s : "False"_s); clif_displaymessage(s, output); - output = STRPRINTF("No Penalty: %s", - (m_id->flag.get(MapFlag::NOPENALTY)) ? "True" : "False"); + output = STRPRINTF("No Penalty: %s"_fmt, + (m_id->flag.get(MapFlag::NOPENALTY)) ? "True"_s : "False"_s); clif_displaymessage(s, output); - output = STRPRINTF("No Return: %s", - (m_id->flag.get(MapFlag::NORETURN)) ? "True" : "False"); + output = STRPRINTF("No Return: %s"_fmt, + (m_id->flag.get(MapFlag::NORETURN)) ? "True"_s : "False"_s); clif_displaymessage(s, output); - output = STRPRINTF("No Save: %s", - (m_id->flag.get(MapFlag::NOSAVE)) ? "True" : "False"); + output = STRPRINTF("No Save: %s"_fmt, + (m_id->flag.get(MapFlag::NOSAVE)) ? "True"_s : "False"_s); clif_displaymessage(s, output); - output = STRPRINTF("Re Save: %s", - (m_id->flag.get(MapFlag::RESAVE)) ? "True" : "False"); + output = STRPRINTF("Re Save: %s"_fmt, + (m_id->flag.get(MapFlag::RESAVE)) ? "True"_s : "False"_s); clif_displaymessage(s, output); - output = STRPRINTF("No Teleport: %s", - (m_id->flag.get(MapFlag::NOTELEPORT)) ? "True" : "False"); + output = STRPRINTF("No Teleport: %s"_fmt, + (m_id->flag.get(MapFlag::NOTELEPORT)) ? "True"_s : "False"_s); clif_displaymessage(s, output); - output = STRPRINTF("No Monster Teleport: %s", - (m_id->flag.get(MapFlag::MONSTER_NOTELEPORT)) ? "True" : "False"); + output = STRPRINTF("No Monster Teleport: %s"_fmt, + (m_id->flag.get(MapFlag::MONSTER_NOTELEPORT)) ? "True"_s : "False"_s); clif_displaymessage(s, output); switch (list) @@ -3499,7 +3507,7 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd, // Do nothing. It's list 0, no additional display. break; case 1: - clif_displaymessage(s, "----- Players in Map -----"); + clif_displaymessage(s, "----- Players in Map -----"_s); for (io::FD i : iter_fds()) { Session *s2 = get_session(i); @@ -3510,54 +3518,54 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd, && pl_sd->mapname_ == map_name) { output = STRPRINTF( - "Player '%s' (session #%d) | Location: %d,%d", + "Player '%s' (session #%d) | Location: %d,%d"_fmt, pl_sd->status_key.name, s2, pl_sd->bl_x, pl_sd->bl_y); clif_displaymessage(s, output); } } break; case 2: - clif_displaymessage(s, "----- NPCs in Map -----"); + clif_displaymessage(s, "----- NPCs in Map -----"_s); for (int i = 0; i < m_id->npc_num;) { nd = m_id->npc[i]; switch (nd->dir) { case DIR::S: - direction = "North"; + direction = "North"_s; break; case DIR::SW: - direction = "North West"; + direction = "North West"_s; break; case DIR::W: - direction = "West"; + direction = "West"_s; break; case DIR::NW: - direction = "South West"; + direction = "South West"_s; break; case DIR::N: - direction = "South"; + direction = "South"_s; break; case DIR::NE: - direction = "South East"; + direction = "South East"_s; break; case DIR::E: - direction = "East"; + direction = "East"_s; break; case DIR::SE: - direction = "North East"; + direction = "North East"_s; break; #if 0 case 9: - direction = "North"; + direction = "North"_s; break; #endif default: - direction = "Unknown"; + direction = "Unknown"_s; break; } output = STRPRINTF( - "NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d", + "NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d"_fmt, ++i, nd->name, direction, nd->npc_class, nd->bl_x, nd->bl_y); clif_displaymessage(s, output); @@ -3566,7 +3574,7 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd, default: // normally impossible to arrive here clif_displaymessage(s, - "Please, enter at least a valid list number (usage: @mapinfo <0-2> [map])."); + "Please, enter at least a valid list number (usage: @mapinfo <0-2> [map])."_s); return ATCE::USAGE; } @@ -3582,27 +3590,27 @@ ATCE atcommand_partyspy(Session *s, dumb_ptr<map_session_data> sd, if (!extract(message, &party_name)) return ATCE::USAGE; - struct party *p; - if ((p = party_searchname(party_name)) != NULL || + PartyPair p; + if ((p = party_searchname(party_name)) || // name first to avoid error when name begin with a number - (p = party_search(atoi(message.c_str()))) != NULL) + (p = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str())))))) { - if (sd->partyspy == p->party_id) + if (sd->partyspy == p.party_id) { - sd->partyspy = 0; - AString output = STRPRINTF("No longer spying on the %s party.", p->name); + sd->partyspy = PartyId(); + AString output = STRPRINTF("No longer spying on the %s party."_fmt, p->name); clif_displaymessage(s, output); } else { - sd->partyspy = p->party_id; - AString output = STRPRINTF("Spying on the %s party.", p->name); + sd->partyspy = p.party_id; + AString output = STRPRINTF("Spying on the %s party."_fmt, p->name); clif_displaymessage(s, output); } } else { - clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."); + clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); return ATCE::EXIST; } @@ -3618,14 +3626,14 @@ ATCE atcommand_enablenpc(Session *s, dumb_ptr<map_session_data>, if (!extract(message, &NPCname) || !NPCname) return ATCE::USAGE; - if (npc_name2id(NPCname) != NULL) + if (npc_name2id(NPCname) != nullptr) { npc_enable(NPCname, 1); - clif_displaymessage(s, "Npc Enabled."); + clif_displaymessage(s, "Npc Enabled."_s); } else { - clif_displaymessage(s, "This NPC doesn't exist."); + clif_displaymessage(s, "This NPC doesn't exist."_s); return ATCE::EXIST; } @@ -3641,14 +3649,14 @@ ATCE atcommand_disablenpc(Session *s, dumb_ptr<map_session_data>, if (!extract(message, &NPCname) || !NPCname) return ATCE::USAGE; - if (npc_name2id(NPCname) != NULL) + if (npc_name2id(NPCname) != nullptr) { npc_enable(NPCname, 0); - clif_displaymessage(s, "Npc Disabled."); + clif_displaymessage(s, "Npc Disabled."_s); } else { - clif_displaymessage(s, "This NPC doesn't exist."); + clif_displaymessage(s, "This NPC doesn't exist."_s); return ATCE::EXIST; } @@ -3661,7 +3669,7 @@ ATCE atcommand_servertime(Session *s, dumb_ptr<map_session_data>, { timestamp_seconds_buffer tsbuf; stamp_time(tsbuf); - AString temp = STRPRINTF("Server time: %s", tsbuf); + AString temp = STRPRINTF("Server time: %s"_fmt, tsbuf); clif_displaymessage(s, temp); return ATCE::OKAY; @@ -3673,33 +3681,32 @@ ATCE atcommand_chardelitem(Session *s, dumb_ptr<map_session_data> sd, { CharName character; XString item_name; - int i, number = 0, item_id, item_position, count; + int i, number = 0; + ItemNameId item_id; + int count; struct item_data *item_data; if (!asplit(message, &item_name, &number, &character) || number < 1) return ATCE::USAGE; - item_id = 0; - if ((item_data = itemdb_searchname(item_name)) != NULL) + if ((item_data = itemdb_searchname(item_name)) != nullptr) item_id = item_data->nameid; - else if (extract(item_name, &item_id) && (item_data = itemdb_exists(item_id)) != NULL) + else if (extract(item_name, &item_id) && (item_data = itemdb_exists(item_id)) != nullptr) item_id = item_data->nameid; - else - item_id = 0; - if (item_id > 500) + if (item_id) { dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can kill only lower or same level - item_position = pc_search_inventory(pl_sd, item_id); - if (item_position >= 0) + IOff0 item_position = pc_search_inventory(pl_sd, item_id); + if (item_position.ok()) { count = 0; - for (i = 0; i < number && item_position >= 0; i++) + for (i = 0; i < number && item_position.ok(); i++) { pc_delitem(pl_sd, item_position, 1, 0); count++; @@ -3707,37 +3714,37 @@ ATCE atcommand_chardelitem(Session *s, dumb_ptr<map_session_data> sd, // for next loop } AString output = STRPRINTF( - "%d item(s) removed by a GM.", + "%d item(s) removed by a GM."_fmt, count); clif_displaymessage(pl_sd->sess, output); if (number == count) - output = STRPRINTF("%d item(s) removed from the player.", count); + output = STRPRINTF("%d item(s) removed from the player."_fmt, count); else - output = STRPRINTF("%d item(s) removed. Player had only %d on %d items.", count, count, number); + output = STRPRINTF("%d item(s) removed. Player had only %d on %d items."_fmt, count, count, number); clif_displaymessage(s, output); } else { - clif_displaymessage(s, "Character does not have the item."); + clif_displaymessage(s, "Character does not have the item."_s); return ATCE::EXIST; } } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } } else { - clif_displaymessage(s, "Invalid item ID or name."); + clif_displaymessage(s, "Invalid item ID or name."_s); return ATCE::RANGE; } @@ -3751,7 +3758,7 @@ ATCE atcommand_broadcast(Session *, dumb_ptr<map_session_data> sd, if (!message) return ATCE::USAGE; - AString output = STRPRINTF("%s : %s", sd->status_key.name, message); + AString output = STRPRINTF("%s : %s"_fmt, sd->status_key.name, message); intif_GMmessage(output); return ATCE::OKAY; @@ -3764,7 +3771,7 @@ ATCE atcommand_localbroadcast(Session *, dumb_ptr<map_session_data> sd, if (!message) return ATCE::USAGE; - AString output = STRPRINTF("%s : %s", sd->status_key.name, message); + AString output = STRPRINTF("%s : %s"_fmt, sd->status_key.name, message); clif_GMmessage(sd, output, 1); @@ -3783,28 +3790,28 @@ ATCE atcommand_email(Session *s, dumb_ptr<map_session_data> sd, if (!e_mail_check(actual_email)) { - clif_displaymessage(s, "Invalid actual email. If you have default e-mail, type a@a.com."); + clif_displaymessage(s, "Invalid actual email. If you have default e-mail, type a@a.com."_s); return ATCE::RANGE; } else if (!e_mail_check(new_email)) { - clif_displaymessage(s, "Invalid new email. Please enter a real e-mail."); + clif_displaymessage(s, "Invalid new email. Please enter a real e-mail."_s); return ATCE::RANGE; } else if (new_email == DEFAULT_EMAIL) { - clif_displaymessage(s, "New email must be a real e-mail."); + clif_displaymessage(s, "New email must be a real e-mail."_s); return ATCE::RANGE; } else if (actual_email == new_email) { - clif_displaymessage(s, "New email must be different of the actual e-mail."); + clif_displaymessage(s, "New email must be different of the actual e-mail."_s); return ATCE::RANGE; } else { chrif_changeemail(sd->status_key.account_id, actual_email, new_email); - clif_displaymessage(s, "Information sended to login-server via char-server."); + clif_displaymessage(s, "Information sended to login-server via char-server."_s); } return ATCE::OKAY; @@ -3821,7 +3828,7 @@ ATCE atcommand_effect(Session *s, dumb_ptr<map_session_data> sd, if (flag <= 0) { clif_specialeffect(sd, type, flag); - clif_displaymessage(s, "Your Effect Has Changed."); + clif_displaymessage(s, "Your Effect Has Changed."_s); } else { @@ -3834,7 +3841,7 @@ ATCE atcommand_effect(Session *s, dumb_ptr<map_session_data> sd, if (pl_sd && pl_sd->state.auth) { clif_specialeffect(pl_sd, type, flag); - clif_displaymessage(pl_sd->sess, "Your Effect Has Changed."); + clif_displaymessage(pl_sd->sess, "Your Effect Has Changed."_s); } } } @@ -3846,34 +3853,34 @@ static ATCE atcommand_character_item_list(Session *s, dumb_ptr<map_session_data> sd, ZString message) { - struct item_data *item_data = NULL; - int i, count, counter; + struct item_data *item_data = nullptr; + int count, counter; CharName character; if (!asplit(message, &character)) return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can look items only lower or same level counter = 0; count = 0; - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { - if (pl_sd->status.inventory[i].nameid > 0 + if (pl_sd->status.inventory[i].nameid && (item_data = itemdb_search(pl_sd->status.inventory[i].nameid)) != - NULL) + nullptr) { counter = counter + pl_sd->status.inventory[i].amount; count++; if (count == 1) { AString output = STRPRINTF( - "------ Items list of '%s' ------", + "------ Items list of '%s' ------"_fmt, pl_sd->status_key.name); clif_displaymessage(s, output); } @@ -3881,35 +3888,35 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr<map_session_data> sd, MString equipstr; if (bool(equip)) { - equipstr += "| equiped: "; + equipstr += "| equiped: "_s; if (bool(equip & EPOS::GLOVES)) - equipstr += "robe/gargment, "; + equipstr += "robe/gargment, "_s; if (bool(equip & EPOS::CAPE)) - equipstr += "left accessory, "; + equipstr += "left accessory, "_s; if (bool(equip & EPOS::MISC1)) - equipstr += "body/armor, "; + equipstr += "body/armor, "_s; if ((equip & (EPOS::WEAPON | EPOS::SHIELD)) == EPOS::WEAPON) - equipstr += "right hand, "; + equipstr += "right hand, "_s; if ((equip & (EPOS::WEAPON | EPOS::SHIELD)) == EPOS::SHIELD) - equipstr += "left hand, "; + equipstr += "left hand, "_s; if ((equip & (EPOS::WEAPON | EPOS::SHIELD)) == (EPOS::WEAPON | EPOS::SHIELD)) - equipstr += "both hands, "; + equipstr += "both hands, "_s; if (bool(equip & EPOS::SHOES)) - equipstr += "feet, "; + equipstr += "feet, "_s; if (bool(equip & EPOS::MISC2)) - equipstr += "right accessory, "; + equipstr += "right accessory, "_s; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == EPOS::LEGS) - equipstr += "lower head, "; + equipstr += "lower head, "_s; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == EPOS::HAT) - equipstr += "top head, "; + equipstr += "top head, "_s; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == (EPOS::HAT | EPOS::LEGS)) - equipstr += "lower/top head, "; + equipstr += "lower/top head, "_s; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == EPOS::TORSO) - equipstr += "mid head, "; + equipstr += "mid head, "_s; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == (EPOS::TORSO | EPOS::LEGS)) - equipstr += "lower/mid head, "; + equipstr += "lower/mid head, "_s; if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) - equipstr += "lower/mid/top head, "; + equipstr += "lower/mid/top head, "_s; // remove final ', ' equipstr.pop_back(2); } @@ -3918,35 +3925,35 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr<map_session_data> sd, AString output; if (true) - output = STRPRINTF("%d %s (%s, id: %d) %s", - pl_sd->status.inventory[i].amount, - item_data->name, item_data->jname, - pl_sd->status.inventory[i].nameid, - AString(equipstr)); + output = STRPRINTF("%d %s (%s, id: %d) %s"_fmt, + pl_sd->status.inventory[i].amount, + item_data->name, item_data->jname, + pl_sd->status.inventory[i].nameid, + AString(equipstr)); clif_displaymessage(s, output); // snip cards } } if (count == 0) - clif_displaymessage(s, "No item found on this player."); + clif_displaymessage(s, "No item found on this player."_s); else { AString output = STRPRINTF( - "%d item(s) found in %d kind(s) of items.", + "%d item(s) found in %d kind(s) of items."_fmt, counter, count); clif_displaymessage(s, output); } } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -3957,74 +3964,74 @@ static ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> sd, ZString message) { - struct storage *stor; - struct item_data *item_data = NULL; - int i, count, counter; + Storage *stor; + struct item_data *item_data = nullptr; + int count, counter; CharName character; if (!asplit(message, &character)) return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { - if (pc_isGM(sd) >= pc_isGM(pl_sd)) + if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can look items only lower or same level - if ((stor = account2storage2(pl_sd->status_key.account_id)) != NULL) + if ((stor = account2storage2(pl_sd->status_key.account_id)) != nullptr) { counter = 0; count = 0; - for (i = 0; i < MAX_STORAGE; i++) + for (SOff0 i : SOff0::iter()) { - if (stor->storage_[i].nameid > 0 + if (stor->storage_[i].nameid && (item_data = - itemdb_search(stor->storage_[i].nameid)) != NULL) + itemdb_search(stor->storage_[i].nameid)) != nullptr) { counter = counter + stor->storage_[i].amount; count++; if (count == 1) { AString output = STRPRINTF( - "------ Storage items list of '%s' ------", + "------ Storage items list of '%s' ------"_fmt, pl_sd->status_key.name); clif_displaymessage(s, output); } AString output; if (true) - output = STRPRINTF("%d %s (%s, id: %d)", - stor->storage_[i].amount, - item_data->name, item_data->jname, - stor->storage_[i].nameid); + output = STRPRINTF("%d %s (%s, id: %d)"_fmt, + stor->storage_[i].amount, + item_data->name, item_data->jname, + stor->storage_[i].nameid); clif_displaymessage(s, output); } } if (count == 0) clif_displaymessage(s, - "No item found in the storage of this player."); + "No item found in the storage of this player."_s); else { AString output = STRPRINTF( - "%d item(s) found in %d kind(s) of items.", + "%d item(s) found in %d kind(s) of items."_fmt, counter, count); clif_displaymessage(s, output); } } else { - clif_displaymessage(s, "This player has no storage."); + clif_displaymessage(s, "This player has no storage."_s); return ATCE::OKAY; } } else { - clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."); + clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s); return ATCE::PERM; } } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -4038,9 +4045,9 @@ ATCE atcommand_killer(Session *s, dumb_ptr<map_session_data> sd, sd->special_state.killer = !sd->special_state.killer; if (sd->special_state.killer) - clif_displaymessage(s, "You be a killa..."); + clif_displaymessage(s, "You be a killa..."_s); else - clif_displaymessage(s, "You gonna be own3d..."); + clif_displaymessage(s, "You gonna be own3d..."_s); return ATCE::OKAY; } @@ -4055,20 +4062,20 @@ ATCE atcommand_charkiller(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd == NULL) + if (pl_sd == nullptr) return ATCE::EXIST; pl_sd->special_state.killer = !pl_sd->special_state.killer; if (pl_sd->special_state.killer) { - clif_displaymessage(s, "The player is now a killer"); - clif_displaymessage(pl_sd->sess, "You are now a killer"); + clif_displaymessage(s, "The player is now a killer"_s); + clif_displaymessage(pl_sd->sess, "You are now a killer"_s); } else { - clif_displaymessage(s, "The player is no longer a killer"); - clif_displaymessage(pl_sd->sess, "You are no longer a killer"); + clif_displaymessage(s, "The player is no longer a killer"_s); + clif_displaymessage(pl_sd->sess, "You are no longer a killer"_s); } return ATCE::OKAY; @@ -4081,9 +4088,9 @@ ATCE atcommand_killable(Session *s, dumb_ptr<map_session_data> sd, sd->special_state.killable = !sd->special_state.killable; if (sd->special_state.killable) - clif_displaymessage(s, "You gonna be own3d..."); + clif_displaymessage(s, "You gonna be own3d..."_s); else - clif_displaymessage(s, "You be a killa..."); + clif_displaymessage(s, "You be a killa..."_s); return ATCE::OKAY; } @@ -4098,15 +4105,15 @@ ATCE atcommand_charkillable(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd == NULL) + if (pl_sd == nullptr) return ATCE::EXIST; pl_sd->special_state.killable = !pl_sd->special_state.killable; if (pl_sd->special_state.killable) - clif_displaymessage(s, "The player is now killable"); + clif_displaymessage(s, "The player is now killable"_s); else - clif_displaymessage(s, "The player is no longer killable"); + clif_displaymessage(s, "The player is no longer killable"_s); return ATCE::OKAY; } @@ -4117,13 +4124,13 @@ ATCE atcommand_npcmove(Session *, dumb_ptr<map_session_data>, { NpcName character; int x = 0, y = 0; - dumb_ptr<npc_data> nd = 0; + dumb_ptr<npc_data> nd = nullptr; if (!asplit(message, &x, &y, &character)) return ATCE::USAGE; nd = npc_name2id(character); - if (nd == NULL) + if (nd == nullptr) return ATCE::EXIST; npc_enable(character, 0); @@ -4146,17 +4153,17 @@ ATCE atcommand_addwarp(Session *s, dumb_ptr<map_session_data> sd, if (!extract(message, record<' '>(&mapname, &x, &y))) return ATCE::USAGE; - AString w1 = STRPRINTF("%s,%d,%d", sd->mapname_, sd->bl_x, sd->bl_y); - AString w3 = STRPRINTF("%s%d%d%d%d", mapname, sd->bl_x, sd->bl_y, x, y); - AString w4 = STRPRINTF("1,1,%s.gat,%d,%d", mapname, x, y); + AString w1 = STRPRINTF("%s,%d,%d"_fmt, sd->mapname_, sd->bl_x, sd->bl_y); + AString w3 = STRPRINTF("%s%d%d%d%d"_fmt, mapname, sd->bl_x, sd->bl_y, x, y); + AString w4 = STRPRINTF("1,1,%s.gat,%d,%d"_fmt, mapname, x, y); NpcName w3name = stringish<NpcName>(w3); - int ret = npc_parse_warp(w1, ZString("warp"), w3name, w4); + int ret = npc_parse_warp(w1, "warp"_s, w3name, w4); if (ret) // warp failed return ATCE::RANGE; - AString output = STRPRINTF("New warp NPC => %s", w3); + AString output = STRPRINTF("New warp NPC => %s"_fmt, w3); clif_displaymessage(s, output); return ATCE::OKAY; @@ -4173,11 +4180,11 @@ ATCE atcommand_chareffect(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(target); - if (pl_sd == NULL) + if (pl_sd == nullptr) return ATCE::EXIST; clif_specialeffect(pl_sd, type, 0); - clif_displaymessage(s, "Your Effect Has Changed."); + clif_displaymessage(s, "Your Effect Has Changed."_s); return ATCE::OKAY; } @@ -4186,8 +4193,7 @@ static ATCE atcommand_dropall(Session *, dumb_ptr<map_session_data> sd, ZString) { - int i; - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (sd->status.inventory[i].amount) { @@ -4208,9 +4214,9 @@ ATCE atcommand_chardropall(Session *s, dumb_ptr<map_session_data>, if (!asplit(message, &character)) return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd == NULL) + if (pl_sd == nullptr) return ATCE::EXIST; - for (int i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (pl_sd->status.inventory[i].amount) { @@ -4220,9 +4226,8 @@ ATCE atcommand_chardropall(Session *s, dumb_ptr<map_session_data>, } } - clif_displaymessage(pl_sd->sess, "Ever play 52 card pickup?"); - clif_displaymessage(s, "It is done"); - //clif_displaymessage(s, "It is offical.. your a jerk"); + clif_displaymessage(pl_sd->sess, "Ever play 52 card pickup?"_s); + clif_displaymessage(s, "It is official.. you're a jerk."_s); return ATCE::OKAY; } @@ -4231,8 +4236,6 @@ static ATCE atcommand_storeall(Session *s, dumb_ptr<map_session_data> sd, ZString) { - int i; - if (!sd->state.storage_open) { //Open storage. @@ -4240,16 +4243,16 @@ ATCE atcommand_storeall(Session *s, dumb_ptr<map_session_data> sd, { case 2: //Try again - clif_displaymessage(s, "run this command again.."); + clif_displaymessage(s, "run this command again.."_s); return ATCE::OKAY; case 1: //Failure clif_displaymessage(s, - "You can't open the storage currently."); + "You can't open the storage currently."_s); return ATCE::EXIST; } } - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (sd->status.inventory[i].amount) { @@ -4260,7 +4263,7 @@ ATCE atcommand_storeall(Session *s, dumb_ptr<map_session_data> sd, } storage_storageclose(sd); - clif_displaymessage(s, "It is done"); + clif_displaymessage(s, "It is done"_s); return ATCE::OKAY; } @@ -4273,7 +4276,7 @@ ATCE atcommand_charstoreall(Session *s, dumb_ptr<map_session_data> sd, if (!asplit(message, &character)) return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd == NULL) + if (pl_sd == nullptr) return ATCE::EXIST; if (storage_storageopen(pl_sd) == 1) @@ -4281,11 +4284,11 @@ ATCE atcommand_charstoreall(Session *s, dumb_ptr<map_session_data> sd, // TODO figure out what the hell this is talking about, // and especially why it's different from the other one. clif_displaymessage(s, - "Had to open the characters storage window..."); - clif_displaymessage(s, "run this command again.."); + "Had to open the characters storage window..."_s); + clif_displaymessage(s, "run this command again.."_s); return ATCE::OKAY; } - for (int i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (pl_sd->status.inventory[i].amount) { @@ -4297,12 +4300,12 @@ ATCE atcommand_charstoreall(Session *s, dumb_ptr<map_session_data> sd, storage_storageclose(pl_sd); clif_displaymessage(pl_sd->sess, - "Everything you own has been put away for safe keeping."); + "Everything you own has been put away for safe keeping."_s); clif_displaymessage(pl_sd->sess, - "go to the nearest kafka to retrieve it.."); - clif_displaymessage(pl_sd->sess, " -- the management"); + "go to the nearest kafka to retrieve it.."_s); + clif_displaymessage(pl_sd->sess, " -- the management"_s); - clif_displaymessage(s, "It is done"); + clif_displaymessage(s, "It is done"_s); return ATCE::OKAY; } @@ -4383,31 +4386,30 @@ ATCE atcommand_summon(Session *, dumb_ptr<map_session_data> sd, ZString message) { MobName name; - int mob_id = 0; + Species mob_id; int x = 0; int y = 0; - int id = 0; tick_t tick = gettick(); if (!extract(message, &name) || !name) return ATCE::USAGE; - if ((mob_id = atoi(name.c_str())) == 0) + if ((mob_id = wrap<Species>(static_cast<uint16_t>(atoi(name.c_str())))) == Species()) mob_id = mobdb_searchname(name); - if (mob_id == 0) + if (mob_id == Species()) return ATCE::EXIST; x = sd->bl_x + random_::in(-5, 4); y = sd->bl_y + random_::in(-5, 4); - id = mob_once_spawn(sd, MOB_THIS_MAP, x, y, JAPANESE_NAME, mob_id, 1, NpcEvent()); + BlockId id = mob_once_spawn(sd, MOB_THIS_MAP, x, y, JAPANESE_NAME, mob_id, 1, NpcEvent()); dumb_ptr<mob_data> md = map_id_is_mob(id); if (md) { md->master_id = sd->bl_id; md->state.special_mob_ai = 1; - md->mode = mob_db[md->mob_class].mode | MobMode::AGGRESSIVE; - md->deletetimer = Timer(tick + std::chrono::minutes(1), + md->mode = get_mob_db(md->mob_class).mode | MobMode::AGGRESSIVE; + md->deletetimer = Timer(tick + 1_min, std::bind(mob_timer_delete, ph::_1, ph::_2, id)); clif_misceffect(md, 344); @@ -4420,12 +4422,12 @@ static ATCE atcommand_adjcmdlvl(Session *s, dumb_ptr<map_session_data>, ZString message) { - int newlev; + GmLevel newlev; XString cmd; if (!extract(message, record<' '>(&newlev, &cmd))) { - clif_displaymessage(s, "usage: @adjcmdlvl <lvl> <command>."); + clif_displaymessage(s, "usage: @adjcmdlvl <lvl> <command>."_s); return ATCE::USAGE; } @@ -4434,12 +4436,12 @@ ATCE atcommand_adjcmdlvl(Session *s, dumb_ptr<map_session_data>, if (it) { it->level = newlev; - clif_displaymessage(s, "@command level changed."); + clif_displaymessage(s, "@command level changed."_s); return ATCE::OKAY; } } - clif_displaymessage(s, "@command not found."); + clif_displaymessage(s, "@command not found."_s); return ATCE::EXIST; } @@ -4447,18 +4449,17 @@ static ATCE atcommand_adjgmlvl(Session *s, dumb_ptr<map_session_data>, ZString message) { - int newlev; + GmLevel newlev; CharName user; - if (!asplit(message, &newlev, &user) - || newlev < 0 || newlev > 99) + if (!asplit(message, &newlev, &user)) { - clif_displaymessage(s, "usage: @adjgmlvl <lvl> <user>."); + clif_displaymessage(s, "usage: @adjgmlvl <lvl> <user>."_s); return ATCE::USAGE; } dumb_ptr<map_session_data> pl_sd = map_nick2sd(user); - if (pl_sd == NULL) + if (pl_sd == nullptr) return ATCE::EXIST; pc_set_gm_level(pl_sd->status_key.account_id, newlev); @@ -4501,14 +4502,14 @@ constexpr size_t magic_skills_nr = sizeof(magic_skills) / sizeof(magic_skills[0]); static -ZString magic_skill_names[magic_skills_nr] = +LString magic_skill_names[magic_skills_nr] = { - {"magic"}, - {"life"}, - {"war"}, - {"transmute"}, - {"nature"}, - {"astral"}, + "magic"_s, + "life"_s, + "war"_s, + "transmute"_s, + "nature"_s, + "astral"_s, }; static @@ -4524,7 +4525,7 @@ ATCE atcommand_magic_info(Session *s, dumb_ptr<map_session_data>, if (pl_sd) { AString buf = STRPRINTF( - "`%s' has the following magic skills:", + "`%s' has the following magic skills:"_fmt, character); clif_displaymessage(s, buf); @@ -4532,7 +4533,7 @@ ATCE atcommand_magic_info(Session *s, dumb_ptr<map_session_data>, { SkillID sk = magic_skills[i]; buf = STRPRINTF( - "%d in %s", + "%d in %s"_fmt, pl_sd->status.skill[sk].lv, magic_skill_names[i]); if (pl_sd->status.skill[sk].lv) @@ -4542,7 +4543,7 @@ ATCE atcommand_magic_info(Session *s, dumb_ptr<map_session_data>, return ATCE::OKAY; } - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -4563,12 +4564,12 @@ ATCE atcommand_set_magic(Session *s, dumb_ptr<map_session_data>, if (!asplit(message, &magic_type, &value, &character)) { clif_displaymessage(s, - "Usage: @setmagic <school> <value> <char-name>, where <school> is either `magic', one of the school names, or `all'."); + "Usage: @setmagic <school> <value> <char-name>, where <school> is either `magic', one of the school names, or `all'."_s); return ATCE::USAGE; } SkillID skill_index = SkillID::NEGATIVE; - if ("all" == magic_type) + if ("all"_s == magic_type) skill_index = SkillID::ZERO; else { @@ -4585,12 +4586,12 @@ ATCE atcommand_set_magic(Session *s, dumb_ptr<map_session_data>, if (skill_index == SkillID::NEGATIVE) { clif_displaymessage(s, - "Incorrect school of magic. Use `magic', `nature', `life', `war', `transmute', `ether', or `all'."); + "Incorrect school of magic. Use `magic', `nature', `life', `war', `transmute', `ether', or `all'."_s); return ATCE::RANGE; } dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { if (skill_index == SkillID::ZERO) for (SkillID sk : magic_skills) @@ -4602,7 +4603,7 @@ ATCE atcommand_set_magic(Session *s, dumb_ptr<map_session_data>, return ATCE::OKAY; } - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -4661,21 +4662,21 @@ ATCE atcommand_jump_iterate(Session *s, dumb_ptr<map_session_data> sd, } if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARPTO) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp you to the map of this player."); + "You are not authorised to warp you to the map of this player."_s); return ATCE::PERM; } if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARP) - && battle_config.any_warp_GM_min_level > pc_isGM(sd)) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) { clif_displaymessage(s, - "You are not authorised to warp you from your actual map."); + "You are not authorised to warp you from your actual map."_s); return ATCE::PERM; } pc_setpos(sd, pl_sd->bl_m->name_, pl_sd->bl_x, pl_sd->bl_y, BeingRemoveWhy::WARPED); - AString output = STRPRINTF("Jump to %s", pl_sd->status_key.name); + AString output = STRPRINTF("Jump to %s"_fmt, pl_sd->status_key.name); clif_displaymessage(s, output); sd->followtarget = pl_sd->bl_id; @@ -4702,9 +4703,9 @@ ATCE atcommand_wgm(Session *s, dumb_ptr<map_session_data> sd, if (tmw_CheckChatSpam(sd, message)) return ATCE::OKAY; - tmw_GmHackMsg(STRPRINTF("[GM] %s: %s", sd->status_key.name, message)); + tmw_GmHackMsg(STRPRINTF("[GM] %s: %s"_fmt, sd->status_key.name, message)); if (!pc_isGM(sd)) - clif_displaymessage(s, "Message sent."); + clif_displaymessage(s, "Message sent."_s); return ATCE::OKAY; } @@ -4720,26 +4721,26 @@ ATCE atcommand_skillpool_info(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { SkillID pool_skills[MAX_SKILL_POOL]; int pool_skills_nr = skill_pool(pl_sd, pool_skills); int i; AString buf = STRPRINTF( - "Active skills %d out of %d for %s:", + "Active skills %d out of %d for %s:"_fmt, pool_skills_nr, skill_pool_max(pl_sd), character); clif_displaymessage(s, buf); for (i = 0; i < pool_skills_nr; ++i) { - buf = STRPRINTF(" - %s [%d]: power %d", + buf = STRPRINTF(" - %s [%d]: power %d"_fmt, skill_name(pool_skills[i]), pool_skills[i], skill_power(pl_sd, pool_skills[i])); clif_displaymessage(s, buf); } - buf = STRPRINTF("Learned skills out of %d for %s:", + buf = STRPRINTF("Learned skills out of %d for %s:"_fmt, skill_pool_skills_size, character); clif_displaymessage(s, buf); @@ -4750,7 +4751,7 @@ ATCE atcommand_skillpool_info(Session *s, dumb_ptr<map_session_data>, if (lvl) { - buf = STRPRINTF(" - %s [%d]: lvl %d", + buf = STRPRINTF(" - %s [%d]: lvl %d"_fmt, name, skill_pool_skills[i], lvl); clif_displaymessage(s, buf); } @@ -4759,7 +4760,7 @@ ATCE atcommand_skillpool_info(Session *s, dumb_ptr<map_session_data>, } else { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -4775,20 +4776,20 @@ ATCE atcommand_skillpool_focus(Session *s, dumb_ptr<map_session_data>, if (!asplit(message, &skill, &character)) { - clif_displaymessage(s, "Usage: @sp-focus <skill-nr> <char_name>"); + clif_displaymessage(s, "Usage: @sp-focus <skill-nr> <char_name>"_s); return ATCE::USAGE; } dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { if (skill_pool_activate(pl_sd, skill)) - clif_displaymessage(s, "Activation failed."); + clif_displaymessage(s, "Activation failed."_s); else - clif_displaymessage(s, "Activation successful."); + clif_displaymessage(s, "Activation successful."_s); } else - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::OKAY; } @@ -4804,15 +4805,15 @@ ATCE atcommand_skillpool_unfocus(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { if (skill_pool_deactivate(pl_sd, skill)) - clif_displaymessage(s, "Deactivation failed."); + clif_displaymessage(s, "Deactivation failed."_s); else - clif_displaymessage(s, "Deactivation successful."); + clif_displaymessage(s, "Deactivation successful."_s); } else - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::OKAY; } @@ -4829,13 +4830,13 @@ ATCE atcommand_skill_learn(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd != NULL) + if (pl_sd != nullptr) { set_skill(pl_sd, skill, level); clif_skillinfoblock(pl_sd); } else - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::OKAY; } @@ -4850,9 +4851,9 @@ ATCE atcommand_ipcheck(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd == NULL) + if (pl_sd == nullptr) { - clif_displaymessage(s, "Character not found."); + clif_displaymessage(s, "Character not found."_s); return ATCE::EXIST; } @@ -4873,7 +4874,7 @@ ATCE atcommand_ipcheck(Session *s, dumb_ptr<map_session_data>, if (ip == pl_sd->get_ip()) { AString output = STRPRINTF( - "Name: %s | Location: %s %d %d", + "Name: %s | Location: %s %d %d"_fmt, pl_sd->status_key.name, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y); clif_displaymessage(s, output); @@ -4881,7 +4882,7 @@ ATCE atcommand_ipcheck(Session *s, dumb_ptr<map_session_data>, } } - clif_displaymessage(s, "End of list"); + clif_displaymessage(s, "End of list"_s); return ATCE::OKAY; } @@ -4898,14 +4899,14 @@ ATCE atcommand_doomspot(Session *s, dumb_ptr<map_session_data> sd, if (pl_sd && pl_sd->state.auth && s2 != s && sd->bl_m == pl_sd->bl_m && sd->bl_x == pl_sd->bl_x && sd->bl_y == pl_sd->bl_y - && pc_isGM(sd) >= pc_isGM(pl_sd)) + && pc_isGM(sd).overwhelms(pc_isGM(pl_sd))) { // you can doom only lower or same gm level - pc_damage(NULL, pl_sd, pl_sd->status.hp + 1); - clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement."); + pc_damage(nullptr, pl_sd, pl_sd->status.hp + 1); + clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement."_s); } } - clif_displaymessage(s, "Judgement was made."); + clif_displaymessage(s, "Judgement was made."_s); return ATCE::OKAY; } @@ -4915,13 +4916,13 @@ ATCE atcommand_source(Session *s, dumb_ptr<map_session_data>, ZString) { clif_displaymessage(s, - "This server code consists of Free Software under GPL3&AGPL3"); + "This server code consists of Free Software under GPL3&AGPL3"_s); clif_displaymessage(s, - "This is commit " VERSION_HASH ", also known as " VERSION_FULL); + "This is commit " VERSION_HASH ", also known as " VERSION_FULL ""_s); clif_displaymessage(s, - "The version is " VERSION_STRING); + "The version is " VERSION_STRING ""_s); clif_displaymessage(s, - "For source, see " VENDOR_SOURCE); + "For source, see " VENDOR_SOURCE ""_s); return ATCE::OKAY; } @@ -4931,424 +4932,425 @@ ATCE atcommand_source(Session *s, dumb_ptr<map_session_data>, // declared extern above Map<XString, AtCommandInfo> atcommand_info = { - {"help", {"[level[-level]|category|@command]", + {"help"_s, {"[level[-level]|category|@command]"_s, 0, atcommand_help, - "Show help"}}, - {"setup", {"<level> <charname>", + "Show help"_s}}, + {"setup"_s, {"<level> <charname>"_s, 40, atcommand_setup, - "Safely set a chars levels and warp them to a special place (for TAW)"}}, - {"charwarp", {"<mapname> <x> <y> <charname>", + "Safely set a chars levels and warp them to a special place (for TAW)"_s}}, + {"charwarp"_s, {"<mapname> <x> <y> <charname>"_s, 60, atcommand_charwarp, - "Warp a character to a point on another map"}}, - {"warp", {"<mapname> [x] [y]", + "Warp a character to a point on another map"_s}}, + {"warp"_s, {"<mapname> [x] [y]"_s, 40, atcommand_warp, - "Warp yourself to another map"}}, - {"where", {"[charname]", + "Warp yourself to another map"_s}}, + {"where"_s, {"[charname]"_s, 40, atcommand_where, - "Show location of a character or yourself"}}, - {"goto", {"<charname>", + "Show location of a character or yourself"_s}}, + {"goto"_s, {"<charname>"_s, 40, atcommand_goto, - "Warp yourself to another character"}}, - {"jump", {"[x] [y]", + "Warp yourself to another character"_s}}, + {"jump"_s, {"[x] [y]"_s, 40, atcommand_jump, - "Warp yourself within a map"}}, - {"who", {"[subsequence]", + "Warp yourself within a map"_s}}, + {"who"_s, {"[subsequence]"_s, 40, atcommand_who, - "List matching players online, with location info"}}, - {"whogroup", {"[subsequence]", + "List matching players online, with location info"_s}}, + {"whogroup"_s, {"[subsequence]"_s, 40, atcommand_whogroup, - "List matching players online, with party info"}}, - {"whomap", {"[mapname]", + "List matching players online, with party info"_s}}, + {"whomap"_s, {"[mapname]"_s, 40, atcommand_whomap, - "List all players on the map, with location info"}}, - {"whomapgroup", {"[mapname]", + "List all players on the map, with location info"_s}}, + {"whomapgroup"_s, {"[mapname]"_s, 40, atcommand_whomapgroup, - "List all players on the map, with party info"}}, - {"whogm", {"[subsequence]", + "List all players on the map, with party info"_s}}, + {"whogm"_s, {"[subsequence]"_s, 40, atcommand_whogm, - "List matching GM players, with location, level, and party info"}}, - {"save", {"", + "List matching GM players, with location, level, and party info"_s}}, + {"save"_s, {""_s, 40, atcommand_save, - "Set your respawn point to your current location"}}, - {"return", {"", + "Set your respawn point to your current location"_s}}, + {"return"_s, {""_s, 40, atcommand_load, - "Return to your respawn point"}}, - {"load", {"", + "Return to your respawn point"_s}}, + {"load"_s, {""_s, 40, atcommand_load, - "Return to your respawn point"}}, - {"speed", {"<rate>", + "Return to your respawn point"_s}}, + {"speed"_s, {"<rate>"_s, 60, atcommand_speed, - "Set walk rate"}}, - {"storage", {"", + "Set walk rate"_s}}, + {"storage"_s, {""_s, 99, atcommand_storage, - "Open your storage"}}, - {"option", {"<opt1> [opt2] [option]", + "Open your storage"_s}}, + {"option"_s, {"<opt1> [opt2] [option]"_s, 80, atcommand_option, - "Set your 'option' status flags"}}, - {"hide", {"", + "Set your 'option' status flags"_s}}, + {"hide"_s, {""_s, 40, atcommand_hide, - "Toggle invisibility from monsters and certain commands"}}, - {"die", {"", + "Toggle invisibility from monsters and certain commands"_s}}, + {"die"_s, {""_s, 40, atcommand_die, - "Cause fatal damage to yourself"}}, - {"kill", {"<charname>", + "Cause fatal damage to yourself"_s}}, + {"kill"_s, {"<charname>"_s, 60, atcommand_kill, - "Cause fatal damage to another player"}}, - {"alive", {"", + "Cause fatal damage to another player"_s}}, + {"alive"_s, {""_s, 60, atcommand_alive, - "Restore life to yourself"}}, - {"kami", {"<message ...>", + "Restore life to yourself"_s}}, + {"kami"_s, {"<message ...>"_s, 99, atcommand_kami, - "Send an anonymous broadcast"}}, - {"heal", {"[hp] [sp]", + "Send an anonymous broadcast"_s}}, + {"heal"_s, {"[hp] [sp]"_s, 40, atcommand_heal, - "Restore or destroy your health"}}, - {"item", {"<item-name-or-id> [count]", + "Restore or destroy your health"_s}}, + {"item"_s, {"<item-name-or-id> [count]"_s, 80, atcommand_item, - "Summon items out of the void"}}, - {"itemreset", {"", + "Summon items out of the void"_s}}, + {"itemreset"_s, {""_s, 40, atcommand_itemreset, - "Cast all of your itens into the void (why would you ever want this?)"}}, - {"itemcheck", {"", + "Cast all of your itens into the void (why would you ever want this?)"_s}}, + {"itemcheck"_s, {""_s, 80, atcommand_itemcheck, - "Perform an internal integrity check on your items"}}, - {"blvl", {"<delta>", + "Perform an internal integrity check on your items"_s}}, + {"blvl"_s, {"<delta>"_s, 60, atcommand_baselevelup, - "Adjust your level"}}, - {"jlvl", {"<delta>", + "Adjust your level"_s}}, + {"jlvl"_s, {"<delta>"_s, 60, atcommand_joblevelup, - "Adjust your job level"}}, - {"gm", {"<password>", + "Adjust your job level"_s}}, + {"gm"_s, {"<password>"_s, 100, atcommand_gm, - "Receive GM powers"}}, - {"pvpoff", {"", + "Receive GM powers"_s}}, + {"pvpoff"_s, {""_s, 60, atcommand_pvpoff, - "Enable PvP on your map"}}, - {"pvpon", {"", + "Enable PvP on your map"_s}}, + {"pvpon"_s, {""_s, 60, atcommand_pvpon, - "Disable PvP on your map"}}, - {"model", {"<style> [color] [dye]", + "Disable PvP on your map"_s}}, + {"model"_s, {"<style> [color] [dye]"_s, 99, atcommand_model, - "Change your hairstyle and hair color"}}, - {"spawn", {"<mob-name-or-id> [count] [x] [y]", + "Change your hairstyle and hair color"_s}}, + {"spawn"_s, {"<mob-name-or-id> [count] [x] [y]"_s, 50, atcommand_spawn, - "Spawn normal monsters at location."}}, - {"killmonster", {"[map]", + "Spawn normal monsters at location."_s}}, + {"killmonster"_s, {"[map]"_s, 60, atcommand_killmonster, - "Kill all monsters (with drops)"}}, - {"killmonster2", {"[map]", + "Kill all monsters (with drops)"_s}}, + {"killmonster2"_s, {"[map]"_s, 60, atcommand_killmonster2, - "Kill all monsters (no drops)"}}, - {"gat", {"", + "Kill all monsters (no drops)"_s}}, + {"gat"_s, {""_s, 99, atcommand_gat, - "Dump the local walkmap"}}, - {"packet", {"<type> <flag>", + "Dump the local walkmap"_s}}, + {"packet"_s, {"<type> <flag>"_s, 99, atcommand_packet, - "Force a status change"}}, - {"stpoint", {"<amount>", + "Force a status change"_s}}, + {"stpoint"_s, {"<amount>"_s, 60, atcommand_statuspoint, - "Increase your stat points"}}, - {"skpoint", {"<amount>", + "Increase your stat points"_s}}, + {"skpoint"_s, {"<amount>"_s, 60, atcommand_skillpoint, - "Increase your skill points"}}, - {"zeny", {"<amount>", + "Increase your skill points"_s}}, + {"zeny"_s, {"<amount>"_s, 80, atcommand_zeny, - "Change how much money you have"}}, - {"str", {"<delta>", + "Change how much money you have"_s}}, + {"str"_s, {"<delta>"_s, 60, atcommand_param<ATTR::STR>, - "Adjust your strength"}}, - {"agi", {"<delta>", + "Adjust your strength"_s}}, + {"agi"_s, {"<delta>"_s, 60, atcommand_param<ATTR::AGI>, - "Adjust your agility"}}, - {"vit", {"<delta>", + "Adjust your agility"_s}}, + {"vit"_s, {"<delta>"_s, 60, atcommand_param<ATTR::VIT>, - "Adjust your vitality"}}, - {"int", {"<delta>", + "Adjust your vitality"_s}}, + {"int"_s, {"<delta>"_s, 60, atcommand_param<ATTR::INT>, - "Adjust your intelligence\0(TODO make this work in real life, I'm lonely)"}}, - {"dex", {"<delta>", + "Adjust your intelligence\0(TODO make this work in real life, I'm lonely)"_s}}, + {"dex"_s, {"<delta>"_s, 60, atcommand_param<ATTR::DEX>, - "Adjust your dexterity"}}, - {"luk", {"<delta>", + "Adjust your dexterity"_s}}, + {"luk"_s, {"<delta>"_s, 60, atcommand_param<ATTR::LUK>, - "Adjust your luck"}}, - {"recall", {"<charname>", + "Adjust your luck"_s}}, + {"recall"_s, {"<charname>"_s, 60, atcommand_recall, - "Warp a player to you"}}, - {"revive", {"<charname>", + "Warp a player to you"_s}}, + {"revive"_s, {"<charname>"_s, 60, atcommand_revive, - "Restore a player to full health"}}, - {"charstats", {"<charname>", + "Restore a player to full health"_s}}, + {"charstats"_s, {"<charname>"_s, 40, atcommand_character_stats, - "Show a bunch of stats about a single user"}}, - {"charstatsall", {"", + "Show a bunch of stats about a single user"_s}}, + {"charstatsall"_s, {""_s, 60, atcommand_character_stats_all, - "Show a bunch of stats about all online users"}}, - {"charoption", {"<opt1> <opt2> <opt3> <charname>", + "Show a bunch of stats about all online users"_s}}, + {"charoption"_s, {"<opt1> <opt2> <opt3> <charname>"_s, 80, atcommand_character_option, - "Set option flags on another character"}}, - {"charsave", {"<map> <x> <y> <charname>", + "Set option flags on another character"_s}}, + {"charsave"_s, {"<map> <x> <y> <charname>"_s, 60, atcommand_character_save, - "Set another character's save point"}}, - {"doom", {"", + "Set another character's save point"_s}}, + {"doom"_s, {""_s, 80, atcommand_doom, - "Kill everyone on the server"}}, - {"doommap", {"", + "Kill everyone on the server"_s}}, + {"doommap"_s, {""_s, 80, atcommand_doommap, - "Kill everyone on your map"}}, - {"raise", {"", + "Kill everyone on your map"_s}}, + {"raise"_s, {""_s, 80, atcommand_raise, - "Resurrect all players on the server"}}, - {"raisemap", {"", + "Resurrect all players on the server"_s}}, + {"raisemap"_s, {""_s, 80, atcommand_raisemap, - "Resurrect all players on your map"}}, - {"charbaselvl", {"<delta> <charname>", + "Resurrect all players on your map"_s}}, + {"charbaselvl"_s, {"<delta> <charname>"_s, 60, atcommand_character_baselevel, - "Adjust another character's level"}}, - {"charjlvl", {"<delta> <charname>", + "Adjust another character's level"_s}}, + {"charjlvl"_s, {"<delta> <charname>"_s, 60, atcommand_character_joblevel, - "Adjust another character's job level"}}, - {"kick", {"<charname>", + "Adjust another character's job level"_s}}, + {"kick"_s, {"<charname>"_s, 40, atcommand_kick, - "Transiently kick a player off the server"}}, - {"kickall", {"", + "Transiently kick a player off the server"_s}}, + {"kickall"_s, {""_s, 99, atcommand_kickall, - "Transiently kick all players off the server"}}, - {"questskill", {"<skill-id>", + "Transiently kick all players off the server"_s}}, + {"questskill"_s, {"<skill-id>"_s, 99, atcommand_questskill, - "Give yourself a quest (?) skill"}}, - {"charquestskill", {"<skill-id> <charname>", + "Give yourself a quest (?) skill"_s}}, + {"charquestskill"_s, {"<skill-id> <charname>"_s, 99, atcommand_charquestskill, - "Give another player a quest (?) skill"}}, - {"lostskill", {"<skill-id>", + "Give another player a quest (?) skill"_s}}, + {"lostskill"_s, {"<skill-id>"_s, 80, atcommand_lostskill, - "Take away one of your quest (?) skills"}}, - {"charlostskill", {"<skill-id> <charname>", + "Take away one of your quest (?) skills"_s}}, + {"charlostskill"_s, {"<skill-id> <charname>"_s, 99, atcommand_charlostskill, - "Take away one of another player's quest (?) skills"}}, - {"party", {"<name>", + "Take away one of another player's quest (?) skills"_s}}, + {"party"_s, {"<name>"_s, 99, atcommand_party, - "Create a new party"}}, - {"mapexit", {"", + "Create a new party"_s}}, + {"mapexit"_s, {""_s, 99, atcommand_mapexit, - "Try to kill the server kindly"}}, - {"idsearch", {"<item-subseq>", + "Try to kill the server kindly"_s}}, + {"idsearch"_s, {"<item-subseq>"_s, 80, atcommand_idsearch, - "Search for some items that might match"}}, - {"mapmove", {"<mapname> [x] [y]", + "Search for some items that might match"_s}}, + {"mapmove"_s, {"<mapname> [x] [y]"_s, 40, atcommand_warp, - "Warp to a different map"}}, - {"broadcast", {"<message ...>", + "Warp to a different map"_s}}, + {"broadcast"_s, {"<message ...>"_s, 40, atcommand_broadcast, - "Broadcast a message from you"}}, - {"localbroadcast", {"<message ...>", + "Broadcast a message from you"_s}}, + {"localbroadcast"_s, {"<message ...>"_s, 40, atcommand_localbroadcast, - "Broadcast a message from you locally"}}, - {"recallall", {"", + "Broadcast a message from you locally"_s}}, + {"recallall"_s, {""_s, 80, atcommand_recallall, - "Warp every online player to your current map"}}, - {"charskreset", {"<charname>", + "Warp every online player to your current map"_s}}, + {"charskreset"_s, {"<charname>"_s, 60, atcommand_charskreset, - "Reset a player's skill points"}}, - {"charstreset", {"<charname>", + "Reset a player's skill points"_s}}, + {"charstreset"_s, {"<charname>"_s, 60, atcommand_charstreset, - "Reset a player's stat points"}}, - {"charreset", {"<charname>", + "Reset a player's stat points"_s}}, + {"charreset"_s, {"<charname>"_s, 60, atcommand_charreset, - "Reset a player's skills, stats, and magic"}}, - {"charmodel", {"<hairstyle> <hair-color> <dye> <charname>", + "Reset a player's skills, stats, and magic"_s}}, + {"charmodel"_s, {"<hairstyle> <hair-color> <dye> <charname>"_s, 99, atcommand_charmodel, - "Change another character's appearance"}}, - {"charskpoint", {"<amount> <charname>", + "Change another character's appearance"_s}}, + {"charskpoint"_s, {"<amount> <charname>"_s, 60, atcommand_charskpoint, - "Adjust another player's skill points"}}, - {"charstpoint", {"<amount> <charname>", + "Adjust another player's skill points"_s}}, + {"charstpoint"_s, {"<amount> <charname>"_s, 60, atcommand_charstpoint, - "Adjust another player's stat points"}}, - {"charzeny", {"<delta> <charname>", + "Adjust another player's stat points"_s}}, + {"charzeny"_s, {"<delta> <charname>"_s, 80, atcommand_charzeny, - "Adjust another player's money"}}, - {"mapinfo", {"<0-2> [map]", + "Adjust another player's money"_s}}, + {"mapinfo"_s, {"<0-2> [map]"_s, 99, atcommand_mapinfo, - "Show some stats for the map. 1 also shows players, 2 also shows NPCs"}}, - {"dye", {"<dye>", + "Show some stats for the map. 1 also shows players, 2 also shows NPCs"_s}}, + {"dye"_s, {"<dye>"_s, 40, atcommand_dye, - "Don't use"}}, - {"ccolor", {"<dye>", + "Don't use"_s}}, + {"ccolor"_s, {"<dye>"_s, 40, atcommand_dye, - "Don't use"}}, - {"hairstyle", {"<style>", + "Don't use"_s}}, + {"hairstyle"_s, {"<style>"_s, 40, atcommand_hair_style, - "Change your hairstyle"}}, - {"haircolor", {"<color>", + "Change your hairstyle"_s}}, + {"haircolor"_s, {"<color>"_s, 40, atcommand_hair_color, - "Change your hair color"}}, - {"allstats", {"[value]", + "Change your hair color"_s}}, + {"allstats"_s, {"[value]"_s, 60, atcommand_all_stats, - "Adjust all stats by value (or maximum)"}}, - {"charchangesex", {"<charname>", + "Adjust all stats by value (or maximum)"_s}}, + {"charchangesex"_s, {"<charname>"_s, 60, atcommand_char_change_sex, - "Flip a characters sex and disconnect them"}}, - {"block", {"<charname>", + "Flip a characters sex and disconnect them"_s}}, + {"block"_s, {"<charname>"_s, 60, atcommand_char_block, - "Permanently block a player's account from the server"}}, - {"unblock", {"<charname>", + "Permanently block a player's account from the server"_s}}, + {"unblock"_s, {"<charname>"_s, 60, atcommand_char_unblock, - "Remove a permanent block from a player's account"}}, - {"ban", {"<timedelta> <charname>", + "Remove a permanent block from a player's account"_s}}, + {"ban"_s, {"<timedelta> <charname>"_s, 60, atcommand_char_ban, - "Ban a player's account from the server for a limited time"}}, - {"unban", {"<timedelta> <charname>", + "Ban a player's account from the server for a limited time"_s}}, + {"unban"_s, {"<timedelta> <charname>"_s, 60, atcommand_char_unban, - "Remove a limited ban from a player's account"}}, - {"partyspy", {"<party-name-or-id>", + "Remove a limited ban from a player's account"_s}}, + {"partyspy"_s, {"<party-name-or-id>"_s, 99, atcommand_partyspy, - "Listen to all chat within a party"}}, - {"partyrecall", {"<party-name-or-id>", + "Listen to all chat within a party"_s}}, + {"partyrecall"_s, {"<party-name-or-id>"_s, 99, atcommand_partyrecall, - "Warp all members of a party to you"}}, - {"enablenpc", {"<npc-name>", + "Warp all members of a party to you"_s}}, + {"enablenpc"_s, {"<npc-name>"_s, 80, atcommand_enablenpc, - "Enable an NPC for visibility"}}, - {"disablenpc", {"<npc-name>", + "Enable an NPC for visibility"_s}}, + {"disablenpc"_s, {"<npc-name>"_s, 80, atcommand_disablenpc, - "Disable an NPC for visibility"}}, - {"servertime", {"", + "Disable an NPC for visibility"_s}}, + {"servertime"_s, {""_s, 0, atcommand_servertime, - "Print the server's idea of the current time"}}, - {"chardelitem", {"<item-name-or-id> <count> <charname>", + "Print the server's idea of the current time"_s}}, + {"chardelitem"_s, {"<item-name-or-id> <count> <charname>"_s, 60, atcommand_chardelitem, - "Delete items from a player's inventory"}}, - {"listnearby", {"", + "Delete items from a player's inventory"_s}}, + {"listnearby"_s, {""_s, 40, atcommand_list_nearby, - "Print name of all nearby players"}}, - {"email", {"<actual@email> <new@email>", + "Print name of all nearby players"_s}}, + {"email"_s, {"<actual@email> <new@email>"_s, 0, atcommand_email, - "Changed your account's email"}}, - {"effect", {"<type> <flag>", + "Changed your account's email"_s}}, + {"effect"_s, {"<type> <flag>"_s, 99, atcommand_effect, - "Apply a special effect to yourself (or everyone! wtf?)"}}, - {"charitemlist", {"<charname>", + "Apply a special effect to yourself (or everyone! wtf?)"_s}}, + {"charitemlist"_s, {"<charname>"_s, 99, atcommand_character_item_list, - "List a player's items"}}, - {"charstoragelist", {"<charname>", + "List a player's items"_s}}, + {"charstoragelist"_s, {"<charname>"_s, 99, atcommand_character_storage_list, - "List a player's storage"}}, - {"addwarp", {"<mapname> <x> <y>", + "List a player's storage"_s}}, + {"addwarp"_s, {"<mapname> <x> <y>"_s, 80, atcommand_addwarp, - "Create a new permanent warp"}}, - {"killer", {"", + "Create a new permanent warp"_s}}, + {"killer"_s, {""_s, 60, atcommand_killer, - "Toggle whether you are a killer"}}, - {"charkiller", {"<charname>", + "Toggle whether you are a killer"_s}}, + {"charkiller"_s, {"<charname>"_s, 60, atcommand_charkiller, - "Toggle whether a player is a killer"}}, - {"npcmove", {"<x> <y> <npc-name>", + "Toggle whether a player is a killer"_s}}, + {"npcmove"_s, {"<x> <y> <npc-name>"_s, 80, atcommand_npcmove, - "Force an NPC to move on the map"}}, - {"killable", {"", + "Force an NPC to move on the map"_s}}, + {"killable"_s, {""_s, 60, atcommand_killable, - "Toggle whether you are killable"}}, - {"charkillable", {"<charname>", + "Toggle whether you are killable"_s}}, + {"charkillable"_s, {"<charname>"_s, 60, atcommand_charkillable, - "Toggle whether a player is killable"}}, - {"chareffect", {"<type> <target>", + "Toggle whether a player is killable"_s}}, + {"chareffect"_s, {"<type> <target>"_s, 40, atcommand_chareffect, - "Apply effect type with arg 0 to a player"}}, - {"dropall", {"", + "Apply effect type with arg 0 to a player"_s}}, + {"dropall"_s, {""_s, 99, atcommand_dropall, - "Drop all of your items"}}, - {"chardropall", {"<charname>", + "Drop all of your items"_s}}, + {"chardropall"_s, {"<charname>"_s, 60, atcommand_chardropall, - "Force a player to drop all of their items"}}, - {"storeall", {"", + "Force a player to drop all of their items"_s}}, + {"storeall"_s, {""_s, 60, atcommand_storeall, - "Store all of your items"}}, - {"charstoreall", {"<charname>", + "Store all of your items"_s}}, + {"charstoreall"_s, {"<charname>"_s, 60, atcommand_charstoreall, - "Store all of a player's items"}}, - {"rain", {"", + "Store all of a player's items"_s}}, + {"rain"_s, {""_s, 99, atcommand_rain, - "Enable the rain mapflag"}}, - {"snow", {"", + "Enable the rain mapflag"_s}}, + {"snow"_s, {""_s, 99, atcommand_snow, - "Enable the snow mapflag"}}, - {"sakura", {"", + "Enable the snow mapflag"_s}}, + {"sakura"_s, {""_s, 99, atcommand_sakura, - "Enable the sakura mapflag"}}, - {"fog", {"", + "Enable the sakura mapflag"_s}}, + {"fog"_s, {""_s, 99, atcommand_fog, - "Enable the fog mapflag"}}, - {"leaves", {"", + "Enable the fog mapflag"_s}}, + {"leaves"_s, {""_s, 99, atcommand_leaves, - "Enable the leaves mapflag"}}, - {"summon", {"<mob-id-or-name>", + "Enable the leaves mapflag"_s}}, + {"summon"_s, {"<mob-id-or-name>"_s, 50, atcommand_summon, - "Summon a slave monster temporarily"}}, - {"adjgmlvl", {"<level> <cmd>", + "Summon a slave monster temporarily"_s}}, + {"adjgmlvl"_s, {"<level> <cmd>"_s, 99, atcommand_adjgmlvl, - "Temporarily adjust the GM level of a command"}}, - {"adjcmdlvl", {"<level> <charname>", + "Temporarily adjust the GM level of a command"_s}}, + {"adjcmdlvl"_s, {"<level> <charname>"_s, 99, atcommand_adjcmdlvl, - "Temporarily adjust the GM level of a player"}}, - {"trade", {"<charname>", + "Temporarily adjust the GM level of a player"_s}}, + {"trade"_s, {"<charname>"_s, 60, atcommand_trade, - "Initiate trade with a player anywhere"}}, - {"charwipe", {"<charname>", + "Initiate trade with a player anywhere"_s}}, + {"charwipe"_s, {"<charname>"_s, 60, atcommand_char_wipe, - "Reset a character almost completely"}}, - {"setmagic", {"<school> <value> <charname>", + "Reset a character almost completely"_s}}, + {"setmagic"_s, {"<school> <value> <charname>"_s, 80, atcommand_set_magic, - "Force magic skill level"}}, - {"magicinfo", {"<charname>", + "Force magic skill level"_s}}, + {"magicinfo"_s, {"<charname>"_s, 80, atcommand_magic_info, - "Show magic skills of a palyer"}}, - {"log", {"<message ...>", + "Show magic skills of a palyer"_s}}, + {"log"_s, {"<message ...>"_s, 40, atcommand_log, - "Write something directly to the log"}}, - {"l", {"<message ...>", + "Write something directly to the log"_s}}, + {"l"_s, {"<message ...>"_s, 40, atcommand_log, - "Write something directly to the log"}}, - {"tee", {"<message ...>", + "Write something directly to the log"_s}}, + {"tee"_s, {"<message ...>"_s, 40, atcommand_tee, - "Duplicate a message to the log and public chat"}}, - {"t", {"<message ...>", + "Duplicate a message to the log and public chat"_s}}, + {"t"_s, {"<message ...>"_s, 40, atcommand_tee, - "Duplicate a message to the log and public chat"}}, - {"invisible", {"", + "Duplicate a message to the log and public chat"_s}}, + {"invisible"_s, {""_s, 50, atcommand_invisible, - "Make yourself invisible to players"}}, - {"visible", {"", + "Make yourself invisible to players"_s}}, + {"visible"_s, {""_s, 50, atcommand_visible, - "Make yourself visible to players"}}, - {"hugo", {"", + "Make yourself visible to players"_s}}, + {"hugo"_s, {""_s, 60, atcommand_iterate_forward_over_players, - "Jump to the next player"}}, - {"linus", {"", + "Jump to the next player"_s}}, + {"linus"_s, {""_s, 60, atcommand_iterate_backwards_over_players, - "Jump to the previous player"}}, - {"sp-info", {"<charname>", + "Jump to the previous player"_s}}, + {"sp-info"_s, {"<charname>"_s, 40, atcommand_skillpool_info, - "Show info about pool skills"}}, - {"sp-focus", {"<skill-id> <charname>", + "Show info about pool skills"_s}}, + {"sp-focus"_s, {"<skill-id> <charname>"_s, 80, atcommand_skillpool_focus, - "Focus on a pool skill"}}, - {"sp-unfocus", {"<skill-id> <charname>", + "Focus on a pool skill"_s}}, + {"sp-unfocus"_s, {"<skill-id> <charname>"_s, 80, atcommand_skillpool_unfocus, - "Unfocus off of a pool skill"}}, - {"skill-learn", {"<skill-id> <level> <charname>", + "Unfocus off of a pool skill"_s}}, + {"skill-learn"_s, {"<skill-id> <level> <charname>"_s, 80, atcommand_skill_learn, - "Change a skill level"}}, - {"wgm", {"<message ...>", + "Change a skill level"_s}}, + {"wgm"_s, {"<message ...>"_s, 0, atcommand_wgm, - "Send a message to online GMs"}}, - {"ipcheck", {"<charname>", + "Send a message to online GMs"_s}}, + {"ipcheck"_s, {"<charname>"_s, 60, atcommand_ipcheck, - "List players on the same IP address"}}, - {"doomspot", {"", + "List players on the same IP address"_s}}, + {"doomspot"_s, {""_s, 60, atcommand_doomspot, - "Kill all players on the same tile"}}, - {"source", {"", + "Kill all players on the same tile"_s}}, + {"source"_s, {""_s, 0, atcommand_source, - "Legal information about source code (must be a level 0 command!)"}}, + "Legal information about source code (must be a level 0 command!)"_s}}, }; +} // namespace tmwa diff --git a/src/map/atcommand.hpp b/src/map/atcommand.hpp index 95e3814..4bf5277 100644 --- a/src/map/atcommand.hpp +++ b/src/map/atcommand.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_ATCOMMAND_HPP -#define TMWA_MAP_ATCOMMAND_HPP +#pragma once // atcommand.hpp - GM commands. // // Copyright © ????-2004 Athena Dev Teams @@ -21,14 +20,21 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "map.hpp" +#include "../generic/fwd.hpp" +#include "../net/fwd.hpp" + +#include "../mmo/fwd.hpp" + + +namespace tmwa +{ bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd, - ZString message, int gmlvl); + ZString message, GmLevel gmlvl); bool atcommand_config_read(ZString cfgName); @@ -38,5 +44,4 @@ void log_atcommand(dumb_ptr<map_session_data> sd, ZString cmd); extern AString gm_log; void atcommand_config_write(ZString cfgName); - -#endif // TMWA_MAP_ATCOMMAND_HPP +} // namespace tmwa diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 8e4d435..eabe8a6 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -21,13 +21,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <cstring> +#include <algorithm> -#include "../compat/alg.hpp" #include "../compat/nullpo.hpp" #include "../strings/astring.hpp" #include "../strings/zstring.hpp" +#include "../strings/xstring.hpp" #include "../generic/random.hpp" @@ -47,12 +47,14 @@ #include "../poison.hpp" +namespace tmwa +{ static Battle_Config init_battle_config(); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshadow" +DIAG_PUSH(); +DIAG_I(shadow); struct Battle_Config battle_config = init_battle_config(); -#pragma GCC diagnostic pop +DIAG_POP(); /*========================================== * 自分をロックしている対象の数を返す(汎用) @@ -63,7 +65,7 @@ static int battle_counttargeted(dumb_ptr<block_list> bl, dumb_ptr<block_list> src, ATK target_lv) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::PC) return pc_counttargeted(bl->is_player(), src, target_lv); @@ -77,15 +79,15 @@ int battle_counttargeted(dumb_ptr<block_list> bl, dumb_ptr<block_list> src, * 戻りは整数で0以上 *------------------------------------------ */ -int battle_get_class(dumb_ptr<block_list> bl) +Species battle_get_class(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retr(Species(), bl); if (bl->bl_type == BL::MOB) return bl->is_mob()->mob_class; else if (bl->bl_type == BL::PC) - return 0; + return bl->is_player()->status.species; else - return 0; + return Species(); } /*========================================== @@ -111,7 +113,7 @@ DIR battle_get_dir(dumb_ptr<block_list> bl) */ int battle_get_lv(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::MOB) return bl->is_mob()->stats[mob_stat::LV]; else if (bl->bl_type == BL::PC) @@ -127,9 +129,9 @@ int battle_get_lv(dumb_ptr<block_list> bl) */ int battle_get_range(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::MOB) - return mob_db[bl->is_mob()->mob_class].range; + return get_mob_db(bl->is_mob()->mob_class).range; else if (bl->bl_type == BL::PC) return bl->is_player()->attackrange; else @@ -189,7 +191,7 @@ int battle_get_str(dumb_ptr<block_list> bl) int str = 0; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (bl->bl_type == BL::MOB) str = bl->is_mob()->stats[mob_stat::STR]; @@ -212,7 +214,7 @@ int battle_get_agi(dumb_ptr<block_list> bl) int agi = 0; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (bl->bl_type == BL::MOB) agi = bl->is_mob()->stats[mob_stat::AGI]; @@ -234,7 +236,7 @@ int battle_get_vit(dumb_ptr<block_list> bl) int vit = 0; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (bl->bl_type == BL::MOB) vit = bl->is_mob()->stats[mob_stat::VIT]; @@ -256,7 +258,7 @@ int battle_get_int(dumb_ptr<block_list> bl) int int_ = 0; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (bl->bl_type == BL::MOB) int_ = bl->is_mob()->stats[mob_stat::INT]; @@ -278,7 +280,7 @@ int battle_get_dex(dumb_ptr<block_list> bl) int dex = 0; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (bl->bl_type == BL::MOB) dex = bl->is_mob()->stats[mob_stat::DEX]; @@ -300,7 +302,7 @@ int battle_get_luk(dumb_ptr<block_list> bl) int luk = 0; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (bl->bl_type == BL::MOB) luk = bl->is_mob()->stats[mob_stat::LUK]; @@ -466,7 +468,7 @@ int battle_get_atk(dumb_ptr<block_list> bl) eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; int atk = 0; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (bl->bl_type == BL::PC) atk = bl->is_player()->watk; @@ -486,7 +488,7 @@ int battle_get_atk(dumb_ptr<block_list> bl) static int battle_get_atk_(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::PC) return bl->is_player()->watk_; else @@ -501,7 +503,7 @@ int battle_get_atk_(dumb_ptr<block_list> bl) static int battle_get_atk2(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::PC) return bl->is_player()->watk2; else @@ -524,7 +526,7 @@ int battle_get_atk2(dumb_ptr<block_list> bl) static int battle_get_atk_2(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::PC) return bl->is_player()->watk_2; else @@ -540,7 +542,7 @@ static int battle_get_matk1(dumb_ptr<block_list> bl) { eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (bl->bl_type == BL::MOB) { @@ -563,7 +565,7 @@ int battle_get_matk1(dumb_ptr<block_list> bl) static int battle_get_matk2(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::MOB) { int matk, int_ = battle_get_int(bl); @@ -587,7 +589,7 @@ int battle_get_def(dumb_ptr<block_list> bl) eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; int def = 0; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (bl->bl_type == BL::PC) { @@ -623,7 +625,7 @@ int battle_get_mdef(dumb_ptr<block_list> bl) eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; int mdef = 0; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (bl->bl_type == BL::PC) mdef = bl->is_player()->mdef; @@ -685,7 +687,7 @@ int battle_get_mdef2(dumb_ptr<block_list> bl) { int mdef2 = 0; - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::MOB) { dumb_ptr<mob_data> md = bl->is_mob(); @@ -710,16 +712,16 @@ int battle_get_mdef2(dumb_ptr<block_list> bl) */ interval_t battle_get_speed(dumb_ptr<block_list> bl) { - nullpo_retr(std::chrono::seconds(1), bl); + nullpo_retr(1_s, bl); if (bl->bl_type == BL::PC) return bl->is_player()->speed; else { - interval_t speed = std::chrono::seconds(1); + interval_t speed = 1_s; if (bl->bl_type == BL::MOB) speed = static_cast<interval_t>(bl->is_mob()->stats[mob_stat::SPEED]); - return std::max(speed, std::chrono::milliseconds(1)); + return std::max(speed, 1_ms); } } @@ -731,13 +733,13 @@ interval_t battle_get_speed(dumb_ptr<block_list> bl) // TODO figure out what all the doubling is about interval_t battle_get_adelay(dumb_ptr<block_list> bl) { - nullpo_retr(std::chrono::seconds(4), bl); + nullpo_retr(4_s, bl); if (bl->bl_type == BL::PC) return bl->is_player()->aspd * 2; else { eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data = battle_get_sc_data(bl); - interval_t adelay = std::chrono::seconds(4); + interval_t adelay = 4_s; int aspd_rate = 100; if (bl->bl_type == BL::MOB) adelay = static_cast<interval_t>(bl->is_mob()->stats[mob_stat::ADELAY]); @@ -759,16 +761,16 @@ interval_t battle_get_adelay(dumb_ptr<block_list> bl) interval_t battle_get_amotion(dumb_ptr<block_list> bl) { - nullpo_retr(std::chrono::seconds(2), bl); + nullpo_retr(2_s, bl); if (bl->bl_type == BL::PC) return bl->is_player()->amotion; else { eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data = battle_get_sc_data(bl); - interval_t amotion = std::chrono::seconds(2); + interval_t amotion = 2_s; int aspd_rate = 100; if (bl->bl_type == BL::MOB) - amotion = static_cast<interval_t>(mob_db[bl->is_mob()->mob_class].amotion); + amotion = static_cast<interval_t>(get_mob_db(bl->is_mob()->mob_class).amotion); if (sc_data) { @@ -789,14 +791,14 @@ interval_t battle_get_dmotion(dumb_ptr<block_list> bl) nullpo_retr(interval_t::zero(), bl); if (bl->bl_type == BL::MOB) { - return static_cast<interval_t>(mob_db[bl->is_mob()->mob_class].dmotion); + return static_cast<interval_t>(get_mob_db(bl->is_mob()->mob_class).dmotion); } else if (bl->bl_type == BL::PC) { return bl->is_player()->dmotion; } else - return std::chrono::seconds(2); + return 2_s; } LevelElement battle_get_element(dumb_ptr<block_list> bl) @@ -810,26 +812,26 @@ LevelElement battle_get_element(dumb_ptr<block_list> bl) return ret; } -int battle_get_party_id(dumb_ptr<block_list> bl) +PartyId battle_get_party_id(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retr(PartyId(), bl); if (bl->bl_type == BL::PC) return bl->is_player()->status.party_id; else if (bl->bl_type == BL::MOB) { dumb_ptr<mob_data> md = bl->is_mob(); - if (md->master_id > 0) - return -md->master_id; - return -md->bl_id; + if (md->master_id) + return wrap<PartyId>(-unwrap<BlockId>(md->master_id)); + return wrap<PartyId>(-unwrap<BlockId>(md->bl_id)); } - return 0; + return PartyId(); } Race battle_get_race(dumb_ptr<block_list> bl) { nullpo_retr(Race::formless, bl); if (bl->bl_type == BL::MOB) - return mob_db[bl->is_mob()->mob_class].race; + return get_mob_db(bl->is_mob()->mob_class).race; else if (bl->bl_type == BL::PC) return Race::demihuman; else @@ -840,7 +842,7 @@ MobMode battle_get_mode(dumb_ptr<block_list> bl) { nullpo_retr(MobMode::CAN_MOVE, bl); if (bl->bl_type == BL::MOB) - return mob_db[bl->is_mob()->mob_class].mode; + return get_mob_db(bl->is_mob()->mob_class).mode; // とりあえず動くということで1 return MobMode::CAN_MOVE; } @@ -883,60 +885,60 @@ eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> battle_ short *battle_get_sc_count(dumb_ptr<block_list> bl) { - nullpo_retr(NULL, bl); + nullpo_retr(nullptr, bl); if (bl->bl_type == BL::MOB) return &bl->is_mob()->sc_count; else if (bl->bl_type == BL::PC) return &bl->is_player()->sc_count; - return NULL; + return nullptr; } Opt1 *battle_get_opt1(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retn(bl); if (bl->bl_type == BL::MOB) return &bl->is_mob()->opt1; else if (bl->bl_type == BL::PC) return &bl->is_player()->opt1; else if (bl->bl_type == BL::NPC) return &bl->is_npc()->opt1; - return 0; + return nullptr; } Opt2 *battle_get_opt2(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retn(bl); if (bl->bl_type == BL::MOB) return &bl->is_mob()->opt2; else if (bl->bl_type == BL::PC) return &bl->is_player()->opt2; else if (bl->bl_type == BL::NPC) return &bl->is_npc()->opt2; - return 0; + return nullptr; } Opt3 *battle_get_opt3(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retn(bl); if (bl->bl_type == BL::MOB) return &bl->is_mob()->opt3; else if (bl->bl_type == BL::PC) return &bl->is_player()->opt3; else if (bl->bl_type == BL::NPC) return &bl->is_npc()->opt3; - return 0; + return nullptr; } Option *battle_get_option(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retn(bl); if (bl->bl_type == BL::MOB) return &bl->is_mob()->option; else if (bl->bl_type == BL::PC) return &bl->is_player()->status.option; else if (bl->bl_type == BL::NPC) return &bl->is_npc()->option; - return 0; + return nullptr; } //------------------------------------------------------------------- @@ -953,17 +955,17 @@ struct battle_delay_damage_ int battle_damage(dumb_ptr<block_list> bl, dumb_ptr<block_list> target, int damage, int flag) { - nullpo_ret(target); //blはNULLで呼ばれることがあるので他でチェック + nullpo_retz(target); //blはNULLで呼ばれることがあるので他でチェック if (damage == 0) return 0; - if (target->bl_prev == NULL) + if (target->bl_prev == nullptr) return 0; if (bl) { - if (bl->bl_prev == NULL) + if (bl->bl_prev == nullptr) return 0; } @@ -991,7 +993,7 @@ int battle_damage(dumb_ptr<block_list> bl, dumb_ptr<block_list> target, int battle_heal(dumb_ptr<block_list> bl, dumb_ptr<block_list> target, int hp, int sp, int flag) { - nullpo_ret(target); //blはNULLで呼ばれることがあるので他でチェック + nullpo_retz(target); //blはNULLで呼ばれることがあるので他でチェック if (target->bl_type == BL::PC && pc_isdead(target->is_player())) @@ -1012,7 +1014,7 @@ int battle_heal(dumb_ptr<block_list> bl, dumb_ptr<block_list> target, int hp, // 攻撃停止 int battle_stopattack(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::MOB) return mob_stopattack(bl->is_mob()); else if (bl->bl_type == BL::PC) @@ -1023,7 +1025,7 @@ int battle_stopattack(dumb_ptr<block_list> bl) // 移動停止 int battle_stopwalking(dumb_ptr<block_list> bl, int type) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::MOB) return mob_stop_walking(bl->is_mob(), type); else if (bl->bl_type == BL::PC) @@ -1040,9 +1042,9 @@ int battle_calc_damage(dumb_ptr<block_list>, dumb_ptr<block_list> bl, int damage, int div_, SkillID, int, BF flag) { - dumb_ptr<mob_data> md = NULL; + dumb_ptr<mob_data> md = nullptr; - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::MOB) md = bl->is_mob(); @@ -1059,7 +1061,7 @@ int battle_calc_damage(dumb_ptr<block_list>, dumb_ptr<block_list> bl, damage = 3; } - if (md != NULL && md->hp > 0 && damage > 0) // 反撃などのMOBスキル判定 + if (md != nullptr && md->hp > 0 && damage > 0) // 反撃などのMOBスキル判定 mobskill_event(md, flag); return damage; @@ -1071,8 +1073,8 @@ struct Damage battle_calc_mob_weapon_attack(dumb_ptr<block_list> src, SkillID skill_num, int skill_lv, int) { - dumb_ptr<map_session_data> tsd = NULL; - dumb_ptr<mob_data> md = src->is_mob(), tmd = NULL; + dumb_ptr<map_session_data> tsd = nullptr; + dumb_ptr<mob_data> md = src->is_mob(), tmd = nullptr; int hitrate, flee, cri = 0, atkmin, atkmax; int target_count = 1; int def1 = battle_get_def(target); @@ -1143,7 +1145,7 @@ struct Damage battle_calc_mob_weapon_attack(dumb_ptr<block_list> src, atkmin = battle_get_atk(src); atkmax = battle_get_atk2(src); } - if (mob_db[md->mob_class].range > 3) + if (get_mob_db(md->mob_class).range > 3) flag = (flag & ~BF::RANGEMASK) | BF::LONG; if (atkmin > atkmax) @@ -1282,7 +1284,7 @@ struct Damage battle_calc_mob_weapon_attack(dumb_ptr<block_list> src, damage = 0; // 完全回避の判定 - if (skill_num == SkillID::ZERO && skill_lv >= 0 && tsd != NULL + if (skill_num == SkillID::ZERO && skill_lv >= 0 && tsd != nullptr && random_::chance({battle_get_flee2(target), 1000})) { damage = 0; @@ -1292,7 +1294,7 @@ struct Damage battle_calc_mob_weapon_attack(dumb_ptr<block_list> src, if (battle_config.enemy_perfect_flee) { - if (skill_num == SkillID::ZERO && skill_lv >= 0 && tmd != NULL + if (skill_num == SkillID::ZERO && skill_lv >= 0 && tmd != nullptr && random_::chance({battle_get_flee2(target), 1000})) { damage = 0; @@ -1327,9 +1329,9 @@ int battle_is_unarmed(dumb_ptr<block_list> bl) { dumb_ptr<map_session_data> sd = bl->is_player(); - int sidx = sd->equip_index_maybe[EQUIP::SHIELD]; - int widx = sd->equip_index_maybe[EQUIP::WEAPON]; - return sidx == -1 && widx == -1; + IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD]; + IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON]; + return !sidx.ok() && !widx.ok(); } else return 0; @@ -1346,8 +1348,8 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src, SkillID skill_num, int skill_lv, int) { - dumb_ptr<map_session_data> sd = src->is_player(), tsd = NULL; - dumb_ptr<mob_data> tmd = NULL; + dumb_ptr<map_session_data> sd = src->is_player(), tsd = nullptr; + dumb_ptr<mob_data> tmd = nullptr; int hitrate, flee, cri = 0, atkmin, atkmax; int dex, target_count = 1; int def1 = battle_get_def(target); @@ -1417,9 +1419,9 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src, int dy = abs(src->bl_y - target->bl_y); int malus_dist; - target_distance = max(dx, dy); + target_distance = std::max(dx, dy); malus_dist = - max(0, target_distance - (skill_power(sd, SkillID::AC_OWL) / 75)); + std::max(0, target_distance - (skill_power(sd, SkillID::AC_OWL) / 75)); hitrate -= (malus_dist * (malus_dist + 1)); } @@ -1449,12 +1451,12 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src, atkmin = atkmin_ = dex; //最低ATKはDEXで初期化? sd->state.arrow_atk = 0; //arrow_atk初期化 - int widx = sd->equip_index_maybe[EQUIP::WEAPON]; - int sidx = sd->equip_index_maybe[EQUIP::SHIELD]; + IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON]; + IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD]; - if (widx >= 0 && sd->inventory_data[widx]) + if (widx.ok() && sd->inventory_data[widx]) atkmin = atkmin * (80 + sd->inventory_data[widx]->wlv * 20) / 100; - if (sidx >= 0 && sd->inventory_data[sidx]) + if (sidx.ok() && sd->inventory_data[sidx]) atkmin_ = atkmin_ * (80 + sd->inventory_data[sidx]->wlv * 20) / 100; if (sd->status.weapon == ItemLook::BOW) { //武器が弓矢の場合 @@ -1708,7 +1710,7 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src, } // 完全回避の判定 - if (skill_num == SkillID::ZERO && skill_lv >= 0 && tsd != NULL && div_ < 255 + if (skill_num == SkillID::ZERO && skill_lv >= 0 && tsd != nullptr && div_ < 255 && random_::chance({battle_get_flee2(target), 1000})) { damage = damage2 = 0; @@ -1719,7 +1721,7 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src, // 対象が完全回避をする設定がONなら if (battle_config.enemy_perfect_flee) { - if (skill_num == SkillID::ZERO && skill_lv >= 0 && tmd != NULL && div_ < 255 + if (skill_num == SkillID::ZERO && skill_lv >= 0 && tmd != nullptr && div_ < 255 && random_::chance({battle_get_flee2(target), 1000})) { damage = damage2 = 0; @@ -1809,7 +1811,7 @@ struct Damage battle_calc_magic_attack(dumb_ptr<block_list> bl, int matk1, matk2, damage = 0, div_ = 1; struct Damage md {}; int normalmagic_flag = 1; - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; nullpo_retr(md, bl); nullpo_retr(md, target); @@ -1885,7 +1887,7 @@ struct Damage battle_calc_misc_attack(dumb_ptr<block_list> bl, dumb_ptr<block_list> target, SkillID skill_num, int skill_lv, int) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; int damage = 0, div_ = 1; struct Damage md {}; int damagefix = 1; @@ -1965,7 +1967,7 @@ struct Damage battle_calc_attack(BF attack_type, flag); default: if (battle_config.error_log) - PRINTF("battle_calc_attack: unknwon attack type ! %d\n", + PRINTF("battle_calc_attack: unknwon attack type ! %d\n"_fmt, attack_type); break; } @@ -1979,7 +1981,7 @@ struct Damage battle_calc_attack(BF attack_type, ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target, tick_t tick) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> t_sc_data = battle_get_sc_data(target); struct Damage wd; @@ -1989,7 +1991,7 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target, if (src->bl_type == BL::PC) sd = src->is_player(); - if (src->bl_prev == NULL || target->bl_prev == NULL) + if (src->bl_prev == nullptr || target->bl_prev == nullptr) return ATK::ZERO; if (src->bl_type == BL::PC && pc_isdead(sd)) return ATK::ZERO; @@ -1998,7 +2000,7 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target, return ATK::ZERO; Opt1 *opt1 = battle_get_opt1(src); - if (opt1 != NULL && bool(*opt1)) + if (opt1 != nullptr && bool(*opt1)) { battle_stopattack(src); return ATK::ZERO; @@ -2010,8 +2012,8 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target, // 攻撃対象となりうるので攻撃 if (sd && sd->status.weapon == ItemLook::BOW) { - int aidx = sd->equip_index_maybe[EQUIP::ARROW]; - if (aidx >= 0) + IOff0 aidx = sd->equip_index_maybe[EQUIP::ARROW]; + if (aidx.ok()) { if (battle_config.arrow_decrement) pc_delitem(sd, aidx, 1, 0); @@ -2040,7 +2042,7 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target, wd.damage -= reduction; MAP_LOG_PC(target->is_player(), - "MAGIC-ABSORB-DMG %d", reduction); + "MAGIC-ABSORB-DMG %d"_fmt, reduction); } { @@ -2050,7 +2052,7 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target, && (sd->status.weapon == ItemLook::_16 || sd->status.weapon >= ItemLook::SINGLE_HANDED_COUNT) && wd.damage2 == 0) - clif_damage(src, target, tick + std::chrono::milliseconds(10), + clif_damage(src, target, tick + 10_ms, wd.amotion, wd.dmotion, 0, 1, DamageType::NORMAL, 0); } @@ -2058,37 +2060,37 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target, if (src->bl_type == BL::PC) { - int weapon_index = sd->equip_index_maybe[EQUIP::WEAPON]; - int weapon = 0; - if (weapon_index >= 0 && sd->inventory_data[weapon_index] + IOff0 weapon_index = sd->equip_index_maybe[EQUIP::WEAPON]; + ItemNameId weapon; + if (weapon_index.ok() && sd->inventory_data[weapon_index] && bool(sd->status.inventory[weapon_index].equip & EPOS::WEAPON)) weapon = sd->inventory_data[weapon_index]->nameid; - MAP_LOG("PC%d %s:%d,%d WPNDMG %s%d %d FOR %d WPN %d", - sd->status_key.char_id, src->bl_m->name_, src->bl_x, src->bl_y, - (target->bl_type == BL::PC) ? "PC" : "MOB", - (target->bl_type == BL::PC) - ? target->is_player()-> status_key.char_id - : target->bl_id, - battle_get_class(target), - wd.damage + wd.damage2, weapon); + MAP_LOG("PC%d %s:%d,%d WPNDMG %s%d %d FOR %d WPN %d"_fmt, + sd->status_key.char_id, src->bl_m->name_, src->bl_x, src->bl_y, + (target->bl_type == BL::PC) ? "PC"_s : "MOB"_s, + (target->bl_type == BL::PC) + ? unwrap<CharId>(target->is_player()->status_key.char_id) + : unwrap<BlockId>(target->bl_id), + battle_get_class(target), + wd.damage + wd.damage2, weapon); } if (target->bl_type == BL::PC) { dumb_ptr<map_session_data> sd2 = target->is_player(); - MAP_LOG("PC%d %s:%d,%d WPNINJURY %s%d %d FOR %d", - sd2->status_key.char_id, target->bl_m->name_, target->bl_x, target->bl_y, - (src->bl_type == BL::PC) ? "PC" : "MOB", - (src->bl_type == BL::PC) - ? src->is_player()->status_key.char_id - : src->bl_id, - battle_get_class(src), - wd.damage + wd.damage2); + MAP_LOG("PC%d %s:%d,%d WPNINJURY %s%d %d FOR %d"_fmt, + sd2->status_key.char_id, target->bl_m->name_, target->bl_x, target->bl_y, + (src->bl_type == BL::PC) ? "PC"_s : "MOB"_s, + (src->bl_type == BL::PC) + ? unwrap<CharId>(src->is_player()->status_key.char_id) + : unwrap<BlockId>(src->bl_id), + battle_get_class(src), + wd.damage + wd.damage2); } battle_damage(src, target, (wd.damage + wd.damage2), 0); - if (target->bl_prev != NULL && + if (target->bl_prev != nullptr && (target->bl_type != BL::PC || (target->bl_type == BL::PC && !pc_isdead(target->is_player())))) @@ -2161,11 +2163,11 @@ bool battle_check_undead(Race race, Element element) int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target, BCT flag) { - int s_p, t_p; + PartyId s_p, t_p; dumb_ptr<block_list> ss = src; - nullpo_ret(src); - nullpo_ret(target); + nullpo_retz(src); + nullpo_retz(target); if (flag & BCT_ENEMY) { // 反転フラグ @@ -2191,7 +2193,7 @@ int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target, if (src->bl_type == BL::MOB) { dumb_ptr<mob_data> md = src->is_mob(); - if (md && md->master_id > 0) + if (md && md->master_id) { if (md->master_id == target->bl_id) // 主なら肯定 return 1; @@ -2214,7 +2216,7 @@ int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target, } } } - if ((ss = map_id2bl(md->master_id)) == NULL) + if ((ss = map_id2bl(md->master_id)) == nullptr) return -1; } } @@ -2226,7 +2228,7 @@ int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target, && pc_isinvisible(target->is_player())) return -1; - if (src->bl_prev == NULL || // 死んでるならエラー + if (src->bl_prev == nullptr || // 死んでるならエラー (src->bl_type == BL::PC && pc_isdead(src->is_player()))) return -1; @@ -2246,9 +2248,6 @@ int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target, return 0; } -//PRINTF("ss:%d src:%d target:%d flag:0x%x %d %d ",ss->bl_id,src->bl_id,target->bl_id,flag,src->bl_type,target->bl_type); -//PRINTF("p:%d %d g:%d %d\n",s_p,t_p,s_g,t_g); - if (ss->bl_type == BL::PC && target->bl_type == BL::PC) { // 両方PVPモードなら否定(敵) if (ss->bl_m->flag.get(MapFlag::PVP) @@ -2256,7 +2255,7 @@ int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target, { // [MouseJstr] if (battle_config.pk_mode) return 1; // prevent novice engagement in pk_mode [Valaris] - else if (ss->bl_m->flag.get(MapFlag::PVP_NOPARTY) && s_p > 0 && t_p > 0 + else if (ss->bl_m->flag.get(MapFlag::PVP_NOPARTY) && s_p && t_p && s_p == t_p) return 1; return 0; @@ -2278,8 +2277,8 @@ int battle_check_range(dumb_ptr<block_list> src, dumb_ptr<block_list> bl, struct walkpath_data wpd; int arange; - nullpo_ret(src); - nullpo_ret(bl); + nullpo_retz(src); + nullpo_retz(bl); dx = abs(bl->bl_x - src->bl_x); dy = abs(bl->bl_y - src->bl_y); @@ -2313,10 +2312,10 @@ int battle_check_range(dumb_ptr<block_list> src, dumb_ptr<block_list> bl, Battle_Config init_battle_config() { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshadow" + DIAG_PUSH(); + DIAG_I(shadow); Battle_Config battle_config; -#pragma GCC diagnostic pop + DIAG_POP(); { battle_config.warp_point_debug = 0; battle_config.enemy_critical = 0; @@ -2430,17 +2429,17 @@ bool battle_config_read(ZString cfgName) io::ReadFile in(cfgName); if (!in.is_open()) { - PRINTF("file not found: %s\n", cfgName); + PRINTF("file not found: %s\n"_fmt, cfgName); return false; } AString line; while (in.getline(line)) { -#define BATTLE_CONFIG_VAR(name) {{#name}, &battle_config.name} +#define BATTLE_CONFIG_VAR(name) {#name##_s, &battle_config.name} const struct { - ZString str; + LString str; int *val; } data[] = { @@ -2550,12 +2549,12 @@ bool battle_config_read(ZString cfgName) ZString w2; if (!config_split(line, &w1, &w2)) { - PRINTF("Bad config line: %s\n", line); + PRINTF("Bad config line: %s\n"_fmt, line); rv = false; continue; } - if (w1 == "import") + if (w1 == "import"_s) { battle_config_read(w2); continue; @@ -2568,7 +2567,7 @@ bool battle_config_read(ZString cfgName) goto continue_outer; } - PRINTF("WARNING: unknown battle conf key: %s\n", AString(w1)); + PRINTF("WARNING: unknown battle conf key: %s\n"_fmt, AString(w1)); rv = false; continue_outer: @@ -2581,7 +2580,7 @@ bool battle_config_read(ZString cfgName) void battle_config_check() { { - if (static_cast<interval_t>(battle_config.flooritem_lifetime) < std::chrono::seconds(1)) + if (static_cast<interval_t>(battle_config.flooritem_lifetime) < 1_s) battle_config.flooritem_lifetime = std::chrono::duration_cast<std::chrono::milliseconds>(LIFETIME_FLOORITEM).count(); if (battle_config.restart_hp_rate < 0) battle_config.restart_hp_rate = 0; @@ -2686,3 +2685,4 @@ void battle_config_check() battle_config.mask_ip_gms = 1; } } +} // namespace tmwa diff --git a/src/map/battle.hpp b/src/map/battle.hpp index b8060a9..97a4a86 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_BATTLE_HPP -#define TMWA_MAP_BATTLE_HPP +#pragma once // battle.hpp - Not so scary code. // // Copyright © ????-2004 Athena Dev Teams @@ -21,18 +20,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "battle.t.hpp" +#include "battle.t.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "../mmo/timer.t.hpp" +#include "../generic/fwd.hpp" -# include "magic-interpreter.t.hpp" -# include "map.t.hpp" -# include "skill.t.hpp" +#include "../net/timer.t.hpp" +#include "clif.t.hpp" +#include "map.t.hpp" +#include "skill.t.hpp" + + +namespace tmwa +{ // ダメージ struct Damage { @@ -44,10 +48,6 @@ struct Damage ATK dmg_lv; }; -struct map_session_data; -struct mob_data; -struct block_list; - // ダメージ計算 struct Damage battle_calc_attack(BF attack_type, @@ -69,7 +69,7 @@ ATK battle_weapon_attack(dumb_ptr<block_list> bl, dumb_ptr<block_list> target, tick_t tick); int battle_is_unarmed(dumb_ptr<block_list> bl); -int battle_get_class(dumb_ptr<block_list> bl); +Species battle_get_class(dumb_ptr<block_list> bl); DIR battle_get_dir(dumb_ptr<block_list> bl); int battle_get_lv(dumb_ptr<block_list> bl); int battle_get_range(dumb_ptr<block_list> bl); @@ -95,7 +95,7 @@ Element battle_get_elem_type(dumb_ptr<block_list> bl) { return battle_get_element(bl).element; } -int battle_get_party_id(dumb_ptr<block_list> bl); +PartyId battle_get_party_id(dumb_ptr<block_list> bl); Race battle_get_race(dumb_ptr<block_list> bl); MobMode battle_get_mode(dumb_ptr<block_list> bl); int battle_get_stat(SP stat_id, dumb_ptr<block_list> bl); @@ -225,5 +225,4 @@ extern struct Battle_Config bool battle_config_read(ZString cfgName); void battle_config_check(); - -#endif // TMWA_MAP_BATTLE_HPP +} // namespace tmwa diff --git a/src/map/battle.t.hpp b/src/map/battle.t.hpp index 9685ae7..53c34ff 100644 --- a/src/map/battle.t.hpp +++ b/src/map/battle.t.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_BATTLE_T_HPP -#define TMWA_MAP_BATTLE_T_HPP +#pragma once // battle.t.hpp - Not so scary code. // // Copyright © ????-2004 Athena Dev Teams @@ -21,10 +20,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../generic/enum.hpp" +#include <cstdint> +#include "../generic/enum.hpp" + + +namespace tmwa +{ namespace e { enum class BF : uint16_t @@ -65,11 +69,11 @@ struct BCT }; constexpr -BCT operator & (BCT l, BCT r) { return {uint8_t(l.lo & r.lo), uint8_t(l.mid & r.mid), uint8_t(l.classic & r.classic), uint8_t(l.level & r.level), uint8_t(l.unused & r.unused) }; } +BCT operator & (BCT l, BCT r) { return {static_cast<uint8_t>(l.lo & r.lo), static_cast<uint8_t>(l.mid & r.mid), static_cast<uint8_t>(l.classic & r.classic), static_cast<uint8_t>(l.level & r.level), static_cast<uint8_t>(l.unused & r.unused) }; } constexpr -BCT operator | (BCT l, BCT r) { return {uint8_t(l.lo | r.lo), uint8_t(l.mid | r.mid), uint8_t(l.classic | r.classic), uint8_t(l.level | r.level), uint8_t(l.unused | r.unused) }; } +BCT operator | (BCT l, BCT r) { return {static_cast<uint8_t>(l.lo | r.lo), static_cast<uint8_t>(l.mid | r.mid), static_cast<uint8_t>(l.classic | r.classic), static_cast<uint8_t>(l.level | r.level), static_cast<uint8_t>(l.unused | r.unused) }; } constexpr -BCT operator ^ (BCT l, BCT r) { return {uint8_t(l.lo ^ r.lo), uint8_t(l.mid ^ r.mid), uint8_t(l.classic ^ r.classic), uint8_t(l.level ^ r.level), uint8_t(l.unused ^ r.unused) }; } +BCT operator ^ (BCT l, BCT r) { return {static_cast<uint8_t>(l.lo ^ r.lo), static_cast<uint8_t>(l.mid ^ r.mid), static_cast<uint8_t>(l.classic ^ r.classic), static_cast<uint8_t>(l.level ^ r.level), static_cast<uint8_t>(l.unused ^ r.unused) }; } inline BCT& operator &= (BCT& l, BCT r) { return l = l & r; } inline @@ -237,15 +241,4 @@ earray<Races, Race, Race::COUNT> race_shift //= Races::boss, Races::other, }}; - -enum class DamageType : uint8_t -{ - NORMAL = 0x00, - TAKEITEM = 0x01, - RETURNED = 0x04, - DOUBLED = 0x08, - CRITICAL = 0x0a, - FLEE2 = 0x0b, -}; - -#endif // TMWA_MAP_BATTLE_T_HPP +} // namespace tmwa diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp index fa95be7..0748f43 100644 --- a/src/map/chrif.cpp +++ b/src/map/chrif.cpp @@ -20,10 +20,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <arpa/inet.h> - -#include <cstring> - #include "../compat/fun.hpp" #include "../compat/nullpo.hpp" @@ -32,8 +28,15 @@ #include "../io/cxxstdio.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" +#include "../net/ip.hpp" +#include "../net/packets.hpp" +#include "../net/socket.hpp" +#include "../net/timer.hpp" + +#include "../proto2/char-map.hpp" + +#include "../mmo/human_time_diff.hpp" +#include "../mmo/mmo.hpp" #include "../mmo/utils.hpp" #include "battle.hpp" @@ -47,15 +50,9 @@ #include "../poison.hpp" -static -const int packet_len_table[0x20] = -{ - 60, 3, 10, 27, 22, -1, 6, -1, // 2af8-2aff - 6, -1, 18, 7, -1, 49, 44, 0, // 2b00-2b07 - 6, 30, -1, 10, 86, 7, 44, 34, // 2b08-2b0f - -1, -1, 10, 6, 11, -1, 0, 0, // 2b10-2b17 -}; +namespace tmwa +{ Session *char_session; static IP4Address char_ip; @@ -132,13 +129,12 @@ int chrif_save(dumb_ptr<map_session_data> sd) pc_makesavestatus(sd); - WFIFOW(char_session, 0) = 0x2b01; - WFIFOW(char_session, 2) = sizeof(sd->status_key) + sizeof(sd->status) + 12; - WFIFOL(char_session, 4) = sd->bl_id; - WFIFOL(char_session, 8) = sd->char_id; - WFIFO_STRUCT(char_session, 12, sd->status_key); - WFIFO_STRUCT(char_session, 12 + sizeof(sd->status_key), sd->status); - WFIFOSET(char_session, WFIFOW(char_session, 2)); + Packet_Payload<0x2b01> payload_01; + payload_01.account_id = block_to_account(sd->bl_id); + payload_01.char_id = sd->char_id_; + payload_01.char_key = sd->status_key; + payload_01.char_data = sd->status; + send_ppacket<0x2b01>(char_session, payload_01); //For data sync if (sd->state.storage_open) @@ -154,13 +150,13 @@ int chrif_save(dumb_ptr<map_session_data> sd) static int chrif_connect(Session *s) { - WFIFOW(s, 0) = 0x2af8; - WFIFO_STRING(s, 2, userid, 24); - WFIFO_STRING(s, 26, passwd, 24); - WFIFOL(s, 50) = 0; - WFIFOIP(s, 54) = clif_getip(); - WFIFOW(s, 58) = clif_getport(); // [Valaris] thanks to fov - WFIFOSET(s, 60); + Packet_Fixed<0x2af8> fixed_f8; + fixed_f8.account_name = userid; + fixed_f8.account_pass = passwd; + fixed_f8.unused = 0; + fixed_f8.ip = clif_getip(); + fixed_f8.port = clif_getport(); + send_fpacket<0x2af8, 60>(s, fixed_f8); return 0; } @@ -172,19 +168,17 @@ int chrif_connect(Session *s) static int chrif_sendmap(Session *s) { - int i = 0; - - WFIFOW(s, 0) = 0x2afa; + std::vector<Packet_Repeat<0x2afa>> repeat_fa; for (auto& pair : maps_db) { map_abstract *ma = pair.second.get(); if (!ma->gat) continue; - WFIFO_STRING(s, 4 + i * 16, ma->name_, 16); - i++; + Packet_Repeat<0x2afa> info; + info.map_name = ma->name_; + repeat_fa.push_back(info); } - WFIFOW(s, 2) = 4 + i * 16; - WFIFOSET(s, WFIFOW(s, 2)); + send_packet_repeatonly<0x2afa, 4, 16>(s, repeat_fa); return 0; } @@ -194,23 +188,21 @@ int chrif_sendmap(Session *s) *------------------------------------------ */ static -int chrif_recvmap(Session *s) +int chrif_recvmap(Session *, Packet_Head<0x2b04> head, const std::vector<Packet_Repeat<0x2b04>>& repeat) { - int i, j; - if (chrif_state < 2) // まだ準備中 return -1; - IP4Address ip = RFIFOIP(s, 4); - uint16_t port = RFIFOW(s, 8); - for (i = 10, j = 0; i < RFIFOW(s, 2); i += 16, j++) + IP4Address ip = head.ip; + uint16_t port = head.port; + for (const Packet_Repeat<0x2b04>& i : repeat) { - MapName map = RFIFO_STRING<16>(s, i); + MapName map = i.map_name; map_setipport(map, ip, port); } if (battle_config.etc_log) - PRINTF("recv map on %s:%d (%d maps)\n", - ip, port, j); + PRINTF("recv map on %s:%d (%zu maps)\n"_fmt, + ip, port, repeat.size()); return 0; } @@ -224,6 +216,9 @@ int chrif_changemapserver(dumb_ptr<map_session_data> sd, { nullpo_retr(-1, sd); + if (!char_session) + return -1; + IP4Address s_ip; for (io::FD i : iter_fds()) { @@ -238,19 +233,19 @@ int chrif_changemapserver(dumb_ptr<map_session_data> sd, } } - WFIFOW(char_session, 0) = 0x2b05; - WFIFOL(char_session, 2) = sd->bl_id; - WFIFOL(char_session, 6) = sd->login_id1; - WFIFOL(char_session, 10) = sd->login_id2; - WFIFOL(char_session, 14) = sd->status_key.char_id; - WFIFO_STRING(char_session, 18, name, 16); - WFIFOW(char_session, 34) = x; - WFIFOW(char_session, 36) = y; - WFIFOIP(char_session, 38) = ip; - WFIFOL(char_session, 42) = port; - WFIFOB(char_session, 44) = static_cast<uint8_t>(sd->status.sex); - WFIFOIP(char_session, 45) = s_ip; - WFIFOSET(char_session, 49); + Packet_Fixed<0x2b05> fixed_05; + fixed_05.account_id = block_to_account(sd->bl_id); + fixed_05.login_id1 = sd->login_id1; + fixed_05.login_id2 = sd->login_id2; + fixed_05.char_id = sd->status_key.char_id; + fixed_05.map_name = name; + fixed_05.x = x; + fixed_05.y = y; + fixed_05.map_ip = ip; + fixed_05.map_port = port; + fixed_05.sex = sd->status.sex; + fixed_05.client_ip = s_ip; + send_fpacket<0x2b05, 49>(char_session, fixed_05); return 0; } @@ -260,25 +255,26 @@ int chrif_changemapserver(dumb_ptr<map_session_data> sd, *------------------------------------------ */ static -int chrif_changemapserverack(Session *s) +int chrif_changemapserverack(Session *, const Packet_Fixed<0x2b06>& fixed) { - dumb_ptr<map_session_data> sd = map_id2sd(RFIFOL(s, 2)); + dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(fixed.account_id)); - if (sd == NULL || sd->status_key.char_id != RFIFOL(s, 14)) + if (sd == nullptr || sd->status_key.char_id != fixed.char_id) return -1; - if (RFIFOL(s, 6) == 1) + // I am fairly certain that this is not possible + if (fixed.error == 1) { if (battle_config.error_log) - PRINTF("map server change failed.\n"); + PRINTF("map server change failed.\n"_fmt); pc_authfail(sd->status_key.account_id); return 0; } - MapName mapname = RFIFO_STRING<16>(s, 18); - uint16_t x = RFIFOW(s, 34); - uint16_t y = RFIFOW(s, 36); - IP4Address ip = RFIFOIP(s, 38); - uint16_t port = RFIFOW(s, 42); + MapName mapname = fixed.map_name; + uint16_t x = fixed.x; + uint16_t y = fixed.y; + IP4Address ip = fixed.map_ip; + uint16_t port = fixed.map_port; clif_changemapserver(sd, mapname, x, y, ip, port); return 0; @@ -289,25 +285,22 @@ int chrif_changemapserverack(Session *s) *------------------------------------------ */ static -int chrif_connectack(Session *s) +int chrif_connectack(Session *s, const Packet_Fixed<0x2af9>& fixed) { - if (RFIFOB(s, 2)) + if (fixed.code) { - PRINTF("Connected to char-server failed %d.\n", RFIFOB(s, 2)); + PRINTF("Connected to char-server failed %d.\n"_fmt, fixed.code); exit(1); } - PRINTF("Connected to char-server (connection #%d).\n", s); + PRINTF("Connected to char-server (connection #%d).\n"_fmt, s); chrif_state = 1; chrif_sendmap(s); - PRINTF("chrif: OnCharIfInit event done. (%d events)\n", - npc_event_doall(stringish<ScriptLabel>("OnCharIfInit"))); - PRINTF("chrif: OnInterIfInit event done. (%d events)\n", - npc_event_doall(stringish<ScriptLabel>("OnInterIfInit"))); - - // <Agit> Run Event [AgitInit] -// PRINTF("NPC_Event:[OnAgitInit] do (%d) events (Agit Initialize).\n", npc_event_doall("OnAgitInit")); + PRINTF("chrif: OnCharIfInit event done. (%d events)\n"_fmt, + npc_event_doall(stringish<ScriptLabel>("OnCharIfInit"_s))); + PRINTF("chrif: OnInterIfInit event done. (%d events)\n"_fmt, + npc_event_doall(stringish<ScriptLabel>("OnInterIfInit"_s))); return 0; } @@ -317,16 +310,16 @@ int chrif_connectack(Session *s) *------------------------------------------ */ static -int chrif_sendmapack(Session *s) +int chrif_sendmapack(Session *, Packet_Fixed<0x2afb> fixed) { - if (RFIFOB(s, 2)) + if (fixed.unknown) //impossible { - PRINTF("chrif : send map list to char server failed %d\n", - RFIFOB(s, 2)); + PRINTF("chrif : send map list to char server failed %d\n"_fmt, + fixed.unknown); exit(1); } - wisp_server_name = stringish<CharName>(RFIFO_STRING<24>(s, 3)); + wisp_server_name = fixed.whisper_name; chrif_state = 2; @@ -352,13 +345,13 @@ int chrif_authreq(dumb_ptr<map_session_data> sd) if (dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get())) == sd) { assert (s == sd->sess); - WFIFOW(char_session, 0) = 0x2afc; - WFIFOL(char_session, 2) = sd->bl_id; - WFIFOL(char_session, 6) = sd->char_id; - WFIFOL(char_session, 10) = sd->login_id1; - WFIFOL(char_session, 14) = sd->login_id2; - WFIFOIP(char_session, 18) = s->client_ip; - WFIFOSET(char_session, 22); + Packet_Fixed<0x2afc> fixed_fc; + fixed_fc.account_id = block_to_account(sd->bl_id); + fixed_fc.char_id = sd->char_id_; + fixed_fc.login_id1 = sd->login_id1; + fixed_fc.login_id2 = sd->login_id2; + fixed_fc.ip = s->client_ip; + send_fpacket<0x2afc, 22>(char_session, fixed_fc); break; } } @@ -391,12 +384,12 @@ int chrif_charselectreq(dumb_ptr<map_session_data> sd) } } - WFIFOW(char_session, 0) = 0x2b02; - WFIFOL(char_session, 2) = sd->bl_id; - WFIFOL(char_session, 6) = sd->login_id1; - WFIFOL(char_session, 10) = sd->login_id2; - WFIFOIP(char_session, 14) = s_ip; - WFIFOSET(char_session, 18); + Packet_Fixed<0x2b02> fixed_02; + fixed_02.account_id = block_to_account(sd->bl_id); + fixed_02.login_id1 = sd->login_id1; + fixed_02.login_id2 = sd->login_id2; + fixed_02.ip = s_ip; + send_fpacket<0x2b02, 18>(char_session, fixed_02); return 0; } @@ -405,35 +398,38 @@ int chrif_charselectreq(dumb_ptr<map_session_data> sd) * GMに変化要求 *------------------------------------------ */ -void chrif_changegm(int id, ZString pass) +void chrif_changegm(AccountId id, ZString pass) { + if (!char_session) + return; + if (battle_config.etc_log) - PRINTF("chrif_changegm: account: %d, password: '%s'.\n", id, pass); - - size_t len = pass.size() + 1; - WFIFOW(char_session, 0) = 0x2b0a; - WFIFOW(char_session, 2) = len + 8; - WFIFOL(char_session, 4) = id; - WFIFO_STRING(char_session, 8, pass, len); - WFIFOSET(char_session, len + 8); + PRINTF("chrif_changegm: account: %d, password: '%s'.\n"_fmt, id, pass); + + Packet_Head<0x2b0a> head_0a; + head_0a.account_id = id; + send_vpacket<0x2b0a, 8, 1>(char_session, head_0a, pass); } /*========================================== * Change Email *------------------------------------------ */ -void chrif_changeemail(int id, AccountEmail actual_email, +void chrif_changeemail(AccountId id, AccountEmail actual_email, AccountEmail new_email) { + if (!char_session) + return; + if (battle_config.etc_log) - PRINTF("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n", - id, actual_email, new_email); - - WFIFOW(char_session, 0) = 0x2b0c; - WFIFOL(char_session, 2) = id; - WFIFO_STRING(char_session, 6, actual_email, 40); - WFIFO_STRING(char_session, 46, new_email, 40); - WFIFOSET(char_session, 86); + PRINTF("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n"_fmt, + id, actual_email, new_email); + + Packet_Fixed<0x2b0c> fixed_0c; + fixed_0c.account_id = id; + fixed_0c.old_email = actual_email; + fixed_0c.new_email = new_email; + send_fpacket<0x2b0c, 86>(char_session, fixed_0c); } /*========================================== @@ -447,17 +443,20 @@ void chrif_changeemail(int id, AccountEmail actual_email, * 5: changesex *------------------------------------------ */ -void chrif_char_ask_name(int id, CharName character_name, short operation_type, +void chrif_char_ask_name(AccountId id, CharName character_name, short operation_type, HumanTimeDiff modif) { - WFIFOW(char_session, 0) = 0x2b0e; - WFIFOL(char_session, 2) = id; // account_id of who ask (for answer) -1 if nobody - WFIFO_STRING(char_session, 6, character_name.to__actual(), 24); - WFIFOW(char_session, 30) = operation_type; // type of operation + if (!char_session) + return; + + Packet_Fixed<0x2b0e> fixed_0e; + fixed_0e.account_id = id; // who ask, or nobody + fixed_0e.char_name = character_name; + fixed_0e.operation = operation_type; // type of operation if (operation_type == 2) - WFIFO_STRUCT(char_session, 32, modif); - PRINTF("chrif : sended 0x2b0e\n"); - WFIFOSET(char_session, 44); + fixed_0e.ban_add = modif; + PRINTF("chrif : sended 0x2b0e\n"_fmt); + send_fpacket<0x2b0e, 44>(char_session, fixed_0e); } /*========================================== @@ -477,123 +476,123 @@ void chrif_char_ask_name(int id, CharName character_name, short operation_type, *------------------------------------------ */ static -int chrif_char_ask_name_answer(Session *s) +int chrif_char_ask_name_answer(Session *, const Packet_Fixed<0x2b0f>& fixed) { - int acc = RFIFOL(s, 2); // account_id of who has asked (-1 if nobody) - CharName player_name = stringish<CharName>(RFIFO_STRING<24>(s, 6)); + AccountId acc = fixed.account_id; // who asked, or nobody + CharName player_name = fixed.char_name; - dumb_ptr<map_session_data> sd = map_id2sd(acc); - if (acc >= 0 && sd != NULL) + dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(acc)); + if (acc && sd != nullptr) { AString output; - if (RFIFOW(s, 32) == 1) // player not found - output = STRPRINTF("The player '%s' doesn't exist.", + if (fixed.error == 1) // player not found + output = STRPRINTF("The player '%s' doesn't exist."_fmt, player_name); else { - switch (RFIFOW(s, 30)) + switch (fixed.operation) { case 1: // block - switch (RFIFOW(s, 32)) + switch (fixed.error) { case 0: // login-server resquest done output = STRPRINTF( - "Login-server has been asked to block the player '%s'.", + "Login-server has been asked to block the player '%s'."_fmt, player_name); break; //case 1: // player not found case 2: // gm level too low output = STRPRINTF( - "Your GM level don't authorise you to block the player '%s'.", + "Your GM level don't authorise you to block the player '%s'."_fmt, player_name); break; case 3: // login-server offline output = STRPRINTF( - "Login-server is offline. Impossible to block the the player '%s'.", + "Login-server is offline. Impossible to block the the player '%s'."_fmt, player_name); break; } break; case 2: // ban - switch (RFIFOW(s, 32)) + switch (fixed.error) { case 0: // login-server resquest done output = STRPRINTF( - "Login-server has been asked to ban the player '%s'.", + "Login-server has been asked to ban the player '%s'."_fmt, player_name); break; //case 1: // player not found case 2: // gm level too low output = STRPRINTF( - "Your GM level don't authorise you to ban the player '%s'.", + "Your GM level don't authorise you to ban the player '%s'."_fmt, player_name); break; case 3: // login-server offline output = STRPRINTF( - "Login-server is offline. Impossible to ban the the player '%s'.", + "Login-server is offline. Impossible to ban the the player '%s'."_fmt, player_name); break; } break; case 3: // unblock - switch (RFIFOW(s, 32)) + switch (fixed.error) { case 0: // login-server resquest done output = STRPRINTF( - "Login-server has been asked to unblock the player '%s'.", + "Login-server has been asked to unblock the player '%s'."_fmt, player_name); break; //case 1: // player not found case 2: // gm level too low output = STRPRINTF( - "Your GM level don't authorise you to unblock the player '%s'.", + "Your GM level don't authorise you to unblock the player '%s'."_fmt, player_name); break; case 3: // login-server offline output = STRPRINTF( - "Login-server is offline. Impossible to unblock the the player '%s'.", + "Login-server is offline. Impossible to unblock the the player '%s'."_fmt, player_name); break; } break; case 4: // unban - switch (RFIFOW(s, 32)) + switch (fixed.error) { case 0: // login-server resquest done output = STRPRINTF( - "Login-server has been asked to unban the player '%s'.", + "Login-server has been asked to unban the player '%s'."_fmt, player_name); break; //case 1: // player not found case 2: // gm level too low output = STRPRINTF( - "Your GM level don't authorise you to unban the player '%s'.", + "Your GM level don't authorise you to unban the player '%s'."_fmt, player_name); break; case 3: // login-server offline output = STRPRINTF( - "Login-server is offline. Impossible to unban the the player '%s'.", + "Login-server is offline. Impossible to unban the the player '%s'."_fmt, player_name); break; } break; case 5: // changesex - switch (RFIFOW(s, 32)) + switch (fixed.error) { case 0: // login-server resquest done output = STRPRINTF( - "Login-server has been asked to change the sex of the player '%s'.", + "Login-server has been asked to change the sex of the player '%s'."_fmt, player_name); break; //case 1: // player not found case 2: // gm level too low output = STRPRINTF( - "Your GM level don't authorise you to change the sex of the player '%s'.", + "Your GM level don't authorise you to change the sex of the player '%s'."_fmt, player_name); break; case 3: // login-server offline output = STRPRINTF( - "Login-server is offline. Impossible to change the sex of the the player '%s'.", + "Login-server is offline. Impossible to change the sex of the the player '%s'."_fmt, player_name); break; } @@ -604,7 +603,7 @@ int chrif_char_ask_name_answer(Session *s) clif_displaymessage(sd->sess, output); } else - PRINTF("chrif_char_ask_name_answer failed - player not online.\n"); + PRINTF("chrif_char_ask_name_answer failed - player not online.\n"_fmt); return 0; } @@ -614,25 +613,22 @@ int chrif_char_ask_name_answer(Session *s) *------------------------------------------ */ static -void chrif_changedgm(Session *s) +void chrif_changedgm(Session *, const Packet_Fixed<0x2b0b>& fixed) { - int acc, level; - dumb_ptr<map_session_data> sd = NULL; - - acc = RFIFOL(s, 2); - level = RFIFOL(s, 6); + AccountId acc = fixed.account_id; + GmLevel level = fixed.gm_level; - sd = map_id2sd(acc); + dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(acc)); if (battle_config.etc_log) - PRINTF("chrif_changedgm: account: %d, GM level 0 -> %d.\n", acc, + PRINTF("chrif_changedgm: account: %d, GM level 0 -> %d.\n"_fmt, acc, level); - if (sd != NULL) + if (sd != nullptr) { - if (level > 0) - clif_displaymessage(sd->sess, "GM modification success."); + if (level) + clif_displaymessage(sd->sess, "GM modification success."_s); else - clif_displaymessage(sd->sess, "Failure of GM modification."); + clif_displaymessage(sd->sess, "Failure of GM modification."_s); } } @@ -641,26 +637,25 @@ void chrif_changedgm(Session *s) *------------------------------------------ */ static -void chrif_changedsex(Session *s) +void chrif_changedsex(Session *, const Packet_Fixed<0x2b0d>& fixed) { - int acc, i; dumb_ptr<map_session_data> sd; - acc = RFIFOL(s, 2); - SEX sex = static_cast<SEX>(RFIFOB(s, 6)); + AccountId acc = fixed.account_id; + SEX sex = fixed.sex; if (battle_config.etc_log) - PRINTF("chrif_changedsex %d.\n", acc); - sd = map_id2sd(acc); - if (acc > 0) + PRINTF("chrif_changedsex %d.\n"_fmt, acc); + sd = map_id2sd(account_to_block(acc)); + if (acc) { - if (sd != NULL && sd->status.sex != sex) + if (sd != nullptr && sd->status.sex != sex) { if (sd->status.sex == SEX::MALE) sd->sex = sd->status.sex = SEX::FEMALE; else if (sd->status.sex == SEX::FEMALE) sd->sex = sd->status.sex = SEX::MALE; // to avoid any problem with equipment and invalid sex, equipment is unequiped. - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (sd->status.inventory[i].nameid && bool(sd->status.inventory[i].equip)) @@ -671,15 +666,15 @@ void chrif_changedsex(Session *s) sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters // do same modify in login-server for the account, but no in char-server (it ask again login_id1 to login, and don't remember it) clif_displaymessage(sd->sess, - "Your sex has been changed (need disconexion by the server)..."); + "Your sex has been changed (need disconexion by the server)..."_s); clif_setwaitclose(sd->sess); // forced to disconnect for the change } } else { - if (sd != NULL) + if (sd != nullptr) { - PRINTF("chrif_changedsex failed.\n"); + PRINTF("chrif_changedsex failed.\n"_fmt); } } } @@ -690,24 +685,27 @@ void chrif_changedsex(Session *s) */ int chrif_saveaccountreg2(dumb_ptr<map_session_data> sd) { - int p, j; nullpo_retr(-1, sd); - p = 8; - for (j = 0; j < sd->status.account_reg2_num; j++) + if (!char_session) + return -1; + + std::vector<Packet_Repeat<0x2b10>> repeat_10; + for (size_t j = 0; j < sd->status.account_reg2_num; j++) { - struct global_reg *reg = &sd->status.account_reg2[j]; + GlobalReg *reg = &sd->status.account_reg2[j]; if (reg->str && reg->value != 0) { - WFIFO_STRING(char_session, p, reg->str, 32); - WFIFOL(char_session, p + 32) = reg->value; - p += 36; + Packet_Repeat<0x2b10> info; + info.name = reg->str; + info.value = reg->value; + repeat_10.push_back(info); } } - WFIFOW(char_session, 0) = 0x2b10; - WFIFOW(char_session, 2) = p; - WFIFOL(char_session, 4) = sd->bl_id; - WFIFOSET(char_session, p); + + Packet_Head<0x2b10> head_10; + head_10.account_id = block_to_account(sd->bl_id); + send_vpacket<0x2b10, 8, 36>(char_session, head_10, repeat_10); return 0; } @@ -717,20 +715,19 @@ int chrif_saveaccountreg2(dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -int chrif_accountreg2(Session *s) +int chrif_accountreg2(Session *, const Packet_Head<0x2b11>& head, const std::vector<Packet_Repeat<0x2b11>>& repeat) { - int j, p; - dumb_ptr<map_session_data> sd = map_id2sd(RFIFOL(s, 4)); - if (sd == NULL) + dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(head.account_id)); + if (sd == nullptr) return 1; - for (p = 8, j = 0; p < RFIFOW(s, 2) && j < ACCOUNT_REG2_NUM; - p += 36, j++) + size_t jlim = std::min(ACCOUNT_REG2_NUM, repeat.size()); + for (size_t j = 0; j < jlim; j++) { - sd->status.account_reg2[j].str = stringish<VarName>(RFIFO_STRING<32>(s, p)); - sd->status.account_reg2[j].value = RFIFOL(s, p + 32); + sd->status.account_reg2[j].str = repeat[j].name; + sd->status.account_reg2[j].value = repeat[j].value; } - sd->status.account_reg2_num = j; + sd->status.account_reg2_num = jlim; return 0; } @@ -742,9 +739,9 @@ int chrif_accountreg2(Session *s) *------------------------------------------ */ static -int chrif_divorce(int char_id, int partner_id) +int chrif_divorce(CharId char_id, CharId partner_id) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; if (!char_id || !partner_id) return 0; @@ -752,7 +749,7 @@ int chrif_divorce(int char_id, int partner_id) sd = map_nick2sd(map_charid2nick(char_id)); if (sd && sd->status.partner_id == partner_id) { - sd->status.partner_id = 0; + sd->status.partner_id = CharId(); if (sd->npc_flags.divorce) { @@ -762,9 +759,9 @@ int chrif_divorce(int char_id, int partner_id) } sd = map_nick2sd(map_charid2nick(partner_id)); - nullpo_ret(sd); + nullpo_retz(sd); if (sd->status.partner_id == char_id) - sd->status.partner_id = 0; + sd->status.partner_id = CharId(); return 0; } @@ -774,14 +771,14 @@ int chrif_divorce(int char_id, int partner_id) * Needed to divorce when partner is not connected to map server *------------------------------------- */ -int chrif_send_divorce(int char_id) +int chrif_send_divorce(CharId char_id) { if (!char_session) return -1; - WFIFOW(char_session, 0) = 0x2b16; - WFIFOL(char_session, 2) = char_id; - WFIFOSET(char_session, 6); + Packet_Fixed<0x2b16> fixed_16; + fixed_16.char_id = char_id; + send_fpacket<0x2b16, 6>(char_session, fixed_16); return 0; } @@ -790,29 +787,28 @@ int chrif_send_divorce(int char_id) *------------------------------------------ */ static -int chrif_accountdeletion(Session *s) +int chrif_accountdeletion(Session *, const Packet_Fixed<0x2b13>& fixed) { - int acc; dumb_ptr<map_session_data> sd; - acc = RFIFOL(s, 2); + AccountId acc = fixed.account_id; if (battle_config.etc_log) - PRINTF("chrif_accountdeletion %d.\n", acc); - sd = map_id2sd(acc); - if (acc > 0) + PRINTF("chrif_accountdeletion %d.\n"_fmt, acc); + sd = map_id2sd(account_to_block(acc)); + if (acc) { - if (sd != NULL) + if (sd != nullptr) { sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters clif_displaymessage(sd->sess, - "Your account has been deleted (disconnection)..."); + "Your account has been deleted (disconnection)..."_s); clif_setwaitclose(sd->sess); // forced to disconnect for the change } } else { - if (sd != NULL) - PRINTF("chrif_accountdeletion failed - player not online.\n"); + if (sd != nullptr) + PRINTF("chrif_accountdeletion failed - player not online.\n"_fmt); } return 0; @@ -823,85 +819,85 @@ int chrif_accountdeletion(Session *s) *------------------------------------------ */ static -int chrif_accountban(Session *s) +int chrif_accountban(Session *, const Packet_Fixed<0x2b14>& fixed) { - int acc; dumb_ptr<map_session_data> sd; - acc = RFIFOL(s, 2); + AccountId acc = fixed.account_id; if (battle_config.etc_log) - PRINTF("chrif_accountban %d.\n", acc); - sd = map_id2sd(acc); - if (acc > 0) + PRINTF("chrif_accountban %d.\n"_fmt, acc); + sd = map_id2sd(account_to_block(acc)); + if (acc) { - if (sd != NULL) + if (sd != nullptr) { sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters - if (RFIFOB(s, 6) == 0) + if (fixed.ban_not_status == 0) { // 0: change of statut, 1: ban - switch (RFIFOL(s, 7)) + switch (static_cast<time_t>(fixed.status_or_ban_until)) { // status or final date of a banishment case 1: // 0 = Unregistered ID clif_displaymessage(sd->sess, - "Your account has 'Unregistered'."); + "Your account has 'Unregistered'."_s); break; case 2: // 1 = Incorrect Password clif_displaymessage(sd->sess, - "Your account has an 'Incorrect Password'..."); + "Your account has an 'Incorrect Password'..."_s); break; case 3: // 2 = This ID is expired clif_displaymessage(sd->sess, - "Your account has expired."); + "Your account has expired."_s); break; case 4: // 3 = Rejected from Server clif_displaymessage(sd->sess, - "Your account has been rejected from server."); + "Your account has been rejected from server."_s); break; case 5: // 4 = You have been blocked by the GM Team clif_displaymessage(sd->sess, - "Your account has been blocked by the GM Team."); + "Your account has been blocked by the GM Team."_s); break; case 6: // 5 = Your Game's EXE file is not the latest version clif_displaymessage(sd->sess, - "Your Game's EXE file is not the latest version."); + "Your Game's EXE file is not the latest version."_s); break; case 7: // 6 = Your are Prohibited to log in until %s clif_displaymessage(sd->sess, - "Your account has been prohibited to log in."); + "Your account has been prohibited to log in."_s); break; case 8: // 7 = Server is jammed due to over populated clif_displaymessage(sd->sess, - "Server is jammed due to over populated."); + "Server is jammed due to over populated."_s); break; case 9: // 8 = No MSG (actually, all states after 9 except 99 are No MSG, use only this) clif_displaymessage(sd->sess, - "Your account has not more authorised."); + "Your account has not more authorised."_s); break; case 100: // 99 = This ID has been totally erased clif_displaymessage(sd->sess, - "Your account has been totally erased."); + "Your account has been totally erased."_s); break; default: clif_displaymessage(sd->sess, - "Your account has not more authorised."); + "Your account has not more authorised."_s); break; } } - else if (RFIFOB(s, 6) == 1) + else if (fixed.ban_not_status == 1) { // 0: change of statut, 1: ban - TimeT timestamp = static_cast<time_t>(RFIFOL(s, 7)); // status or final date of a banishment - char tmpstr[] = WITH_TIMESTAMP("Your account has been banished until "); - REPLACE_TIMESTAMP(tmpstr, timestamp); - clif_displaymessage(sd->sess, const_(tmpstr)); + const TimeT timestamp = fixed.status_or_ban_until; // status or final date of a banishment + timestamp_seconds_buffer buffer; + stamp_time(buffer, ×tamp); + AString tmpstr = STRPRINTF("Your account has been banished until %s"_fmt, buffer); + clif_displaymessage(sd->sess, tmpstr); } clif_setwaitclose(sd->sess); // forced to disconnect for the change } } else { - if (sd != NULL) - PRINTF("chrif_accountban failed - player not online.\n"); + if (sd != nullptr) + PRINTF("chrif_accountban failed - player not online.\n"_fmt); } return 0; @@ -912,10 +908,10 @@ int chrif_accountban(Session *s) *------------------------------------------ */ static -int chrif_recvgmaccounts(Session *s) +int chrif_recvgmaccounts(Session *s, const std::vector<Packet_Repeat<0x2b15>>& repeat) { - PRINTF("From login-server: receiving of %d GM accounts information.\n", - pc_read_gm_account(s)); + PRINTF("From login-server: receiving of %d GM accounts information.\n"_fmt, + pc_read_gm_account(s, repeat)); return 0; } @@ -926,9 +922,11 @@ int chrif_recvgmaccounts(Session *s) */ int chrif_reloadGMdb(void) { + if (!char_session) + return -1; - WFIFOW(char_session, 0) = 0x2af7; - WFIFOSET(char_session, 2); + Packet_Fixed<0x2af7> fixed_f7; + send_fpacket<0x2af7, 2>(char_session, fixed_f7); return 0; } @@ -939,7 +937,7 @@ int chrif_reloadGMdb(void) */ static -void ladmin_itemfrob_fix_item(int source, int dest, struct item *item) +void ladmin_itemfrob_fix_item(ItemNameId source, ItemNameId dest, Item *item) { if (item && item->nameid == source) { @@ -949,7 +947,7 @@ void ladmin_itemfrob_fix_item(int source, int dest, struct item *item) } static -void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, int source_id, int dest_id) +void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, ItemNameId source_id, ItemNameId dest_id) { #define IFIX(v) if (v == source_id) {v = dest_id; } #define FIX(item) ladmin_itemfrob_fix_item(source_id, dest_id, &item) @@ -962,10 +960,9 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, int source_id, int dest_id) case BL::PC: { dumb_ptr<map_session_data> pc = bl->is_player(); - struct storage *stor = account2storage2(pc->status_key.account_id); - int j; + Storage *stor = account2storage2(pc->status_key.account_id); - for (j = 0; j < MAX_INVENTORY; j++) + for (IOff0 j : IOff0::iter()) IFIX(pc->status.inventory[j].nameid); // cart is no longer supported // IFIX(pc->status.weapon); @@ -975,10 +972,12 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, int source_id, int dest_id) IFIX(pc->status.head_bottom); if (stor) - for (j = 0; j < stor->storage_amount; j++) + { + for (SOff0 j : SOff0::iter()) FIX(stor->storage_[j]); + } - for (j = 0; j < MAX_INVENTORY; j++) + for (IOff0 j : IOff0::iter()) { struct item_data *item = pc->inventory_data[j]; if (item && item->nameid == source_id) @@ -996,7 +995,7 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, int source_id, int dest_id) case BL::MOB: { dumb_ptr<mob_data> mob = bl->is_mob(); - for (struct item& itm : mob->lootitemv) + for (Item& itm : mob->lootitemv) FIX(itm); break; } @@ -1013,16 +1012,16 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, int source_id, int dest_id) } static -void ladmin_itemfrob_c(dumb_ptr<block_list> bl, int source_id, int dest_id) +void ladmin_itemfrob_c(dumb_ptr<block_list> bl, ItemNameId source_id, ItemNameId dest_id) { ladmin_itemfrob_c2(bl, source_id, dest_id); } static -void ladmin_itemfrob(Session *s) +void ladmin_itemfrob(Session *, const Packet_Fixed<0x2afa>& fixed) { - int source_id = RFIFOL(s, 2); - int dest_id = RFIFOL(s, 6); + ItemNameId source_id = fixed.source_item_id; + ItemNameId dest_id = fixed.dest_item_id; dumb_ptr<block_list> bl = map_get_first_session(); // flooritems @@ -1041,7 +1040,7 @@ static void chrif_delete(Session *s) { assert (s == char_session); - PRINTF("Map-server can't connect to char-server (connection #%d).\n", + PRINTF("Map-server can't connect to char-server (connection #%d).\n"_fmt, s); char_session = nullptr; } @@ -1053,121 +1052,213 @@ void chrif_delete(Session *s) static void chrif_parse(Session *s) { - int packet_len, cmd; - - // only char-server can have an access to here. - // so, if it isn't the char-server, we disconnect the session (fd != char_fd). - if (s != char_session) - { - s->set_eof(); - return; - } + assert (s == char_session); - while (RFIFOREST(s) >= 2) + RecvResult rv = RecvResult::Complete; + uint16_t packet_id; + while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id)) { - cmd = RFIFOW(s, 0); - if (cmd < 0x2af8 - || cmd >= - 0x2af8 + - (sizeof(packet_len_table) / sizeof(packet_len_table[0])) - || packet_len_table[cmd - 0x2af8] == 0) - { - - int r = intif_parse(s); // intifに渡す - - if (r == 1) - continue; // intifで処理した - if (r == 2) - return; // intifで処理したが、データが足りない - - s->set_eof(); - return; - } - packet_len = packet_len_table[cmd - 0x2af8]; - if (packet_len == -1) - { - if (RFIFOREST(s) < 4) - return; - packet_len = RFIFOW(s, 2); - } - if (RFIFOREST(s) < packet_len) - return; - - switch (cmd) + switch (packet_id) { case 0x2af9: - chrif_connectack(s); + { + Packet_Fixed<0x2af9> fixed; + rv = recv_fpacket<0x2af9, 3>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_connectack(s, fixed); break; + } case 0x2afa: - ladmin_itemfrob(s); + { + Packet_Fixed<0x2afa> fixed; + rv = recv_fpacket<0x2afa, 10>(s, fixed); + if (rv != RecvResult::Complete) + break; + + ladmin_itemfrob(s, fixed); break; + } case 0x2afb: - chrif_sendmapack(s); + { + Packet_Fixed<0x2afb> fixed; + rv = recv_fpacket<0x2afb, 27>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_sendmapack(s, fixed); break; + } case 0x2afd: { - int id = RFIFOL(s, 4); - int login_id2 = RFIFOL(s, 8); - TimeT connect_until_time = static_cast<time_t>(RFIFOL(s, 12)); - short tmw_version = RFIFOW(s, 16); - CharKey st_key; - CharData st_data; - RFIFO_STRUCT(s, 18, st_key); - RFIFO_STRUCT(s, 18 + sizeof(st_key), st_data); + Packet_Payload<0x2afd> payload; + rv = recv_ppacket<0x2afd>(s, payload); + if (rv != RecvResult::Complete) + break; + + AccountId id = payload.account_id; + int login_id2 = payload.login_id2; + TimeT connect_until_time = payload.connect_until; + short tmw_version = payload.packet_tmw_version; + CharKey st_key = payload.char_key; + CharData st_data = payload.char_data; pc_authok(id, login_id2, connect_until_time, tmw_version, &st_key, &st_data); - } break; + } case 0x2afe: - pc_authfail(RFIFOL(s, 2)); + { + Packet_Fixed<0x2afe> fixed; + rv = recv_fpacket<0x2afe, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + + pc_authfail(fixed.account_id); break; + } case 0x2b00: - map_setusers(RFIFOL(s, 2)); + { + Packet_Fixed<0x2b00> fixed; + rv = recv_fpacket<0x2b00, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + + map_setusers(fixed.users); break; + } case 0x2b03: - clif_charselectok(RFIFOL(s, 2)); + { + Packet_Fixed<0x2b03> fixed; + rv = recv_fpacket<0x2b03, 7>(s, fixed); + if (rv != RecvResult::Complete) + break; + + clif_charselectok(account_to_block(fixed.account_id)); break; + } case 0x2b04: - chrif_recvmap(s); + { + Packet_Head<0x2b04> head; + std::vector<Packet_Repeat<0x2b04>> repeat; + rv = recv_vpacket<0x2b04, 10, 16>(s, head, repeat); + if (rv != RecvResult::Complete) + break; + + chrif_recvmap(s, head, repeat); break; + } case 0x2b06: - chrif_changemapserverack(s); + { + Packet_Fixed<0x2b06> fixed; + rv = recv_fpacket<0x2b06, 44>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_changemapserverack(s, fixed); break; + } case 0x2b0b: - chrif_changedgm(s); + { + Packet_Fixed<0x2b0b> fixed; + rv = recv_fpacket<0x2b0b, 10>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_changedgm(s, fixed); break; + } case 0x2b0d: - chrif_changedsex(s); + { + Packet_Fixed<0x2b0d> fixed; + rv = recv_fpacket<0x2b0d, 7>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_changedsex(s, fixed); break; + } case 0x2b0f: - chrif_char_ask_name_answer(s); + { + Packet_Fixed<0x2b0f> fixed; + rv = recv_fpacket<0x2b0f, 34>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_char_ask_name_answer(s, fixed); break; + } case 0x2b11: - chrif_accountreg2(s); + { + Packet_Head<0x2b11> head; + std::vector<Packet_Repeat<0x2b11>> repeat; + rv = recv_vpacket<0x2b11, 8, 36>(s, head, repeat); + if (rv != RecvResult::Complete) + break; + + chrif_accountreg2(s, head, repeat); break; + } case 0x2b12: - chrif_divorce(RFIFOL(s, 2), RFIFOL(s, 6)); + { + Packet_Fixed<0x2b12> fixed; + rv = recv_fpacket<0x2b12, 10>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_divorce(fixed.char_id, fixed.partner_id); break; + } case 0x2b13: - chrif_accountdeletion(s); + { + Packet_Fixed<0x2b13> fixed; + rv = recv_fpacket<0x2b13, 6>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_accountdeletion(s, fixed); break; + } case 0x2b14: - chrif_accountban(s); + { + Packet_Fixed<0x2b14> fixed; + rv = recv_fpacket<0x2b14, 11>(s, fixed); + if (rv != RecvResult::Complete) + break; + + chrif_accountban(s, fixed); break; + } case 0x2b15: - chrif_recvgmaccounts(s); - break; + { + std::vector<Packet_Repeat<0x2b15>> repeat; + rv = recv_packet_repeatonly<0x2b15, 4, 5>(s, repeat); + if (rv != RecvResult::Complete) + break; + chrif_recvgmaccounts(s, repeat); + break; + } default: + { + RecvResult r = intif_parse(s, packet_id); + + if (r == RecvResult::Complete) + break; + if (r == RecvResult::Incomplete) + return; + if (battle_config.error_log) - PRINTF("chrif_parse : unknown packet %d %d\n", s, - RFIFOW(s, 0)); + PRINTF("chrif_parse : unknown packet %d %d\n"_fmt, s, + packet_id); s->set_eof(); return; + } } - RFIFOSKIP(s, packet_len); } + if (rv == RecvResult::Error) + s->set_eof(); } /*========================================== @@ -1178,12 +1269,11 @@ void chrif_parse(Session *s) static void send_users_tochar(TimerData *, tick_t) { - int users = 0; - if (!char_session) return; - WFIFOW(char_session, 0) = 0x2aff; + Packet_Head<0x2aff> head_ff; + std::vector<Packet_Repeat<0x2aff>> repeat_ff; for (io::FD i : iter_fds()) { Session *s = get_session(i); @@ -1195,13 +1285,13 @@ void send_users_tochar(TimerData *, tick_t) || sd->state.shroud_active || bool(sd->status.option & Option::HIDE)) && pc_isGM(sd))) { - WFIFOL(char_session, 6 + 4 * users) = sd->status_key.char_id; - users++; + Packet_Repeat<0x2aff> info; + info.char_id = sd->status_key.char_id; + repeat_ff.push_back(info); } } - WFIFOW(char_session, 2) = 6 + 4 * users; - WFIFOW(char_session, 4) = users; - WFIFOSET(char_session, 6 + 4 * users); + head_ff.users = repeat_ff.size(); + send_vpacket<0x2aff, 6, 4>(char_session, head_ff, repeat_ff); } /*========================================== @@ -1214,10 +1304,10 @@ void check_connect_char_server(TimerData *, tick_t) { if (!char_session) { - PRINTF("Attempt to connect to char-server...\n"); + PRINTF("Attempt to connect to char-server...\n"_fmt); chrif_state = 0; char_session = make_connection(char_ip, char_port, - SessionParsers{func_parse: chrif_parse, func_delete: chrif_delete}); + SessionParsers{.func_parse= chrif_parse, .func_delete= chrif_delete}); if (!char_session) return; realloc_fifo(char_session, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); @@ -1232,12 +1322,13 @@ void check_connect_char_server(TimerData *, tick_t) */ void do_init_chrif(void) { - Timer(gettick() + std::chrono::seconds(1), + Timer(gettick() + 1_s, check_connect_char_server, - std::chrono::seconds(10) + 10_s ).detach(); - Timer(gettick() + std::chrono::seconds(1), + Timer(gettick() + 1_s, send_users_tochar, - std::chrono::seconds(5) + 5_s ).detach(); } +} // namespace tmwa diff --git a/src/map/chrif.hpp b/src/map/chrif.hpp index afeba75..4711bc5 100644 --- a/src/map/chrif.hpp +++ b/src/map/chrif.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_CHRIF_HPP -#define TMWA_MAP_CHRIF_HPP +#pragma once // chrif.hpp - Network interface to the character server. // // Copyright © ????-2004 Athena Dev Teams @@ -21,16 +20,19 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "../mmo/dumb_ptr.hpp" -# include "../mmo/human_time_diff.hpp" -# include "../mmo/ip.hpp" +#include "../generic/fwd.hpp" -# include "map.hpp" +#include "../net/fwd.hpp" +#include "../mmo/fwd.hpp" + + +namespace tmwa +{ void chrif_setuserid(AccountName); void chrif_setpasswd(AccountPass); AccountPass chrif_getpasswd(void); @@ -48,18 +50,17 @@ int chrif_changemapserver(dumb_ptr<map_session_data> sd, MapName name, int x, int y, IP4Address ip, short port); -void chrif_changegm(int id, ZString pass); -void chrif_changeemail(int id, AccountEmail actual_email, AccountEmail new_email); -void chrif_char_ask_name(int id, CharName character_name, short operation_type, +void chrif_changegm(AccountId id, ZString pass); +void chrif_changeemail(AccountId id, AccountEmail actual_email, AccountEmail new_email); +void chrif_char_ask_name(AccountId id, CharName character_name, short operation_type, HumanTimeDiff modif); int chrif_saveaccountreg2(dumb_ptr<map_session_data> sd); int chrif_reloadGMdb(void); -int chrif_send_divorce(int char_id); +int chrif_send_divorce(CharId char_id); void do_init_chrif(void); // only used by intif.cpp // and clif.cpp for the new on_delete stuff ... extern Session *char_session; - -#endif // TMWA_MAP_CHRIF_HPP +} // namespace tmwa diff --git a/src/map/clif.cpp b/src/map/clif.cpp index eb008e4..e7557c8 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -20,29 +20,35 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <arpa/inet.h> - -#include <cstdlib> -#include <cstring> +#include <cassert> #include <ctime> -#include "../compat/alg.hpp" +#include <algorithm> + #include "../compat/attr.hpp" #include "../compat/fun.hpp" #include "../compat/nullpo.hpp" +#include "../ints/cmp.hpp" + #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" -#include "../generic/random.hpp" - #include "../io/cxxstdio.hpp" #include "../io/write.hpp" +#include "../net/ip.hpp" +#include "../net/packets.hpp" +#include "../net/socket.hpp" +#include "../net/timer.hpp" + +#include "../proto2/any-user.hpp" +#include "../proto2/char-map.hpp" +#include "../proto2/map-user.hpp" + #include "../mmo/md5more.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" +#include "../mmo/utils.hpp" #include "../mmo/version.hpp" #include "atcommand.hpp" @@ -51,6 +57,7 @@ #include "intif.hpp" #include "itemdb.hpp" #include "magic.hpp" +#include "magic-stmt.hpp" #include "map.hpp" #include "npc.hpp" #include "party.hpp" @@ -62,8 +69,9 @@ #include "../poison.hpp" -#define DUMP_UNKNOWN_PACKET 1 +namespace tmwa +{ constexpr int EMOTE_IGNORED = 0x0e; // functions list. Rate is how many milliseconds are required between @@ -71,20 +79,20 @@ constexpr int EMOTE_IGNORED = 0x0e; // map.h must be the same length as this table. rate 0 is default // rate -1 is unlimited -typedef void (*clif_func)(Session *s, dumb_ptr<map_session_data> sd); +typedef RecvResult (*clif_func)(Session *s, dumb_ptr<map_session_data> sd); struct func_table { interval_t rate; - int len; + uint16_t len_unused; clif_func func; // ctor exists because interval_t must be explicit - func_table(int r, int l, clif_func f) - : rate(r), len(l), func(f) + func_table(int r, uint16_t l, clif_func f) + : rate(r), len_unused(l), func(f) {} }; -constexpr int VAR = -1; +constexpr uint16_t VAR = 1; extern // not really - defined below func_table clif_parse_func_table[0x0220]; @@ -107,36 +115,6 @@ enum class SendWho SELF, }; -inline -void WBUFPOS(uint8_t *p, size_t pos, uint16_t x, uint16_t y) -{ - p += pos; - p[0] = x >> 2; - p[1] = (x << 6) | ((y >> 4) & 0x3f); - p[2] = y << 4; -} -inline -void WBUFPOS2(uint8_t *p, size_t pos, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) -{ - p += pos; - p[0] = x0 >> 2; - p[1] = (x0 << 6) | ((y0 >> 4) & 0x3f); - p[2] = (y0 << 4) | ((x1 >> 6) & 0x0f); - p[3] = (x1 << 2) | ((y1 >> 8) & 0x03); - p[4] = y1; -} - -inline -void WFIFOPOS(Session *s, size_t pos, uint16_t x, uint16_t y) -{ - WBUFPOS(static_cast<uint8_t *>(WFIFOP(s, pos)), 0, x, y); -} -inline -void WFIFOPOS2(Session *s, size_t pos, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) -{ - WBUFPOS2(static_cast<uint8_t *>(WFIFOP(s, pos)), 0, x0, y0, x1, y1); -} - static IP4Address map_ip; static @@ -159,11 +137,11 @@ void clif_delete(Session *s) pc_logout(sd); clif_quitsave(s, sd); - PRINTF("Player [%s] has logged off your server.\n", sd->status_key.name); // Player logout display [Valaris] + PRINTF("Player [%s] has logged off your server.\n"_fmt, sd->status_key.name); // Player logout display [Valaris] } else if (sd) { // not authentified! (refused by char-server or disconnect before to be authentified) - PRINTF("Player with account [%d] has logged off your server (not auth account).\n", sd->bl_id); // Player logout display [Yor] + PRINTF("Player with account [%d] has logged off your server (not auth account).\n"_fmt, sd->bl_id); // Player logout display [Yor] map_deliddb(sd); // account_id has been included in the DB before auth answer } } @@ -265,14 +243,14 @@ enum class ChatType }; static -AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type); +AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type, XString buf); /*========================================== * clif_sendでSendWho::AREA*指定時用 *------------------------------------------ */ static -void clif_send_sub(dumb_ptr<block_list> bl, const unsigned char *buf, int len, +void clif_send_sub(dumb_ptr<block_list> bl, const Buffer& buf, dumb_ptr<block_list> src_bl, SendWho type) { nullpo_retv(bl); @@ -299,14 +277,11 @@ void clif_send_sub(dumb_ptr<block_list> bl, const unsigned char *buf, int len, break; } - if (sd->sess != NULL) + if (sd->sess != nullptr) { { - if (clif_parse_func_table[RBUFW(buf, 0)].len) { - // packet must exist - WFIFO_BUF_CLONE(sd->sess, buf, len); - WFIFOSET(sd->sess, len); + send_buffer(sd->sess, buf); } } } @@ -317,14 +292,14 @@ void clif_send_sub(dumb_ptr<block_list> bl, const unsigned char *buf, int len, *------------------------------------------ */ static -int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type) +int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type) { - struct party *p = NULL; + PartyPair p; int x0 = 0, x1 = 0, y0 = 0, y1 = 0; if (type != SendWho::ALL_CLIENT) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::PC) { @@ -360,11 +335,8 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get())); if (sd && sd->state.auth) { - if (clif_parse_func_table[RBUFW(buf, 0)].len) { - // packet must exist - WFIFO_BUF_CLONE(s, buf, len); - WFIFOSET(s, len); + send_buffer(s, buf); } } } @@ -378,25 +350,22 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get())); if (sd && sd->state.auth && sd->bl_m == bl->bl_m) { - if (clif_parse_func_table[RBUFW(buf, 0)].len) { - // packet must exist - WFIFO_BUF_CLONE(s, buf, len); - WFIFOSET(s, len); + send_buffer(s, buf); } } } break; case SendWho::AREA: case SendWho::AREA_WOS: - map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, len, bl, type), + map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, bl, type), bl->bl_m, bl->bl_x - AREA_SIZE, bl->bl_y - AREA_SIZE, bl->bl_x + AREA_SIZE, bl->bl_y + AREA_SIZE, BL::PC); break; case SendWho::AREA_CHAT_WOC: - map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, len, bl, SendWho::AREA_CHAT_WOC), + map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, bl, SendWho::AREA_CHAT_WOC), bl->bl_m, bl->bl_x - (AREA_SIZE), bl->bl_y - (AREA_SIZE), bl->bl_x + (AREA_SIZE), bl->bl_y + (AREA_SIZE), @@ -417,13 +386,13 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type if (bl->bl_type == BL::PC) { dumb_ptr<map_session_data> sd = bl->is_player(); - if (sd->partyspy > 0) + if (sd->partyspy) { p = party_search(sd->partyspy); } else { - if (sd->status.party_id > 0) + if (sd->status.party_id) p = party_search(sd->status.party_id); } } @@ -444,11 +413,8 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type (sd->bl_x < x0 || sd->bl_y < y0 || sd->bl_x > x1 || sd->bl_y > y1)) continue; - if (clif_parse_func_table[RBUFW(buf, 0)].len) { - // packet must exist - WFIFO_BUF_CLONE(sd->sess, buf, len); - WFIFOSET(sd->sess, len); + send_buffer(sd->sess, buf); } } } @@ -460,13 +426,10 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get())); if (sd && sd->state.auth) { - if (sd->partyspy == p->party_id) + if (sd->partyspy == p.party_id) { - if (clif_parse_func_table[RBUFW(buf, 0)].len) { - // packet must exist - WFIFO_BUF_CLONE(sd->sess, buf, len); - WFIFOSET(sd->sess, len); + send_buffer(sd->sess, buf); } } } @@ -476,18 +439,16 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type case SendWho::SELF: { dumb_ptr<map_session_data> sd = bl->is_player(); - if (clif_parse_func_table[RBUFW(buf, 0)].len) + { - // packet must exist - WFIFO_BUF_CLONE(sd->sess, buf, len); - WFIFOSET(sd->sess, len); + send_buffer(sd->sess, buf); } } break; default: if (battle_config.error_log) - PRINTF("clif_send まだ作ってないよー\n"); + PRINTF("clif_send まだ作ってないよー\n"_fmt); return -1; } @@ -503,7 +464,7 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type */ int clif_authok(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); if (!sd) return 0; @@ -513,12 +474,12 @@ int clif_authok(dumb_ptr<map_session_data> sd) Session *s = sd->sess; - WFIFOW(s, 0) = 0x73; - WFIFOL(s, 2) = gettick().time_since_epoch().count(); - WFIFOPOS(s, 6, sd->bl_x, sd->bl_y); - WFIFOB(s, 9) = 5; - WFIFOB(s, 10) = 5; - WFIFOSET(s, clif_parse_func_table[0x73].len); + Packet_Fixed<0x0073> fixed_73; + fixed_73.tick = gettick(); + fixed_73.pos = Position1{static_cast<uint16_t>(sd->bl_x), static_cast<uint16_t>(sd->bl_y), DIR::S}; + fixed_73.five1 = 5; + fixed_73.five2 = 5; + send_fpacket<0x0073, 11>(s, fixed_73); return 0; } @@ -532,9 +493,9 @@ int clif_authfail_fd(Session *s, int type) if (!s) return 0; - WFIFOW(s, 0) = 0x81; - WFIFOL(s, 2) = type; - WFIFOSET(s, clif_parse_func_table[0x81].len); + Packet_Fixed<0x0081> fixed_81; + fixed_81.error_code = type; + send_fpacket<0x0081, 3>(s, fixed_81); clif_setwaitclose(s); @@ -545,20 +506,20 @@ int clif_authfail_fd(Session *s, int type) * *------------------------------------------ */ -int clif_charselectok(int id) +int clif_charselectok(BlockId id) { dumb_ptr<map_session_data> sd; - if ((sd = map_id2sd(id)) == NULL) + if ((sd = map_id2sd(id)) == nullptr) return 1; if (!sd->sess) return 1; Session *s = sd->sess; - WFIFOW(s, 0) = 0xb3; - WFIFOB(s, 2) = 1; - WFIFOSET(s, clif_parse_func_table[0xb3].len); + Packet_Fixed<0x00b3> fixed_b3; + fixed_b3.one = 1; + send_fpacket<0x00b3, 3>(s, fixed_b3); return 0; } @@ -568,22 +529,21 @@ int clif_charselectok(int id) *------------------------------------------ */ static -int clif_set009e(dumb_ptr<flooritem_data> fitem, uint8_t *buf) +void clif_set009e(dumb_ptr<flooritem_data> fitem, Buffer& buf) { - nullpo_ret(fitem); + nullpo_retv(fitem); - //009e <ID>.l <name ID>.w <identify flag>.B <X>.w <Y>.w <subX>.B <subY>.B <amount>.w - WBUFW(buf, 0) = 0x9e; - WBUFL(buf, 2) = fitem->bl_id; - WBUFW(buf, 6) = fitem->item_data.nameid; - WBUFB(buf, 8) = 1; //identify; - WBUFW(buf, 9) = fitem->bl_x; - WBUFW(buf, 11) = fitem->bl_y; - WBUFB(buf, 13) = fitem->subx; - WBUFB(buf, 14) = fitem->suby; - WBUFW(buf, 15) = fitem->item_data.amount; + Packet_Fixed<0x009e> fixed_9e; + fixed_9e.block_id = fitem->bl_id; + fixed_9e.name_id = fitem->item_data.nameid; + fixed_9e.identify = 1; + fixed_9e.x = fitem->bl_x; + fixed_9e.y = fitem->bl_y; + fixed_9e.subx = fitem->subx; + fixed_9e.suby = fitem->suby; + fixed_9e.amount = fitem->item_data.amount; - return clif_parse_func_table[0x9e].len; + buf = create_fpacket<0x009e, 17>(fixed_9e); } /*========================================== @@ -592,14 +552,14 @@ int clif_set009e(dumb_ptr<flooritem_data> fitem, uint8_t *buf) */ int clif_dropflooritem(dumb_ptr<flooritem_data> fitem) { - uint8_t buf[64]; + nullpo_retz(fitem); - nullpo_ret(fitem); - - if (fitem->item_data.nameid <= 0) + if (!fitem->item_data.nameid) return 0; + + Buffer buf; clif_set009e(fitem, buf); - clif_send(buf, clif_parse_func_table[0x9e].len, fitem, SendWho::AREA); + clif_send(buf, fitem, SendWho::AREA); return 0; } @@ -610,21 +570,19 @@ int clif_dropflooritem(dumb_ptr<flooritem_data> fitem) */ int clif_clearflooritem(dumb_ptr<flooritem_data> fitem, Session *s) { - unsigned char buf[16]; - - nullpo_ret(fitem); + nullpo_retz(fitem); - WBUFW(buf, 0) = 0xa1; - WBUFL(buf, 2) = fitem->bl_id; + Packet_Fixed<0x00a1> fixed_a1; + fixed_a1.block_id = fitem->bl_id; if (!s) { - clif_send(buf, clif_parse_func_table[0xa1].len, fitem, SendWho::AREA); + Buffer buf = create_fpacket<0x00a1, 6>(fixed_a1); + clif_send(buf, fitem, SendWho::AREA); } else { - WFIFO_BUF_CLONE(s, buf, 6); - WFIFOSET(s, clif_parse_func_table[0xa1].len); + send_fpacket<0x00a1, 6>(s, fixed_a1); } return 0; @@ -636,21 +594,22 @@ int clif_clearflooritem(dumb_ptr<flooritem_data> fitem, Session *s) */ int clif_clearchar(dumb_ptr<block_list> bl, BeingRemoveWhy type) { - unsigned char buf[16]; + nullpo_retz(bl); - nullpo_ret(bl); + Packet_Fixed<0x0080> fixed_80; + fixed_80.block_id = bl->bl_id; - WBUFW(buf, 0) = 0x80; - WBUFL(buf, 2) = bl->bl_id; if (type == BeingRemoveWhy::DISGUISE) { - WBUFB(buf, 6) = static_cast<uint8_t>(BeingRemoveWhy::GONE); - clif_send(buf, clif_parse_func_table[0x80].len, bl, SendWho::AREA); + fixed_80.type = BeingRemoveWhy::GONE; + Buffer buf = create_fpacket<0x0080, 7>(fixed_80); + clif_send(buf, bl, SendWho::AREA); } else { - WBUFB(buf, 6) = static_cast<uint8_t>(type); - clif_send(buf, clif_parse_func_table[0x80].len, bl, + fixed_80.type = type; + Buffer buf = create_fpacket<0x0080, 7>(fixed_80); + clif_send(buf, bl, type == BeingRemoveWhy::DEAD ? SendWho::AREA : SendWho::AREA_WOS); } @@ -692,12 +651,12 @@ int clif_clearchar_delay(tick_t tick, * *------------------------------------------ */ -void clif_clearchar_id(int id, BeingRemoveWhy type, Session *s) +void clif_clearchar_id(BlockId id, BeingRemoveWhy type, Session *s) { - WFIFOW(s, 0) = 0x80; - WFIFOL(s, 2) = id; - WFIFOB(s, 6) = static_cast<uint8_t>(type); - WFIFOSET(s, clif_parse_func_table[0x80].len); + Packet_Fixed<0x0080> fixed_80; + fixed_80.block_id = id; + fixed_80.type = type; + send_fpacket<0x0080, 7>(s, fixed_80); } /*========================================== @@ -705,59 +664,111 @@ void clif_clearchar_id(int id, BeingRemoveWhy type, Session *s) *------------------------------------------ */ static -int clif_set0078(dumb_ptr<map_session_data> sd, unsigned char *buf) +void clif_set0078_main_1d8(dumb_ptr<map_session_data> sd, Buffer& buf) { - nullpo_ret(sd); + nullpo_retv(sd); - WBUFW(buf, 0) = 0x1d8; - WBUFL(buf, 2) = sd->bl_id; - WBUFW(buf, 6) = static_cast<uint16_t>(sd->speed.count()); - WBUFW(buf, 8) = static_cast<uint16_t>(sd->opt1); - WBUFW(buf, 10) = static_cast<uint16_t>(sd->opt2); - WBUFW(buf, 12) = static_cast<uint16_t>(sd->status.option); - WBUFW(buf, 14) = sd->status.species; - WBUFW(buf, 16) = sd->status.hair; + Packet_Fixed<0x01d8> fixed_1d8; + fixed_1d8.block_id = sd->bl_id; + fixed_1d8.speed = sd->speed; + fixed_1d8.opt1 = sd->opt1; + fixed_1d8.opt2 = sd->opt2; + fixed_1d8.option = sd->status.option; + fixed_1d8.species = sd->status.species; + fixed_1d8.hair_style = sd->status.hair; + + IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON]; + IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD]; + if (sd->attack_spell_override) + fixed_1d8.weapon = sd->attack_spell_look_override; + else + { + if (widx.ok() && sd->inventory_data[widx]) + { + fixed_1d8.weapon = sd->status.inventory[widx].nameid; + } + else + fixed_1d8.weapon = ItemNameId(); + } + if (sidx.ok() && sidx != widx && sd->inventory_data[sidx]) + { + fixed_1d8.shield = sd->status.inventory[sidx].nameid; + } + else + fixed_1d8.shield = ItemNameId(); + fixed_1d8.head_bottom = sd->status.head_bottom; + fixed_1d8.head_top = sd->status.head_top; + fixed_1d8.head_mid = sd->status.head_mid; + fixed_1d8.hair_color = sd->status.hair_color; + fixed_1d8.clothes_color = sd->status.clothes_color; + fixed_1d8.head_dir = sd->head_dir; + fixed_1d8.guild_id = 0; + fixed_1d8.guild_emblem_id = 0; + fixed_1d8.manner = sd->status.manner; + fixed_1d8.opt3 = sd->opt3; + fixed_1d8.karma = sd->status.karma; + fixed_1d8.sex = sd->sex; + fixed_1d8.pos.x = sd->bl_x; + fixed_1d8.pos.y = sd->bl_y; + fixed_1d8.pos.dir = sd->dir; + fixed_1d8.gm_bits = pc_isGM(sd).get_public_word(); + fixed_1d8.dead_sit = sd->state.dead_sit; + fixed_1d8.unused = 0; + + buf = create_fpacket<0x01d8, 54>(fixed_1d8); +} +static +void clif_set0078_alt_1d9(dumb_ptr<map_session_data> sd, Buffer& buf) +{ + nullpo_retv(sd); - int widx = sd->equip_index_maybe[EQUIP::WEAPON]; - int sidx = sd->equip_index_maybe[EQUIP::SHIELD]; + Packet_Fixed<0x01d9> fixed_1d8; // LIES + fixed_1d8.block_id = sd->bl_id; + fixed_1d8.speed = sd->speed; + fixed_1d8.opt1 = sd->opt1; + fixed_1d8.opt2 = sd->opt2; + fixed_1d8.option = sd->status.option; + fixed_1d8.species = sd->status.species; + fixed_1d8.hair_style = sd->status.hair; + + IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON]; + IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD]; if (sd->attack_spell_override) - WBUFW(buf, 18) = sd->attack_spell_look_override; + fixed_1d8.weapon = sd->attack_spell_look_override; else { - if (widx >= 0 && sd->inventory_data[widx]) + if (widx.ok() && sd->inventory_data[widx]) { - WBUFW(buf, 18) = sd->status.inventory[widx].nameid; + fixed_1d8.weapon = sd->status.inventory[widx].nameid; } else - WBUFW(buf, 18) = 0; + fixed_1d8.weapon = ItemNameId(); } - if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx]) + if (sidx.ok() && sidx != widx && sd->inventory_data[sidx]) { - WBUFW(buf, 20) = sd->status.inventory[sidx].nameid; + fixed_1d8.shield = sd->status.inventory[sidx].nameid; } else - WBUFW(buf, 20) = 0; - WBUFW(buf, 22) = sd->status.head_bottom; - WBUFW(buf, 24) = sd->status.head_top; - WBUFW(buf, 26) = sd->status.head_mid; - WBUFW(buf, 28) = sd->status.hair_color; - WBUFW(buf, 30) = sd->status.clothes_color; - WBUFW(buf, 32) = static_cast<uint8_t>(sd->head_dir); - WBUFL(buf, 34) = 0 /*guild_id*/; - WBUFW(buf, 38) = 0 /*guild_emblem_id*/; - WBUFW(buf, 40) = sd->status.manner; - WBUFW(buf, 42) = static_cast<uint16_t>(sd->opt3); - WBUFB(buf, 44) = sd->status.karma; - WBUFB(buf, 45) = static_cast<uint8_t>(sd->sex); - WBUFPOS(buf, 46, sd->bl_x, sd->bl_y); - // work around ICE in gcc 4.6 - uint8_t dir = static_cast<uint8_t>(sd->dir); - WBUFB(buf, 48) |= dir; - WBUFW(buf, 49) = (pc_isGM(sd) == 60 || pc_isGM(sd) == 99) ? 0x80 : 0; - WBUFB(buf, 51) = sd->state.dead_sit; - WBUFW(buf, 52) = 0; - - return clif_parse_func_table[0x1d8].len; + fixed_1d8.shield = ItemNameId(); + fixed_1d8.head_bottom = sd->status.head_bottom; + fixed_1d8.head_top = sd->status.head_top; + fixed_1d8.head_mid = sd->status.head_mid; + fixed_1d8.hair_color = sd->status.hair_color; + fixed_1d8.clothes_color = sd->status.clothes_color; + fixed_1d8.head_dir = sd->head_dir; + fixed_1d8.guild_id = 0; + fixed_1d8.guild_emblem_id = 0; + fixed_1d8.manner = sd->status.manner; + fixed_1d8.opt3 = sd->opt3; + fixed_1d8.karma = sd->status.karma; + fixed_1d8.sex = sd->sex; + fixed_1d8.pos.x = sd->bl_x; + fixed_1d8.pos.y = sd->bl_y; + fixed_1d8.pos.dir = sd->dir; + fixed_1d8.gm_bits = pc_isGM(sd).get_public_word(); + fixed_1d8.unused = 0; + + buf = create_fpacket<0x01d9, 53>(fixed_1d8); } /*========================================== @@ -765,51 +776,54 @@ int clif_set0078(dumb_ptr<map_session_data> sd, unsigned char *buf) *------------------------------------------ */ static -int clif_set007b(dumb_ptr<map_session_data> sd, unsigned char *buf) -{ - nullpo_ret(sd); - - WBUFW(buf, 0) = 0x1da; - WBUFL(buf, 2) = sd->bl_id; - WBUFW(buf, 6) = static_cast<uint16_t>(sd->speed.count()); - WBUFW(buf, 8) = static_cast<uint16_t>(sd->opt1); - WBUFW(buf, 10) = static_cast<uint16_t>(sd->opt2); - WBUFW(buf, 12) = static_cast<uint16_t>(sd->status.option); - WBUFW(buf, 14) = sd->status.species; - WBUFW(buf, 16) = sd->status.hair; - int widx = sd->equip_index_maybe[EQUIP::WEAPON]; - int sidx = sd->equip_index_maybe[EQUIP::SHIELD]; - if (widx >= 0 && sd->inventory_data[widx]) +void clif_set007b(dumb_ptr<map_session_data> sd, Buffer& buf) +{ + nullpo_retv(sd); + + Packet_Fixed<0x01da> fixed_1da; + fixed_1da.block_id = sd->bl_id; + fixed_1da.speed = sd->speed; + fixed_1da.opt1 = sd->opt1; + fixed_1da.opt2 = sd->opt2; + fixed_1da.option = sd->status.option; + fixed_1da.species = sd->status.species; + fixed_1da.hair_style = sd->status.hair; + IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON]; + IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD]; + if (widx.ok() && sd->inventory_data[widx]) { - WBUFW(buf, 18) = sd->status.inventory[widx].nameid; + fixed_1da.weapon = sd->status.inventory[widx].nameid; } else - WBUFW(buf, 18) = 0; - if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx]) + fixed_1da.weapon = ItemNameId(); + if (sidx.ok() && sidx != widx && sd->inventory_data[sidx]) { - WBUFW(buf, 20) = sd->status.inventory[sidx].nameid; + fixed_1da.shield = sd->status.inventory[sidx].nameid; } else - WBUFW(buf, 20) = 0; - WBUFW(buf, 22) = sd->status.head_bottom; - WBUFL(buf, 24) = gettick().time_since_epoch().count(); - WBUFW(buf, 28) = sd->status.head_top; - WBUFW(buf, 30) = sd->status.head_mid; - WBUFW(buf, 32) = sd->status.hair_color; - WBUFW(buf, 34) = sd->status.clothes_color; - WBUFW(buf, 36) = static_cast<uint8_t>(sd->head_dir); - WBUFL(buf, 38) = 0/*guild_id*/; - WBUFW(buf, 42) = 0/*guild_emblem_id*/; - WBUFW(buf, 44) = sd->status.manner; - WBUFW(buf, 46) = static_cast<uint16_t>(sd->opt3); - WBUFB(buf, 48) = sd->status.karma; - WBUFB(buf, 49) = static_cast<uint8_t>(sd->sex); - WBUFPOS2(buf, 50, sd->bl_x, sd->bl_y, sd->to_x, sd->to_y); - WBUFW(buf, 55) = pc_isGM(sd) == 60 ? 0x80 : 0; - WBUFB(buf, 57) = 5; - WBUFW(buf, 58) = 0; - - return clif_parse_func_table[0x1da].len; + fixed_1da.shield = ItemNameId(); + fixed_1da.head_bottom = sd->status.head_bottom; + fixed_1da.tick = gettick(); + fixed_1da.head_top = sd->status.head_top; + fixed_1da.head_mid = sd->status.head_mid; + fixed_1da.hair_color = sd->status.hair_color; + fixed_1da.clothes_color = sd->status.clothes_color; + fixed_1da.head_dir = sd->head_dir; + fixed_1da.guild_id = 0; + fixed_1da.guild_emblem_id = 0; + fixed_1da.manner = sd->status.manner; + fixed_1da.opt3 = sd->opt3; + fixed_1da.karma = sd->status.karma; + fixed_1da.sex = sd->sex; + fixed_1da.pos2.x0 = sd->bl_x; + fixed_1da.pos2.y0 = sd->bl_y; + fixed_1da.pos2.x1 = sd->to_x; + fixed_1da.pos2.y1 = sd->to_y; + fixed_1da.gm_bits = pc_isGM(sd).get_public_word(); + fixed_1da.five = 5; + fixed_1da.unused = 0; + + buf = create_fpacket<0x01da, 60>(fixed_1da); } /*========================================== @@ -817,30 +831,27 @@ int clif_set007b(dumb_ptr<map_session_data> sd, unsigned char *buf) *------------------------------------------ */ static -int clif_mob0078(dumb_ptr<mob_data> md, unsigned char *buf) +void clif_mob0078(dumb_ptr<mob_data> md, Buffer& buf) { - really_memset0(buf, clif_parse_func_table[0x78].len); - - nullpo_ret(md); + nullpo_retv(md); - WBUFW(buf, 0) = 0x78; - WBUFL(buf, 2) = md->bl_id; - WBUFW(buf, 6) = static_cast<uint16_t>(battle_get_speed(md).count()); - WBUFW(buf, 8) = static_cast<uint16_t>(md->opt1); - WBUFW(buf, 10) = static_cast<uint16_t>(md->opt2); - WBUFW(buf, 12) = static_cast<uint16_t>(md->option); - WBUFW(buf, 14) = md->mob_class; + Packet_Fixed<0x0078> fixed_78; + fixed_78.block_id = md->bl_id; + fixed_78.speed = battle_get_speed(md); + fixed_78.opt1 = md->opt1; + fixed_78.opt2 = md->opt2; + fixed_78.option = md->option; + fixed_78.species = md->mob_class; // snip: stuff do do with disguise as a PC - WBUFPOS(buf, 46, md->bl_x, md->bl_y); - // work around ICE in gcc 4.6 - uint8_t dir = static_cast<uint8_t>(md->dir); - WBUFB(buf, 48) |= dir; - WBUFB(buf, 49) = 5; - WBUFB(buf, 50) = 5; + fixed_78.pos.x = md->bl_x; + fixed_78.pos.y = md->bl_y; + fixed_78.pos.dir = md->dir; + fixed_78.five1 = 5; + fixed_78.five2 = 5; int level = battle_get_lv(md); - WBUFW(buf, 52) = (level > battle_config.max_lv) ? battle_config.max_lv : level; + fixed_78.level = (level > battle_config.max_lv) ? battle_config.max_lv : level; - return clif_parse_func_table[0x78].len; + buf = create_fpacket<0x0078, 54>(fixed_78); } /*========================================== @@ -848,29 +859,30 @@ int clif_mob0078(dumb_ptr<mob_data> md, unsigned char *buf) *------------------------------------------ */ static -int clif_mob007b(dumb_ptr<mob_data> md, unsigned char *buf) +void clif_mob007b(dumb_ptr<mob_data> md, Buffer& buf) { - really_memset0(buf, clif_parse_func_table[0x7b].len); - - nullpo_ret(md); + nullpo_retv(md); - WBUFW(buf, 0) = 0x7b; - WBUFL(buf, 2) = md->bl_id; - WBUFW(buf, 6) = static_cast<uint16_t>(battle_get_speed(md).count()); - WBUFW(buf, 8) = static_cast<uint16_t>(md->opt1); - WBUFW(buf, 10) = static_cast<uint16_t>(md->opt2); - WBUFW(buf, 12) = static_cast<uint16_t>(md->option); - WBUFW(buf, 14) = md->mob_class; + Packet_Fixed<0x007b> fixed_7b; + fixed_7b.block_id = md->bl_id; + fixed_7b.speed = battle_get_speed(md); + fixed_7b.opt1 = md->opt1; + fixed_7b.opt2 = md->opt2; + fixed_7b.option = md->option; + fixed_7b.mob_class = md->mob_class; // snip: stuff for monsters disguised as PCs - WBUFL(buf, 22) = gettick().time_since_epoch().count(); - - WBUFPOS2(buf, 50, md->bl_x, md->bl_y, md->to_x, md->to_y); - WBUFB(buf, 56) = 5; - WBUFB(buf, 57) = 5; + fixed_7b.tick_and_maybe_part_of_guild_emblem = gettick(); + + fixed_7b.pos2.x0 = md->bl_x; + fixed_7b.pos2.y0 = md->bl_y; + fixed_7b.pos2.x1 = md->to_x; + fixed_7b.pos2.y1 = md->to_y; + fixed_7b.five1 = 5; + fixed_7b.five2 = 5; int level = battle_get_lv(md); - WBUFW(buf, 58) = (level > battle_config.max_lv) ? battle_config.max_lv : level; + fixed_7b.level = (level > battle_config.max_lv) ? battle_config.max_lv : level; - return clif_parse_func_table[0x7b].len; + buf = create_fpacket<0x007b, 60>(fixed_7b); } /*========================================== @@ -878,24 +890,23 @@ int clif_mob007b(dumb_ptr<mob_data> md, unsigned char *buf) *------------------------------------------ */ static -int clif_npc0078(dumb_ptr<npc_data> nd, unsigned char *buf) +void clif_npc0078(dumb_ptr<npc_data> nd, Buffer& buf) { - nullpo_ret(nd); - - really_memset0(buf, clif_parse_func_table[0x78].len); + nullpo_retv(nd); - WBUFW(buf, 0) = 0x78; - WBUFL(buf, 2) = nd->bl_id; - WBUFW(buf, 6) = static_cast<uint16_t>(nd->speed.count()); - WBUFW(buf, 14) = nd->npc_class; - WBUFPOS(buf, 46, nd->bl_x, nd->bl_y); - // work around ICE in gcc 4.6 - uint8_t dir = static_cast<uint8_t>(nd->dir); - WBUFB(buf, 48) |= dir; - WBUFB(buf, 49) = 5; - WBUFB(buf, 50) = 5; + Packet_Fixed<0x0078> fixed_78; + fixed_78.block_id = nd->bl_id; + fixed_78.speed = nd->speed; + fixed_78.species = nd->npc_class; + fixed_78.pos.x = nd->bl_x; + fixed_78.pos.y = nd->bl_y; + fixed_78.pos.dir = nd->dir; + fixed_78.five1 = 5; + fixed_78.five2 = 5; + fixed_78.zero = 0; + fixed_78.level = 0; - return clif_parse_func_table[0x78].len; + buf = create_fpacket<0x0078, 54>(fixed_78); } /* These indices are derived from equip_pos in pc.c and some guesswork */ @@ -924,15 +935,12 @@ earray<EQUIP, LOOK, LOOK::COUNT> equip_points //= */ int clif_spawnpc(dumb_ptr<map_session_data> sd) { - unsigned char buf[128]; + nullpo_retz(sd); - nullpo_ret(sd); + Buffer buf; + clif_set0078_alt_1d9(sd, buf); - clif_set0078(sd, buf); - - WBUFW(buf, 0) = 0x1d9; - WBUFW(buf, 51) = 0; - clif_send(buf, clif_parse_func_table[0x1d9].len, sd, SendWho::AREA_WOS); + clif_send(buf, sd, SendWho::AREA_WOS); if (sd->bl_m->flag.get(MapFlag::SNOW)) clif_specialeffect(sd, 162, 1); @@ -945,7 +953,7 @@ int clif_spawnpc(dumb_ptr<map_session_data> sd) if (sd->bl_m->flag.get(MapFlag::RAIN)) clif_specialeffect(sd, 161, 1); -// clif_changelook_accessories(sd, NULL); +// clif_changelook_accessories(sd, nullptr); return 0; } @@ -956,62 +964,64 @@ int clif_spawnpc(dumb_ptr<map_session_data> sd) */ int clif_spawnnpc(dumb_ptr<npc_data> nd) { - unsigned char buf[64]; - int len; - - nullpo_ret(nd); + nullpo_retz(nd); - if (nd->npc_class < 0 || nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS) + if (nd->npc_class == NEGATIVE_SPECIES || nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS) return 0; - really_memset0(buf, clif_parse_func_table[0x7c].len); + Packet_Fixed<0x007c> fixed_7c; + fixed_7c.block_id = nd->bl_id; + fixed_7c.speed = nd->speed; + fixed_7c.species = nd->npc_class; + fixed_7c.pos.x = nd->bl_x; + fixed_7c.pos.y = nd->bl_y; - WBUFW(buf, 0) = 0x7c; - WBUFL(buf, 2) = nd->bl_id; - WBUFW(buf, 6) = static_cast<uint16_t>(nd->speed.count()); - WBUFW(buf, 20) = nd->npc_class; - WBUFPOS(buf, 36, nd->bl_x, nd->bl_y); + Buffer buf = create_fpacket<0x007c, 41>(fixed_7c); + clif_send(buf, nd, SendWho::AREA); - clif_send(buf, clif_parse_func_table[0x7c].len, nd, SendWho::AREA); - - len = clif_npc0078(nd, buf); - clif_send(buf, len, nd, SendWho::AREA); + clif_npc0078(nd, buf); + clif_send(buf, nd, SendWho::AREA); return 0; } -int clif_spawn_fake_npc_for_player(dumb_ptr<map_session_data> sd, int fake_npc_id) +int clif_spawn_fake_npc_for_player(dumb_ptr<map_session_data> sd, BlockId fake_npc_id) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; if (!s) return 0; - WFIFOW(s, 0) = 0x7c; - WFIFOL(s, 2) = fake_npc_id; - WFIFOW(s, 6) = 0; - WFIFOW(s, 8) = 0; - WFIFOW(s, 10) = 0; - WFIFOW(s, 12) = 0; - WFIFOW(s, 20) = 127; - WFIFOPOS(s, 36, sd->bl_x, sd->bl_y); - WFIFOSET(s, clif_parse_func_table[0x7c].len); - - WFIFOW(s, 0) = 0x78; - WFIFOL(s, 2) = fake_npc_id; - WFIFOW(s, 6) = 0; - WFIFOW(s, 8) = 0; - WFIFOW(s, 10) = 0; - WFIFOW(s, 12) = 0; - WFIFOW(s, 14) = 127; // identifies as NPC - WFIFOW(s, 20) = 127; - WFIFOPOS(s, 46, sd->bl_x, sd->bl_y); - WFIFOPOS(s, 36, sd->bl_x, sd->bl_y); - WFIFOB(s, 49) = 5; - WFIFOB(s, 50) = 5; - WFIFOSET(s, clif_parse_func_table[0x78].len); + Packet_Fixed<0x007c> fixed_7c; + fixed_7c.block_id = fake_npc_id; + fixed_7c.speed = interval_t(); + fixed_7c.opt1 = Opt1::ZERO; + fixed_7c.opt2 = Opt2::ZERO; + fixed_7c.option = Option::ZERO; + fixed_7c.species = FAKE_NPC_CLASS; + fixed_7c.pos.x = sd->bl_x; + fixed_7c.pos.y = sd->bl_y; + send_fpacket<0x007c, 41>(s, fixed_7c); + + Packet_Fixed<0x0078> fixed_78; + fixed_78.block_id = fake_npc_id; + fixed_78.speed = interval_t(); + fixed_78.opt1 = Opt1::ZERO; + fixed_78.opt2 = Opt2::ZERO; + fixed_78.option = Option::ZERO; + fixed_78.species = FAKE_NPC_CLASS; + fixed_78.unused_head_bottom_or_species_again = unwrap<Species>(FAKE_NPC_CLASS); + fixed_78.pos.x = sd->bl_x; + fixed_78.pos.y = sd->bl_y; + fixed_78.unused_pos_again.x = sd->bl_x; + fixed_78.unused_pos_again.y = sd->bl_y; + fixed_78.five1 = 5; + fixed_78.five2 = 5; + fixed_78.zero = 0; + fixed_78.level = 0; + send_fpacket<0x0078, 54>(s, fixed_78); return 0; } @@ -1022,27 +1032,25 @@ int clif_spawn_fake_npc_for_player(dumb_ptr<map_session_data> sd, int fake_npc_i */ int clif_spawnmob(dumb_ptr<mob_data> md) { - unsigned char buf[64]; - int len; - - nullpo_ret(md); + nullpo_retz(md); { - really_memset0(buf, clif_parse_func_table[0x7c].len); - - WBUFW(buf, 0) = 0x7c; - WBUFL(buf, 2) = md->bl_id; - WBUFW(buf, 6) = md->stats[mob_stat::SPEED]; - WBUFW(buf, 8) = uint16_t(md->opt1); - WBUFW(buf, 10) = uint16_t(md->opt2); - WBUFW(buf, 12) = uint16_t(md->option); - WBUFW(buf, 20) = md->mob_class; - WBUFPOS(buf, 36, md->bl_x, md->bl_y); - clif_send(buf, clif_parse_func_table[0x7c].len, md, SendWho::AREA); + Packet_Fixed<0x007c> fixed_7c; + fixed_7c.block_id = md->bl_id; + fixed_7c.speed = interval_t(md->stats[mob_stat::SPEED]); + fixed_7c.opt1 = md->opt1; + fixed_7c.opt2 = md->opt2; + fixed_7c.option = md->option; + fixed_7c.species = md->mob_class; + fixed_7c.pos.x = md->bl_x; + fixed_7c.pos.y = md->bl_y; + Buffer buf = create_fpacket<0x007c, 41>(fixed_7c); + clif_send(buf, md, SendWho::AREA); } - len = clif_mob0078(md, buf); - clif_send(buf, len, md, SendWho::AREA); + Buffer buf; + clif_mob0078(md, buf); + clif_send(buf, md, SendWho::AREA); return 0; } @@ -1054,12 +1062,12 @@ int clif_spawnmob(dumb_ptr<mob_data> md) static int clif_servertick(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0x7f; - WFIFOL(s, 2) = sd->server_tick.time_since_epoch().count(); - WFIFOSET(s, clif_parse_func_table[0x7f].len); + Packet_Fixed<0x007f> fixed_7f; + fixed_7f.tick = gettick(); + send_fpacket<0x007f, 6>(s, fixed_7f); return 0; } @@ -1070,14 +1078,17 @@ int clif_servertick(dumb_ptr<map_session_data> sd) */ int clif_walkok(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0x87; - WFIFOL(s, 2) = gettick().time_since_epoch().count(); - WFIFOPOS2(s, 6, sd->bl_x, sd->bl_y, sd->to_x, sd->to_y); - WFIFOB(s, 11) = 0; - WFIFOSET(s, clif_parse_func_table[0x87].len); + Packet_Fixed<0x0087> fixed_87; + fixed_87.tick = gettick(); + fixed_87.pos2.x0 = sd->bl_x; + fixed_87.pos2.y0 = sd->bl_y; + fixed_87.pos2.x1 = sd->to_x; + fixed_87.pos2.y1 = sd->to_y; + fixed_87.zero = 0; + send_fpacket<0x0087, 12>(s, fixed_87); return 0; } @@ -1088,14 +1099,12 @@ int clif_walkok(dumb_ptr<map_session_data> sd) */ int clif_movechar(dumb_ptr<map_session_data> sd) { - int len; - unsigned char buf[256]; + nullpo_retz(sd); - nullpo_ret(sd); + Buffer buf; + clif_set007b(sd, buf); - len = clif_set007b(sd, buf); - - clif_send(buf, len, sd, SendWho::AREA_WOS); + clif_send(buf, sd, SendWho::AREA_WOS); if (battle_config.save_clothcolor == 1 && sd->status.clothes_color > 0) clif_changelook(sd, LOOK::CLOTHES_COLOR, @@ -1131,7 +1140,7 @@ void clif_waitclose(TimerData *, tick_t, Session *s) */ void clif_setwaitclose(Session *s) { - s->timed_close = Timer(gettick() + std::chrono::seconds(5), + s->timed_close = Timer(gettick() + 5_s, std::bind(clif_waitclose, ph::_1, ph::_2, s) ); @@ -1147,11 +1156,11 @@ void clif_changemap(dumb_ptr<map_session_data> sd, MapName mapname, int x, int y Session *s = sd->sess; - WFIFOW(s, 0) = 0x91; - WFIFO_STRING(s, 2, mapname, 16); - WFIFOW(s, 18) = x; - WFIFOW(s, 20) = y; - WFIFOSET(s, clif_parse_func_table[0x91].len); + Packet_Fixed<0x0091> fixed_91; + fixed_91.map_name = mapname; + fixed_91.x = x; + fixed_91.y = y; + send_fpacket<0x0091, 22>(s, fixed_91); } /*========================================== @@ -1164,13 +1173,13 @@ void clif_changemapserver(dumb_ptr<map_session_data> sd, nullpo_retv(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0x92; - WFIFO_STRING(s, 2, mapname, 16); - WFIFOW(s, 18) = x; - WFIFOW(s, 20) = y; - WFIFOIP(s, 22) = ip; - WFIFOW(s, 26) = port; - WFIFOSET(s, clif_parse_func_table[0x92].len); + Packet_Fixed<0x0092> fixed_92; + fixed_92.map_name = mapname; + fixed_92.x = x; + fixed_92.y = y; + fixed_92.ip = ip; + fixed_92.port = port; + send_fpacket<0x0092, 28>(s, fixed_92); } /*========================================== @@ -1179,30 +1188,29 @@ void clif_changemapserver(dumb_ptr<map_session_data> sd, */ void clif_fixpos(dumb_ptr<block_list> bl) { - uint8_t buf[16]; - nullpo_retv(bl); - WBUFW(buf, 0) = 0x88; - WBUFL(buf, 2) = bl->bl_id; - WBUFW(buf, 6) = bl->bl_x; - WBUFW(buf, 8) = bl->bl_y; + Packet_Fixed<0x0088> fixed_88; + fixed_88.block_id = bl->bl_id; + fixed_88.x = bl->bl_x; + fixed_88.y = bl->bl_y; - clif_send(buf, clif_parse_func_table[0x88].len, bl, SendWho::AREA); + Buffer buf = create_fpacket<0x0088, 10>(fixed_88); + clif_send(buf, bl, SendWho::AREA); } /*========================================== * *------------------------------------------ */ -int clif_npcbuysell(dumb_ptr<map_session_data> sd, int id) +int clif_npcbuysell(dumb_ptr<map_session_data> sd, BlockId id) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xc4; - WFIFOL(s, 2) = id; - WFIFOSET(s, clif_parse_func_table[0xc4].len); + Packet_Fixed<0x00c4> fixed_c4; + fixed_c4.block_id = id; + send_fpacket<0x00c4, 6>(s, fixed_c4); return 0; } @@ -1216,22 +1224,21 @@ int clif_buylist(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data_shop> nd) struct item_data *id; int i, val; - nullpo_ret(sd); - nullpo_ret(nd); + nullpo_retz(sd); + nullpo_retz(nd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xc6; + std::vector<Packet_Repeat<0x00c6>> repeat_c6(nd->shop_items.size()); for (i = 0; i < nd->shop_items.size(); i++) { id = itemdb_search(nd->shop_items[i].nameid); val = nd->shop_items[i].value; - WFIFOL(s, 4 + i * 11) = val; // base price - WFIFOL(s, 8 + i * 11) = val; // actual price - WFIFOB(s, 12 + i * 11) = uint8_t(id->type); - WFIFOW(s, 13 + i * 11) = nd->shop_items[i].nameid; + repeat_c6[i].base_price = val; // base price + repeat_c6[i].actual_price = val; // actual price + repeat_c6[i].type = id->type; + repeat_c6[i].name_id = nd->shop_items[i].nameid; } - WFIFOW(s, 2) = i * 11 + 4; - WFIFOSET(s, WFIFOW(s, 2)); + send_packet_repeatonly<0x00c6, 4, 11>(s, repeat_c6); return 0; } @@ -1242,27 +1249,25 @@ int clif_buylist(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data_shop> nd) */ int clif_selllist(dumb_ptr<map_session_data> sd) { - int i, c = 0, val; - - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xc7; - for (i = 0; i < MAX_INVENTORY; i++) + std::vector<Packet_Repeat<0x00c7>> repeat_c7; + for (IOff0 i : IOff0::iter()) { - if (sd->status.inventory[i].nameid > 0 && sd->inventory_data[i]) + if (sd->status.inventory[i].nameid && sd->inventory_data[i]) { - val = sd->inventory_data[i]->value_sell; + int val = sd->inventory_data[i]->value_sell; if (val < 0) continue; - WFIFOW(s, 4 + c * 10) = i + 2; - WFIFOL(s, 6 + c * 10) = val; // base price - WFIFOL(s, 10 + c * 10) = val; // actual price - c++; + Packet_Repeat<0x00c7> info; + info.ioff2 = i.shift(); + info.base_price = val; + info.actual_price = val; + repeat_c7.push_back(info); } } - WFIFOW(s, 2) = c * 10 + 4; - WFIFOSET(s, WFIFOW(s, 2)); + send_packet_repeatonly<0x00c7, 4, 10>(s, repeat_c7); return 0; } @@ -1271,166 +1276,130 @@ int clif_selllist(dumb_ptr<map_session_data> sd) * *------------------------------------------ */ -void clif_scriptmes(dumb_ptr<map_session_data> sd, int npcid, XString mes) +void clif_scriptmes(dumb_ptr<map_session_data> sd, BlockId npcid, XString mes) { nullpo_retv(sd); Session *s = sd->sess; - size_t len = mes.size() + 1; - WFIFOW(s, 0) = 0xb4; - WFIFOW(s, 2) = len + 8; - WFIFOL(s, 4) = npcid; - WFIFO_STRING(s, 8, mes, len); - WFIFOSET(s, WFIFOW(s, 2)); + Packet_Head<0x00b4> head_b4; + head_b4.block_id = npcid; + send_vpacket<0x00b4, 8, 1>(s, head_b4, mes); } /*========================================== * *------------------------------------------ */ -void clif_scriptnext(dumb_ptr<map_session_data> sd, int npcid) +void clif_scriptnext(dumb_ptr<map_session_data> sd, BlockId npcid) { nullpo_retv(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xb5; - WFIFOL(s, 2) = npcid; - WFIFOSET(s, clif_parse_func_table[0xb5].len); + Packet_Fixed<0x00b5> fixed_b5; + fixed_b5.block_id = npcid; + send_fpacket<0x00b5, 6>(s, fixed_b5); } /*========================================== * *------------------------------------------ */ -void clif_scriptclose(dumb_ptr<map_session_data> sd, int npcid) +void clif_scriptclose(dumb_ptr<map_session_data> sd, BlockId npcid) { nullpo_retv(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xb6; - WFIFOL(s, 2) = npcid; - WFIFOSET(s, clif_parse_func_table[0xb6].len); + Packet_Fixed<0x00b6> fixed_b6; + fixed_b6.block_id = npcid; + send_fpacket<0x00b6, 6>(s, fixed_b6); } /*========================================== * *------------------------------------------ */ -void clif_scriptmenu(dumb_ptr<map_session_data> sd, int npcid, XString mes) +void clif_scriptmenu(dumb_ptr<map_session_data> sd, BlockId npcid, XString mes) { nullpo_retv(sd); Session *s = sd->sess; - size_t len = mes.size() + 1; - WFIFOW(s, 0) = 0xb7; - WFIFOW(s, 2) = len + 8; - WFIFOL(s, 4) = npcid; - WFIFO_STRING(s, 8, mes, len); - WFIFOSET(s, WFIFOW(s, 2)); + Packet_Head<0x00b7> head_b7; + head_b7.block_id = npcid; + send_vpacket<0x00b7, 8, 1>(s, head_b7, mes); } /*========================================== * *------------------------------------------ */ -void clif_scriptinput(dumb_ptr<map_session_data> sd, int npcid) +void clif_scriptinput(dumb_ptr<map_session_data> sd, BlockId npcid) { nullpo_retv(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0x142; - WFIFOL(s, 2) = npcid; - WFIFOSET(s, clif_parse_func_table[0x142].len); + Packet_Fixed<0x0142> fixed_142; + fixed_142.block_id = npcid; + send_fpacket<0x0142, 6>(s, fixed_142); } /*========================================== * *------------------------------------------ */ -void clif_scriptinputstr(dumb_ptr<map_session_data> sd, int npcid) +void clif_scriptinputstr(dumb_ptr<map_session_data> sd, BlockId npcid) { nullpo_retv(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0x1d4; - WFIFOL(s, 2) = npcid; - WFIFOSET(s, clif_parse_func_table[0x1d4].len); + Packet_Fixed<0x01d4> fixed_1d4; + fixed_1d4.block_id = npcid; + send_fpacket<0x01d4, 6>(s, fixed_1d4); } /*========================================== * *------------------------------------------ */ -void clif_viewpoint(dumb_ptr<map_session_data> sd, int npc_id, int type, - int x, int y, int id, int color) +int clif_additem(dumb_ptr<map_session_data> sd, IOff0 n, int amount, PickupFail fail) { - nullpo_retv(sd); - - Session *s = sd->sess; - WFIFOW(s, 0) = 0x144; - WFIFOL(s, 2) = npc_id; - WFIFOL(s, 6) = type; - WFIFOL(s, 10) = x; - WFIFOL(s, 14) = y; - WFIFOB(s, 18) = id; - WFIFOL(s, 19) = color; - WFIFOSET(s, clif_parse_func_table[0x144].len); -} - -/*========================================== - * - *------------------------------------------ - */ -int clif_additem(dumb_ptr<map_session_data> sd, int n, int amount, PickupFail fail) -{ - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; + Packet_Fixed<0x00a0> fixed_a0; if (fail != PickupFail::OKAY) { - WFIFOW(s, 0) = 0xa0; - WFIFOW(s, 2) = n + 2; - WFIFOW(s, 4) = amount; - WFIFOW(s, 6) = 0; - WFIFOB(s, 8) = 0; - WFIFOB(s, 9) = 0; - WFIFOB(s, 10) = 0; - WFIFOW(s, 11) = 0; - WFIFOW(s, 13) = 0; - WFIFOW(s, 15) = 0; - WFIFOW(s, 17) = 0; - WFIFOW(s, 19) = 0; - WFIFOB(s, 21) = 0; - WFIFOB(s, 22) = uint8_t(fail); + fixed_a0.ioff2 = n.shift(); + fixed_a0.amount = amount; + fixed_a0.name_id = ItemNameId(); + fixed_a0.pickup_fail = fail; } else { - if (n < 0 || n >= MAX_INVENTORY || sd->status.inventory[n].nameid <= 0 - || sd->inventory_data[n] == NULL) + if (!n.ok() || !sd->status.inventory[n].nameid + || sd->inventory_data[n] == nullptr) return 1; - WFIFOW(s, 0) = 0xa0; - WFIFOW(s, 2) = n + 2; - WFIFOW(s, 4) = amount; - WFIFOW(s, 6) = sd->status.inventory[n].nameid; - WFIFOB(s, 8) = 1; //identify; - WFIFOB(s, 9) = 0; // broken or attribute; - WFIFOB(s, 10) = 0; //refine; + fixed_a0.ioff2 = n.shift(); + fixed_a0.amount = amount; + fixed_a0.name_id = sd->status.inventory[n].nameid; + fixed_a0.identify = 1; + fixed_a0.broken_or_attribute = 0; + fixed_a0.refine = 0; { - WFIFOW(s, 11) = 0; //card[0]; - WFIFOW(s, 13) = 0; //card[1]; - WFIFOW(s, 15) = 0; //card[2]; - WFIFOW(s, 17) = 0; //card[3]; + fixed_a0.card0 = 0; + fixed_a0.card1 = 0; + fixed_a0.card2 = 0; + fixed_a0.card3 = 0; } - WFIFOW(s, 19) = uint16_t(pc_equippoint(sd, n)); - WFIFOB(s, 21) = uint8_t(sd->inventory_data[n]->type == ItemType::_7 + fixed_a0.epos = pc_equippoint(sd, n); + fixed_a0.item_type = (sd->inventory_data[n]->type == ItemType::_7 ? ItemType::WEAPON : sd->inventory_data[n]->type); - WFIFOB(s, 22) = uint8_t(fail); + fixed_a0.pickup_fail = fail; } - WFIFOSET(s, clif_parse_func_table[0xa0].len); + send_fpacket<0x00a0, 23>(s, fixed_a0); return 0; } @@ -1438,16 +1407,16 @@ int clif_additem(dumb_ptr<map_session_data> sd, int n, int amount, PickupFail fa * *------------------------------------------ */ -void clif_delitem(dumb_ptr<map_session_data> sd, int n, int amount) +void clif_delitem(dumb_ptr<map_session_data> sd, IOff0 n, int amount) { nullpo_retv(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xaf; - WFIFOW(s, 2) = n + 2; - WFIFOW(s, 4) = amount; + Packet_Fixed<0x00af> fixed_af; + fixed_af.ioff2 = n.shift(); + fixed_af.amount = amount; - WFIFOSET(s, clif_parse_func_table[0xaf].len); + send_fpacket<0x00af, 6>(s, fixed_af); } /*========================================== @@ -1458,41 +1427,40 @@ void clif_itemlist(dumb_ptr<map_session_data> sd) { nullpo_retv(sd); - int n = 0; - int arrow = -1; + IOff0 arrow = IOff0::from(-1); Session *s = sd->sess; - WFIFOW(s, 0) = 0x1ee; - for (int i = 0; i < MAX_INVENTORY; i++) + std::vector<Packet_Repeat<0x01ee>> repeat_1ee; + for (IOff0 i : IOff0::iter()) { - if (sd->status.inventory[i].nameid <= 0 - || sd->inventory_data[i] == NULL + if (!sd->status.inventory[i].nameid + || sd->inventory_data[i] == nullptr || itemdb_isequip2(sd->inventory_data[i])) continue; - WFIFOW(s, n * 18 + 4) = i + 2; - WFIFOW(s, n * 18 + 6) = sd->status.inventory[i].nameid; - WFIFOB(s, n * 18 + 8) = uint8_t(sd->inventory_data[i]->type); - WFIFOB(s, n * 18 + 9) = 1; //identify; - WFIFOW(s, n * 18 + 10) = sd->status.inventory[i].amount; + Packet_Repeat<0x01ee> info; + info.ioff2 = i.shift(); + info.name_id = sd->status.inventory[i].nameid; + info.item_type = sd->inventory_data[i]->type; + info.identify = 1; + info.amount = sd->status.inventory[i].amount; if (sd->inventory_data[i]->equip == EPOS::ARROW) { - WFIFOW(s, n * 18 + 12) = uint16_t(EPOS::ARROW); + info.epos = EPOS::ARROW; if (bool(sd->status.inventory[i].equip)) - arrow = i; // ついでに矢装備チェック + arrow = i; } else - WFIFOW(s, n * 18 + 12) = uint16_t(EPOS::ZERO); - WFIFOW(s, n * 18 + 14) = 0; //card[0]; - WFIFOW(s, n * 18 + 16) = 0; //card[1]; - WFIFOW(s, n * 18 + 18) = 0; //card[2]; - WFIFOW(s, n * 18 + 20) = 0; //card[3]; - n++; + info.epos = EPOS::ZERO; + info.card0 = 0; + info.card1 = 0; + info.card2 = 0; + info.card3 = 0; + repeat_1ee.push_back(info); } - if (n) + if (!repeat_1ee.empty()) { - WFIFOW(s, 2) = 4 + n * 18; - WFIFOSET(s, WFIFOW(s, 2)); + send_packet_repeatonly<0x01ee, 4, 18>(s, repeat_1ee); } - if (arrow >= 0) + if (arrow.ok()) clif_arrowequip(sd, arrow); } @@ -1505,37 +1473,36 @@ void clif_equiplist(dumb_ptr<map_session_data> sd) nullpo_retv(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xa4; - int n = 0; - for (int i = 0; i < MAX_INVENTORY; i++) + std::vector<Packet_Repeat<0x00a4>> repeat_a4; + for (IOff0 i : IOff0::iter()) { - if (sd->status.inventory[i].nameid <= 0 - || sd->inventory_data[i] == NULL + if (!sd->status.inventory[i].nameid + || sd->inventory_data[i] == nullptr || !itemdb_isequip2(sd->inventory_data[i])) continue; - WFIFOW(s, n * 20 + 4) = i + 2; - WFIFOW(s, n * 20 + 6) = sd->status.inventory[i].nameid; - WFIFOB(s, n * 20 + 8) = uint8_t( + Packet_Repeat<0x00a4> info; + info.ioff2 = i.shift(); + info.name_id = sd->status.inventory[i].nameid; + info.item_type = ( sd->inventory_data[i]->type == ItemType::_7 ? ItemType::WEAPON : sd->inventory_data[i]->type); - WFIFOB(s, n * 20 + 9) = 0; //identify; - WFIFOW(s, n * 20 + 10) = uint16_t(pc_equippoint(sd, i)); - WFIFOW(s, n * 20 + 12) = uint16_t(sd->status.inventory[i].equip); - WFIFOB(s, n * 20 + 14) = 0; //broken or attribute; - WFIFOB(s, n * 20 + 15) = 0; //refine; + info.identify = 0; + info.epos_pc = pc_equippoint(sd, i); + info.epos_inv = sd->status.inventory[i].equip; + info.broken_or_attribute = 0; + info.refine = 0; { - WFIFOW(s, n * 20 + 16) = 0; //card[0]; - WFIFOW(s, n * 20 + 18) = 0; //card[1]; - WFIFOW(s, n * 20 + 20) = 0; //card[2]; - WFIFOW(s, n * 20 + 22) = 0; //card[3]; + info.card0 = 0; + info.card1 = 0; + info.card2 = 0; + info.card3 = 0; } - n++; + repeat_a4.push_back(info); } - if (n) + if (!repeat_a4.empty()) { - WFIFOW(s, 2) = 4 + n * 20; - WFIFOSET(s, WFIFOW(s, 2)); + send_packet_repeatonly<0x00a4, 4, 20>(s, repeat_a4); } } @@ -1543,41 +1510,40 @@ void clif_equiplist(dumb_ptr<map_session_data> sd) * カプラさんに預けてある消耗品&収集品リスト *------------------------------------------ */ -int clif_storageitemlist(dumb_ptr<map_session_data> sd, struct storage *stor) +int clif_storageitemlist(dumb_ptr<map_session_data> sd, Storage *stor) { - nullpo_ret(sd); - nullpo_ret(stor); + nullpo_retz(sd); + nullpo_retz(stor); Session *s = sd->sess; - WFIFOW(s, 0) = 0x1f0; - int n = 0; - for (int i = 0; i < MAX_STORAGE; i++) + std::vector<Packet_Repeat<0x01f0>> repeat_1f0; + for (SOff0 i : SOff0::iter()) { - if (stor->storage_[i].nameid <= 0) + if (!stor->storage_[i].nameid) continue; struct item_data *id; id = itemdb_search(stor->storage_[i].nameid); - nullpo_ret(id); + nullpo_retz(id); if (itemdb_isequip2(id)) continue; - WFIFOW(s, n * 18 + 4) = i + 1; - WFIFOW(s, n * 18 + 6) = stor->storage_[i].nameid; - WFIFOB(s, n * 18 + 8) = uint8_t(id->type); - WFIFOB(s, n * 18 + 9) = 0; //identify; - WFIFOW(s, n * 18 + 10) = stor->storage_[i].amount; - WFIFOW(s, n * 18 + 12) = 0; - WFIFOW(s, n * 18 + 14) = 0; //card[0]; - WFIFOW(s, n * 18 + 16) = 0; //card[1]; - WFIFOW(s, n * 18 + 18) = 0; //card[2]; - WFIFOW(s, n * 18 + 20) = 0; //card[3]; - n++; + Packet_Repeat<0x01f0> info; + info.soff1 = i.shift(); + info.name_id = stor->storage_[i].nameid; + info.item_type = id->type; + info.identify = 0; + info.amount = stor->storage_[i].amount; + info.epos_zero = EPOS::ZERO; + info.card0 = 0; + info.card1 = 0; + info.card2 = 0; + info.card3 = 0; + repeat_1f0.push_back(info); } - if (n) + if (!repeat_1f0.empty()) { - WFIFOW(s, 2) = 4 + n * 18; - WFIFOSET(s, WFIFOW(s, 2)); + send_packet_repeatonly<0x01f0, 4, 18>(s, repeat_1f0); } return 0; } @@ -1586,44 +1552,43 @@ int clif_storageitemlist(dumb_ptr<map_session_data> sd, struct storage *stor) * カプラさんに預けてある装備リスト *------------------------------------------ */ -int clif_storageequiplist(dumb_ptr<map_session_data> sd, struct storage *stor) +int clif_storageequiplist(dumb_ptr<map_session_data> sd, Storage *stor) { - nullpo_ret(sd); - nullpo_ret(stor); + nullpo_retz(sd); + nullpo_retz(stor); Session *s = sd->sess; - WFIFOW(s, 0) = 0xa6; - int n = 0; - for (int i = 0; i < MAX_STORAGE; i++) + std::vector<Packet_Repeat<0x00a6>> repeat_a6; + for (SOff0 i : SOff0::iter()) { - if (stor->storage_[i].nameid <= 0) + if (!stor->storage_[i].nameid) continue; struct item_data *id; id = itemdb_search(stor->storage_[i].nameid); - nullpo_ret(id); + nullpo_retz(id); if (!itemdb_isequip2(id)) continue; - WFIFOW(s, n * 20 + 4) = i + 1; - WFIFOW(s, n * 20 + 6) = stor->storage_[i].nameid; - WFIFOB(s, n * 20 + 8) = uint8_t(id->type); - WFIFOB(s, n * 20 + 9) = 0; //identify; - WFIFOW(s, n * 20 + 10) = uint16_t(id->equip); - WFIFOW(s, n * 20 + 12) = uint16_t(stor->storage_[i].equip); - WFIFOB(s, n * 20 + 14) = 0; //broken or attribute - WFIFOB(s, n * 20 + 15) = 0; //refine; + Packet_Repeat<0x00a6> info; + info.soff1 = i.shift(); + info.name_id = stor->storage_[i].nameid; + info.item_type = id->type; + info.identify = 0; + info.epos_id = id->equip; + info.epos_stor = stor->storage_[i].equip; + info.broken_or_attribute = 0; + info.refine = 0; { - WFIFOW(s, n * 20 + 16) = 0; //card[0]; - WFIFOW(s, n * 20 + 18) = 0; //card[1]; - WFIFOW(s, n * 20 + 20) = 0; //card[2]; - WFIFOW(s, n * 20 + 22) = 0; //card[3]; + info.card0 = 0; + info.card1 = 0; + info.card2 = 0; + info.card3 = 0; } - n++; + repeat_a6.push_back(info); } - if (n) + if (!repeat_a6.empty()) { - WFIFOW(s, 2) = 4 + n * 20; - WFIFOSET(s, WFIFOW(s, 2)); + send_packet_repeatonly<0x00a6, 4, 20>(s, repeat_a6); } return 0; } @@ -1635,140 +1600,183 @@ int clif_storageequiplist(dumb_ptr<map_session_data> sd, struct storage *stor) */ int clif_updatestatus(dumb_ptr<map_session_data> sd, SP type) { - int len = 8; - - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xb0; - WFIFOW(s, 2) = static_cast<uint16_t>(type); - switch (type) { - // 00b0 + Packet_Fixed<0x00b0> fixed_b0; + fixed_b0.sp_type = type; + switch (type) + { case SP::WEIGHT: pc_checkweighticon(sd); - // is this because pc_checkweighticon can send other packets? - WFIFOW(s, 0) = 0xb0; - WFIFOW(s, 2) = static_cast<uint16_t>(type); - WFIFOL(s, 4) = sd->weight; + fixed_b0.value = sd->weight; break; case SP::MAXWEIGHT: - WFIFOL(s, 4) = sd->max_weight; + fixed_b0.value = sd->max_weight; break; case SP::SPEED: - // ... - WFIFOL(s, 4) = static_cast<uint16_t>(sd->speed.count()); + // 'speed' is actually delay, in milliseconds + fixed_b0.value = sd->speed.count(); break; case SP::BASELEVEL: - WFIFOL(s, 4) = sd->status.base_level; + fixed_b0.value = sd->status.base_level; break; case SP::JOBLEVEL: - WFIFOL(s, 4) = 0; + fixed_b0.value = sd->status.job_level; break; case SP::STATUSPOINT: - WFIFOL(s, 4) = sd->status.status_point; + fixed_b0.value = sd->status.status_point; break; case SP::SKILLPOINT: - WFIFOL(s, 4) = sd->status.skill_point; + fixed_b0.value = sd->status.skill_point; break; case SP::HIT: - WFIFOL(s, 4) = sd->hit; + fixed_b0.value = sd->hit; break; case SP::FLEE1: - WFIFOL(s, 4) = sd->flee; + fixed_b0.value = sd->flee; break; case SP::FLEE2: - WFIFOL(s, 4) = sd->flee2 / 10; + fixed_b0.value = sd->flee2 / 10; break; case SP::MAXHP: - WFIFOL(s, 4) = sd->status.max_hp; + fixed_b0.value = sd->status.max_hp; break; case SP::MAXSP: - WFIFOL(s, 4) = sd->status.max_sp; + fixed_b0.value = sd->status.max_sp; break; case SP::HP: - WFIFOL(s, 4) = sd->status.hp; + fixed_b0.value = sd->status.hp; break; case SP::SP: - WFIFOL(s, 4) = sd->status.sp; + fixed_b0.value = sd->status.sp; break; case SP::ASPD: - WFIFOL(s, 4) = static_cast<uint16_t>(sd->aspd.count()); + fixed_b0.value = sd->aspd.count(); break; case SP::ATK1: - WFIFOL(s, 4) = sd->base_atk + sd->watk; + fixed_b0.value = sd->base_atk + sd->watk; break; case SP::DEF1: - WFIFOL(s, 4) = sd->def; + fixed_b0.value = sd->def; break; case SP::MDEF1: - WFIFOL(s, 4) = sd->mdef; + fixed_b0.value = sd->mdef; break; case SP::ATK2: - WFIFOL(s, 4) = sd->watk2; + fixed_b0.value = sd->watk2; break; case SP::DEF2: - WFIFOL(s, 4) = sd->def2; + fixed_b0.value = sd->def2; break; case SP::MDEF2: - WFIFOL(s, 4) = sd->mdef2; + fixed_b0.value = sd->mdef2; break; case SP::CRITICAL: - WFIFOL(s, 4) = sd->critical / 10; + fixed_b0.value = sd->critical / 10; break; case SP::MATK1: - WFIFOL(s, 4) = sd->matk1; + fixed_b0.value = sd->matk1; break; case SP::MATK2: - WFIFOL(s, 4) = sd->matk2; + fixed_b0.value = sd->matk2; + break; + case SP::GM: + fixed_b0.value = pc_isGM(sd).get_all_bits(); break; + default: + goto not_b0; + } + + send_fpacket<0x00b0, 8>(s, fixed_b0); + return 0; + } +not_b0: + + { + Packet_Fixed<0x00b1> fixed_b1; + fixed_b1.sp_type = type; + switch (type) + { case SP::ZENY: trade_verifyzeny(sd); - WFIFOW(s, 0) = 0xb1; if (sd->status.zeny < 0) sd->status.zeny = 0; - WFIFOL(s, 4) = sd->status.zeny; + fixed_b1.value = sd->status.zeny; break; + case SP::BASEEXP: - WFIFOW(s, 0) = 0xb1; - WFIFOL(s, 4) = sd->status.base_exp; + fixed_b1.value = sd->status.base_exp; break; case SP::JOBEXP: - WFIFOW(s, 0) = 0xb1; - WFIFOL(s, 4) = sd->status.job_exp; + fixed_b1.value = sd->status.job_exp; break; case SP::NEXTBASEEXP: - WFIFOW(s, 0) = 0xb1; - WFIFOL(s, 4) = pc_nextbaseexp(sd); + fixed_b1.value = pc_nextbaseexp(sd); break; case SP::NEXTJOBEXP: - WFIFOW(s, 0) = 0xb1; - WFIFOL(s, 4) = pc_nextjobexp(sd); + fixed_b1.value = pc_nextjobexp(sd); break; - // 00be 終了 + default: + goto not_b1; + } + + send_fpacket<0x00b1, 8>(s, fixed_b1); + return 0; + } +not_b1: + + { + Packet_Fixed<0x00be> fixed_be; + fixed_be.sp_type = type; + switch (type) + { case SP::USTR: case SP::UAGI: case SP::UVIT: case SP::UINT: case SP::UDEX: case SP::ULUK: - WFIFOW(s, 0) = 0xbe; - WFIFOB(s, 4) = pc_need_status_point(sd, usp_to_sp(type)); - len = 5; + fixed_be.value = pc_need_status_point(sd, usp_to_sp(type)); break; - // 013a 終了 + default: + goto not_be; + } + + send_fpacket<0x00be, 5>(s, fixed_be); + return 0; + } +not_be: + + { + Packet_Fixed<0x013a> fixed_13a; + switch (type) + { case SP::ATTACKRANGE: - WFIFOW(s, 0) = 0x13a; - WFIFOW(s, 2) = (sd->attack_spell_override) - ? sd->attack_spell_range : sd->attackrange; - len = 4; + fixed_13a.attack_range = (sd->attack_spell_override + ? sd->attack_spell_range + : sd->attackrange); break; - // 0141 終了 + default: + goto not_13a; + } + + send_fpacket<0x013a, 4>(s, fixed_13a); + return 0; + } +not_13a: + + { + Packet_Fixed<0x00141> fixed_141; + fixed_141.sp_type = type; + switch (type) + { case SP::STR: case SP::AGI: case SP::VIT: @@ -1777,27 +1785,28 @@ int clif_updatestatus(dumb_ptr<map_session_data> sd, SP type) case SP::LUK: { ATTR attr = sp_to_attr(type); - WFIFOW(s, 0) = 0x141; - WFIFOL(s, 2) = uint16_t(type); - WFIFOL(s, 6) = sd->status.attrs[attr]; - WFIFOL(s, 10) = sd->paramb[attr] + sd->parame[attr]; - len = 14; + fixed_141.value_status = sd->status.attrs[attr]; + fixed_141.value_b_e = sd->paramb[attr] + sd->parame[attr]; } break; - case SP::GM: - WFIFOL(s, 4) = pc_isGM(sd); - break; - default: + goto not_141; + } + + send_fpacket<0x0141, 14>(s, fixed_141); + return 0; + } + +not_141: + { + { if (battle_config.error_log) - PRINTF("clif_updatestatus : make %d routine\n", + PRINTF("clif_updatestatus : make %d routine\n"_fmt, type); return 1; + } } - WFIFOSET(s, len); - - return 0; } /*========================================== @@ -1806,16 +1815,15 @@ int clif_updatestatus(dumb_ptr<map_session_data> sd, SP type) */ int clif_changelook(dumb_ptr<block_list> bl, LOOK type, int val) { - return clif_changelook_towards(bl, type, val, NULL); + return clif_changelook_towards(bl, type, val, nullptr); } int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val, dumb_ptr<map_session_data> dstsd) { - unsigned char buf[32]; - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::PC) sd = bl->is_player(); @@ -1826,61 +1834,65 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val, if (sd && (type == LOOK::WEAPON || type == LOOK::SHIELD || type >= LOOK::SHOES)) { - WBUFW(buf, 0) = 0x1d7; - WBUFL(buf, 2) = bl->bl_id; + Packet_Fixed<0x01d7> fixed_1d7; + fixed_1d7.block_id = bl->bl_id; if (type >= LOOK::SHOES) { EQUIP equip_point = equip_points[type]; - WBUFB(buf, 6) = uint16_t(type); - int idx = sd->equip_index_maybe[equip_point]; - if (idx >= 0 && sd->inventory_data[idx]) + fixed_1d7.look_type = type; + IOff0 idx = sd->equip_index_maybe[equip_point]; + if (idx.ok() && sd->inventory_data[idx]) { - WBUFW(buf, 7) = sd->status.inventory[idx].nameid; + fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(sd->status.inventory[idx].nameid); } else - WBUFW(buf, 7) = 0; - WBUFW(buf, 9) = 0; + fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(ItemNameId()); + fixed_1d7.shield = ItemNameId(); } else { - WBUFB(buf, 6) = 2; - int widx = sd->equip_index_maybe[EQUIP::WEAPON]; - int sidx = sd->equip_index_maybe[EQUIP::SHIELD]; + fixed_1d7.look_type = LOOK::WEAPON; + IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON]; + IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD]; if (sd->attack_spell_override) - WBUFW(buf, 7) = sd->attack_spell_look_override; + fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(sd->attack_spell_look_override); else { - if (widx >= 0 && sd->inventory_data[widx]) + if (widx.ok() && sd->inventory_data[widx]) { - WBUFW(buf, 7) = sd->status.inventory[widx].nameid; + fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(sd->status.inventory[widx].nameid); } else - WBUFW(buf, 7) = 0; + fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(ItemNameId()); } - if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx]) + if (sidx.ok() && sidx != widx && sd->inventory_data[sidx]) { - WBUFW(buf, 9) = sd->status.inventory[sidx].nameid; + fixed_1d7.shield = sd->status.inventory[sidx].nameid; } else - WBUFW(buf, 9) = 0; + fixed_1d7.shield = ItemNameId(); } + + Buffer buf = create_fpacket<0x01d7, 11>(fixed_1d7); if (dstsd) - clif_send(buf, clif_parse_func_table[0x1d7].len, dstsd, SendWho::SELF); + clif_send(buf, dstsd, SendWho::SELF); else - clif_send(buf, clif_parse_func_table[0x1d7].len, bl, SendWho::AREA); + clif_send(buf, bl, SendWho::AREA); } else { - WBUFW(buf, 0) = 0x1d7; - WBUFL(buf, 2) = bl->bl_id; - WBUFB(buf, 6) = uint8_t(type); - WBUFW(buf, 7) = val; - WBUFW(buf, 9) = 0; + Packet_Fixed<0x01d7> fixed_1d7; + fixed_1d7.block_id = bl->bl_id; + fixed_1d7.look_type = type; + fixed_1d7.weapon_or_name_id_or_value = val; + fixed_1d7.shield = ItemNameId(); + + Buffer buf = create_fpacket<0x01d7, 11>(fixed_1d7); if (dstsd) - clif_send(buf, clif_parse_func_table[0x1d7].len, dstsd, SendWho::SELF); + clif_send(buf, dstsd, SendWho::SELF); else - clif_send(buf, clif_parse_func_table[0x1d7].len, bl, SendWho::AREA); + clif_send(buf, bl, SendWho::AREA); } return 0; } @@ -1892,42 +1904,42 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val, static int clif_initialstatus(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xbd; - WFIFOW(s, 2) = sd->status.status_point; - - WFIFOB(s, 4) = min(sd->status.attrs[ATTR::STR], 255); - WFIFOB(s, 5) = pc_need_status_point(sd, SP::STR); - WFIFOB(s, 6) = min(sd->status.attrs[ATTR::AGI], 255); - WFIFOB(s, 7) = pc_need_status_point(sd, SP::AGI); - WFIFOB(s, 8) = min(sd->status.attrs[ATTR::VIT], 255); - WFIFOB(s, 9) = pc_need_status_point(sd, SP::VIT); - WFIFOB(s, 10) = min(sd->status.attrs[ATTR::INT], 255); - WFIFOB(s, 11) = pc_need_status_point(sd, SP::INT); - WFIFOB(s, 12) = min(sd->status.attrs[ATTR::DEX], 255); - WFIFOB(s, 13) = pc_need_status_point(sd, SP::DEX); - WFIFOB(s, 14) = min(sd->status.attrs[ATTR::LUK], 255); - WFIFOB(s, 15) = pc_need_status_point(sd, SP::LUK); - - WFIFOW(s, 16) = sd->base_atk + sd->watk; - WFIFOW(s, 18) = sd->watk2; //atk bonus - WFIFOW(s, 20) = sd->matk1; - WFIFOW(s, 22) = sd->matk2; - WFIFOW(s, 24) = sd->def; // def - WFIFOW(s, 26) = sd->def2; - WFIFOW(s, 28) = sd->mdef; // mdef - WFIFOW(s, 30) = sd->mdef2; - WFIFOW(s, 32) = sd->hit; - WFIFOW(s, 34) = sd->flee; - WFIFOW(s, 36) = sd->flee2 / 10; - WFIFOW(s, 38) = sd->critical / 10; - WFIFOW(s, 40) = sd->status.karma; - WFIFOW(s, 42) = sd->status.manner; - - WFIFOSET(s, clif_parse_func_table[0xbd].len); + Packet_Fixed<0x00bd> fixed_bd; + fixed_bd.status_point = sd->status.status_point; + + fixed_bd.str_attr = saturate<uint8_t>(sd->status.attrs[ATTR::STR]); + fixed_bd.str_upd = pc_need_status_point(sd, SP::STR); + fixed_bd.agi_attr = saturate<uint8_t>(sd->status.attrs[ATTR::AGI]); + fixed_bd.agi_upd = pc_need_status_point(sd, SP::AGI); + fixed_bd.vit_attr = saturate<uint8_t>(sd->status.attrs[ATTR::VIT]); + fixed_bd.vit_upd = pc_need_status_point(sd, SP::VIT); + fixed_bd.int_attr = saturate<uint8_t>(sd->status.attrs[ATTR::INT]); + fixed_bd.int_upd = pc_need_status_point(sd, SP::INT); + fixed_bd.dex_attr = saturate<uint8_t>(sd->status.attrs[ATTR::DEX]); + fixed_bd.dex_upd = pc_need_status_point(sd, SP::DEX); + fixed_bd.luk_attr = saturate<uint8_t>(sd->status.attrs[ATTR::LUK]); + fixed_bd.luk_upd = pc_need_status_point(sd, SP::LUK); + + fixed_bd.atk_sum = sd->base_atk + sd->watk; + fixed_bd.watk2 = sd->watk2; //atk bonus + fixed_bd.matk1 = sd->matk1; + fixed_bd.matk2 = sd->matk2; + fixed_bd.def = sd->def; + fixed_bd.def2 = sd->def2; + fixed_bd.mdef = sd->mdef; + fixed_bd.mdef2 = sd->mdef2; + fixed_bd.hit = sd->hit; + fixed_bd.flee = sd->flee; + fixed_bd.flee2 = sd->flee2 / 10; + fixed_bd.critical = sd->critical / 10; + fixed_bd.karma = sd->status.karma; + fixed_bd.manner = sd->status.manner; + + send_fpacket<0x00bd, 44>(s, fixed_bd); clif_updatestatus(sd, SP::STR); clif_updatestatus(sd, SP::AGI); @@ -1946,18 +1958,16 @@ int clif_initialstatus(dumb_ptr<map_session_data> sd) *矢装備 *------------------------------------------ */ -int clif_arrowequip(dumb_ptr<map_session_data> sd, int val) +int clif_arrowequip(dumb_ptr<map_session_data> sd, IOff0 val) { - nullpo_ret(sd); + nullpo_retz(sd); - if (sd->attacktarget && sd->attacktarget > 0) // [Valaris] - sd->attacktarget = 0; + sd->attacktarget = BlockId(); Session *s = sd->sess; - WFIFOW(s, 0) = 0x013c; - WFIFOW(s, 2) = val + 2; //矢のアイテムID - - WFIFOSET(s, clif_parse_func_table[0x013c].len); + Packet_Fixed<0x013c> fixed_13c; + fixed_13c.ioff2 = val.shift(); + send_fpacket<0x013c, 4>(s, fixed_13c); return 0; } @@ -1968,14 +1978,13 @@ int clif_arrowequip(dumb_ptr<map_session_data> sd, int val) */ int clif_arrow_fail(dumb_ptr<map_session_data> sd, int type) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0x013b; - WFIFOW(s, 2) = type; - - WFIFOSET(s, clif_parse_func_table[0x013b].len); + Packet_Fixed<0x013b> fixed_13b; + fixed_13b.type = type; + send_fpacket<0x013b, 4>(s, fixed_13b); return 0; } @@ -1986,14 +1995,14 @@ int clif_arrow_fail(dumb_ptr<map_session_data> sd, int type) */ int clif_statusupack(dumb_ptr<map_session_data> sd, SP type, int ok, int val) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xbc; - WFIFOW(s, 2) = uint16_t(type); - WFIFOB(s, 4) = ok; - WFIFOB(s, 5) = val; - WFIFOSET(s, clif_parse_func_table[0xbc].len); + Packet_Fixed<0x00bc> fixed_bc; + fixed_bc.sp_type = type; + fixed_bc.ok = ok; + fixed_bc.val = val; + send_fpacket<0x00bc, 6>(s, fixed_bc); return 0; } @@ -2002,16 +2011,16 @@ int clif_statusupack(dumb_ptr<map_session_data> sd, SP type, int ok, int val) * *------------------------------------------ */ -int clif_equipitemack(dumb_ptr<map_session_data> sd, int n, EPOS pos, int ok) +int clif_equipitemack(dumb_ptr<map_session_data> sd, IOff0 n, EPOS pos, int ok) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xaa; - WFIFOW(s, 2) = n + 2; - WFIFOW(s, 4) = uint16_t(pos); - WFIFOB(s, 6) = ok; - WFIFOSET(s, clif_parse_func_table[0xaa].len); + Packet_Fixed<0x00aa> fixed_aa; + fixed_aa.ioff2 = n.shift(); + fixed_aa.epos = pos; + fixed_aa.ok = ok; + send_fpacket<0x00aa, 7>(s, fixed_aa); return 0; } @@ -2020,16 +2029,16 @@ int clif_equipitemack(dumb_ptr<map_session_data> sd, int n, EPOS pos, int ok) * *------------------------------------------ */ -int clif_unequipitemack(dumb_ptr<map_session_data> sd, int n, EPOS pos, int ok) +int clif_unequipitemack(dumb_ptr<map_session_data> sd, IOff0 n, EPOS pos, int ok) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xac; - WFIFOW(s, 2) = n + 2; - WFIFOW(s, 4) = uint16_t(pos); - WFIFOB(s, 6) = ok; - WFIFOSET(s, clif_parse_func_table[0xac].len); + Packet_Fixed<0x00ac> fixed_ac; + fixed_ac.ioff2 = n.shift(); + fixed_ac.epos = pos; + fixed_ac.ok = ok; + send_fpacket<0x00ac, 7>(s, fixed_ac); return 0; } @@ -2040,15 +2049,14 @@ int clif_unequipitemack(dumb_ptr<map_session_data> sd, int n, EPOS pos, int ok) */ int clif_misceffect(dumb_ptr<block_list> bl, int type) { - uint8_t buf[32]; + nullpo_retz(bl); - nullpo_ret(bl); + Packet_Fixed<0x019b> fixed_19b; + fixed_19b.block_id = bl->bl_id; + fixed_19b.type = type; + Buffer buf = create_fpacket<0x019b, 10>(fixed_19b); - WBUFW(buf, 0) = 0x19b; - WBUFL(buf, 2) = bl->bl_id; - WBUFL(buf, 6) = type; - - clif_send(buf, clif_parse_func_table[0x19b].len, bl, SendWho::AREA); + clif_send(buf, bl, SendWho::AREA); return 0; } @@ -2059,22 +2067,22 @@ int clif_misceffect(dumb_ptr<block_list> bl, int type) */ int clif_changeoption(dumb_ptr<block_list> bl) { - uint8_t buf[32]; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; - nullpo_ret(bl); + nullpo_retz(bl); Option option = *battle_get_option(bl); sc_data = battle_get_sc_data(bl); - WBUFW(buf, 0) = 0x119; - WBUFL(buf, 2) = bl->bl_id; - WBUFW(buf, 6) = uint16_t(*battle_get_opt1(bl)); - WBUFW(buf, 8) = uint16_t(*battle_get_opt2(bl)); - WBUFW(buf, 10) = uint16_t(option); - WBUFB(buf, 12) = 0; // ?? + Packet_Fixed<0x0119> fixed_119; + fixed_119.block_id = bl->bl_id; + fixed_119.opt1 = *battle_get_opt1(bl); + fixed_119.opt2 = *battle_get_opt2(bl); + fixed_119.option = option; + fixed_119.zero = 0; + Buffer buf = create_fpacket<0x0119, 13>(fixed_119); - clif_send(buf, clif_parse_func_table[0x119].len, bl, SendWho::AREA); + clif_send(buf, bl, SendWho::AREA); return 0; } @@ -2083,31 +2091,30 @@ int clif_changeoption(dumb_ptr<block_list> bl) * *------------------------------------------ */ -int clif_useitemack(dumb_ptr<map_session_data> sd, int index, int amount, +int clif_useitemack(dumb_ptr<map_session_data> sd, IOff0 index, int amount, int ok) { - nullpo_ret(sd); + nullpo_retz(sd); if (!ok) { Session *s = sd->sess; - WFIFOW(s, 0) = 0xa8; - WFIFOW(s, 2) = index + 2; - WFIFOW(s, 4) = amount; - WFIFOB(s, 6) = ok; - WFIFOSET(s, clif_parse_func_table[0xa8].len); + Packet_Fixed<0x00a8> fixed_a8; + fixed_a8.ioff2 = index.shift(); + fixed_a8.amount = amount; + fixed_a8.ok = ok; + send_fpacket<0x00a8, 7>(s, fixed_a8); } else { - uint8_t buf[32]; - - WBUFW(buf, 0) = 0x1c8; - WBUFW(buf, 2) = index + 2; - WBUFW(buf, 4) = sd->status.inventory[index].nameid; - WBUFL(buf, 6) = sd->bl_id; - WBUFW(buf, 10) = amount; - WBUFB(buf, 12) = ok; - clif_send(buf, clif_parse_func_table[0x1c8].len, sd, SendWho::SELF); + Packet_Fixed<0x01c8> fixed_1c8; + fixed_1c8.ioff2 = index.shift(); + fixed_1c8.name_id = sd->status.inventory[index].nameid; + fixed_1c8.block_id = sd->bl_id; + fixed_1c8.amount = amount; + fixed_1c8.ok = ok; + Buffer buf = create_fpacket<0x01c8, 13>(fixed_1c8); + clif_send(buf, sd, SendWho::SELF); } return 0; @@ -2122,9 +2129,9 @@ void clif_traderequest(dumb_ptr<map_session_data> sd, CharName name) nullpo_retv(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xe5; - WFIFO_STRING(s, 2, name.to__actual(), 24); - WFIFOSET(s, clif_parse_func_table[0xe5].len); + Packet_Fixed<0x00e5> fixed_e5; + fixed_e5.char_name = name; + send_fpacket<0x00e5, 26>(s, fixed_e5); } /*========================================== @@ -2136,9 +2143,9 @@ void clif_tradestart(dumb_ptr<map_session_data> sd, int type) nullpo_retv(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xe7; - WFIFOB(s, 2) = type; - WFIFOSET(s, clif_parse_func_table[0xe7].len); + Packet_Fixed<0x00e7> fixed_e7; + fixed_e7.type = type; + send_fpacket<0x00e7, 3>(s, fixed_e7); } /*========================================== @@ -2146,57 +2153,57 @@ void clif_tradestart(dumb_ptr<map_session_data> sd, int type) *------------------------------------------ */ void clif_tradeadditem(dumb_ptr<map_session_data> sd, - dumb_ptr<map_session_data> tsd, int index, int amount) + dumb_ptr<map_session_data> tsd, IOff2 index2, int amount) { nullpo_retv(sd); nullpo_retv(tsd); Session *s = tsd->sess; - WFIFOW(s, 0) = 0xe9; - WFIFOL(s, 2) = amount; - if (index == 0) + Packet_Fixed<0x00e9> fixed_e9; + fixed_e9.amount = amount; + if (!index2.ok()) { - WFIFOW(s, 6) = 0; // type id - WFIFOB(s, 8) = 0; //identify flag - WFIFOB(s, 9) = 0; // attribute - WFIFOB(s, 10) = 0; //refine - WFIFOW(s, 11) = 0; //card (4w) - WFIFOW(s, 13) = 0; //card (4w) - WFIFOW(s, 15) = 0; //card (4w) - WFIFOW(s, 17) = 0; //card (4w) + fixed_e9.name_id = ItemNameId(); + fixed_e9.identify = 0; + fixed_e9.broken_or_attribute = 0; + fixed_e9.refine = 0; + fixed_e9.card0 = 0; + fixed_e9.card1 = 0; + fixed_e9.card2 = 0; + fixed_e9.card3 = 0; } else { - index -= 2; - WFIFOW(s, 6) = sd->status.inventory[index].nameid; // type id - WFIFOB(s, 8) = 0; //identify; - WFIFOB(s, 9) = 0; //broken or attribute; - WFIFOB(s, 10) = 0; //refine; + IOff0 index0 = index2.unshift(); + fixed_e9.name_id = sd->status.inventory[index0].nameid; + fixed_e9.identify = 0; + fixed_e9.broken_or_attribute = 0; + fixed_e9.refine = 0; { - WFIFOW(s, 11) = 0; //card[0]; - WFIFOW(s, 13) = 0; //card[1]; - WFIFOW(s, 15) = 0; //card[2]; - WFIFOW(s, 17) = 0; //card[3]; + fixed_e9.card0 = 0; + fixed_e9.card1 = 0; + fixed_e9.card2 = 0; + fixed_e9.card3 = 0; } } - WFIFOSET(s, clif_parse_func_table[0xe9].len); + send_fpacket<0x00e9, 19>(s, fixed_e9); } /*========================================== * アイテム追加成功/失敗 *------------------------------------------ */ -int clif_tradeitemok(dumb_ptr<map_session_data> sd, int index, int amount, +int clif_tradeitemok(dumb_ptr<map_session_data> sd, IOff2 index2, int amount, int fail) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0x1b1; - WFIFOW(s, 2) = index; - WFIFOW(s, 4) = amount; - WFIFOB(s, 6) = fail; - WFIFOSET(s, clif_parse_func_table[0x1b1].len); + Packet_Fixed<0x01b1> fixed_1b1; + fixed_1b1.ioff2 = index2; + fixed_1b1.amount = amount; + fixed_1b1.fail = fail; + send_fpacket<0x01b1, 7>(s, fixed_1b1); return 0; } @@ -2207,12 +2214,12 @@ int clif_tradeitemok(dumb_ptr<map_session_data> sd, int index, int amount, */ int clif_tradedeal_lock(dumb_ptr<map_session_data> sd, int fail) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xec; - WFIFOB(s, 2) = fail; // 0=you 1=the other person - WFIFOSET(s, clif_parse_func_table[0xec].len); + Packet_Fixed<0x00ec> fixed_ec; + fixed_ec.fail = fail; // 0=you 1=the other person + send_fpacket<0x00ec, 3>(s, fixed_ec); return 0; } @@ -2223,11 +2230,11 @@ int clif_tradedeal_lock(dumb_ptr<map_session_data> sd, int fail) */ int clif_tradecancelled(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xee; - WFIFOSET(s, clif_parse_func_table[0xee].len); + Packet_Fixed<0x00ee> fixed_ee; + send_fpacket<0x00ee, 2>(s, fixed_ee); return 0; } @@ -2238,12 +2245,12 @@ int clif_tradecancelled(dumb_ptr<map_session_data> sd) */ int clif_tradecompleted(dumb_ptr<map_session_data> sd, int fail) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xf0; - WFIFOB(s, 2) = fail; - WFIFOSET(s, clif_parse_func_table[0xf0].len); + Packet_Fixed<0x00f0> fixed_f0; + fixed_f0.fail = fail; + send_fpacket<0x00f0, 3>(s, fixed_f0); return 0; } @@ -2253,16 +2260,16 @@ int clif_tradecompleted(dumb_ptr<map_session_data> sd, int fail) *------------------------------------------ */ int clif_updatestorageamount(dumb_ptr<map_session_data> sd, - struct storage *stor) + Storage *stor) { - nullpo_ret(sd); - nullpo_ret(stor); + nullpo_retz(sd); + nullpo_retz(stor); Session *s = sd->sess; - WFIFOW(s, 0) = 0xf2; // update storage amount - WFIFOW(s, 2) = stor->storage_amount; //items - WFIFOW(s, 4) = MAX_STORAGE; //items max - WFIFOSET(s, clif_parse_func_table[0xf2].len); + Packet_Fixed<0x00f2> fixed_f2; + fixed_f2.current_slots = stor->storage_amount; //items + fixed_f2.max_slots = MAX_STORAGE; //items max + send_fpacket<0x00f2, 6>(s, fixed_f2); return 0; } @@ -2271,30 +2278,27 @@ int clif_updatestorageamount(dumb_ptr<map_session_data> sd, * カプラ倉庫にアイテムを追加する *------------------------------------------ */ -int clif_storageitemadded(dumb_ptr<map_session_data> sd, struct storage *stor, - int index, int amount) +int clif_storageitemadded(dumb_ptr<map_session_data> sd, Storage *stor, + SOff0 index, int amount) { - nullpo_ret(sd); - nullpo_ret(stor); + nullpo_retz(sd); + nullpo_retz(stor); Session *s = sd->sess; - WFIFOW(s, 0) = 0xf4; // Storage item added - WFIFOW(s, 2) = index + 1; // index - WFIFOL(s, 4) = amount; // amount -/* if ((view = itemdb_viewid(stor->storage_[index].nameid)) > 0) - WFIFOW(fd,8) =view; - else*/ - WFIFOW(s, 8) = stor->storage_[index].nameid; - WFIFOB(s, 10) = 0; //identify; - WFIFOB(s, 11) = 0; //broken or attribute; - WFIFOB(s, 12) = 0; //refine; + Packet_Fixed<0x00f4> fixed_f4; + fixed_f4.soff1 = index.shift(); + fixed_f4.amount = amount; + fixed_f4.name_id = stor->storage_[index].nameid; + fixed_f4.identify = 0; + fixed_f4.broken_or_attribute = 0; + fixed_f4.refine = 0; { - WFIFOW(s, 13) = 0; //card[0]; - WFIFOW(s, 15) = 0; //card[1]; - WFIFOW(s, 17) = 0; //card[2]; - WFIFOW(s, 19) = 0; //card[3]; + fixed_f4.card0 = 0; + fixed_f4.card1 = 0; + fixed_f4.card2 = 0; + fixed_f4.card3 = 0; } - WFIFOSET(s, clif_parse_func_table[0xf4].len); + send_fpacket<0x00f4, 21>(s, fixed_f4); return 0; } @@ -2303,16 +2307,16 @@ int clif_storageitemadded(dumb_ptr<map_session_data> sd, struct storage *stor, * カプラ倉庫からアイテムを取り去る *------------------------------------------ */ -int clif_storageitemremoved(dumb_ptr<map_session_data> sd, int index, +int clif_storageitemremoved(dumb_ptr<map_session_data> sd, SOff0 index, int amount) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xf6; // Storage item removed - WFIFOW(s, 2) = index + 1; - WFIFOL(s, 4) = amount; - WFIFOSET(s, clif_parse_func_table[0xf6].len); + Packet_Fixed<0x00f6> fixed_f6; + fixed_f6.soff1 = index.shift(); + fixed_f6.amount = amount; + send_fpacket<0x00f6, 8>(s, fixed_f6); return 0; } @@ -2323,11 +2327,11 @@ int clif_storageitemremoved(dumb_ptr<map_session_data> sd, int index, */ int clif_storageclose(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xf8; // Storage Closed - WFIFOSET(s, clif_parse_func_table[0xf8].len); + Packet_Fixed<0x00f8> fixed_f8; + send_fpacket<0x00f8, 2>(s, fixed_f8); return 0; } @@ -2335,7 +2339,7 @@ int clif_storageclose(dumb_ptr<map_session_data> sd) void clif_changelook_accessories(dumb_ptr<block_list> bl, dumb_ptr<map_session_data> dest) { - for (LOOK i = LOOK::SHOES; i < LOOK::COUNT; i = LOOK(uint8_t(i) + 1)) + for (LOOK i = LOOK::SHOES; i < LOOK::COUNT; i = LOOK(static_cast<uint8_t>(i) + 1)) clif_changelook_towards(bl, i, 0, dest); } @@ -2350,25 +2354,22 @@ static void clif_getareachar_pc(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> dstsd) { - int len; - if (bool(dstsd->status.option & Option::INVISIBILITY)) return; nullpo_retv(sd); nullpo_retv(dstsd); - uint8_t buf[256]; + Buffer buf; if (dstsd->walktimer) { - len = clif_set007b(dstsd, buf); + clif_set007b(dstsd, buf); } else { - len = clif_set0078(dstsd, buf); + clif_set0078_main_1d8(dstsd, buf); } - WFIFO_BUF_CLONE(sd->sess, buf, len); - WFIFOSET(sd->sess, len); + send_buffer(sd->sess, buf); if (battle_config.save_clothcolor == 1 && dstsd->status.clothes_color > 0) clif_changelook(dstsd, LOOK::CLOTHES_COLOR, @@ -2385,16 +2386,15 @@ void clif_getareachar_pc(dumb_ptr<map_session_data> sd, static void clif_getareachar_npc(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data> nd) { - int len; - nullpo_retv(sd); nullpo_retv(nd); - if (nd->npc_class < 0 || nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS) + if (nd->npc_class == NEGATIVE_SPECIES || nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS) return; - len = clif_npc0078(nd, static_cast<uint8_t *>(WFIFOP(sd->sess, 0))); - WFIFOSET(sd->sess, len); + Buffer buf; + clif_npc0078(nd, buf); + send_buffer(sd->sess, buf); } /*========================================== @@ -2403,13 +2403,11 @@ void clif_getareachar_npc(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data> nd) */ int clif_movemob(dumb_ptr<mob_data> md) { - unsigned char buf[256]; - int len; + nullpo_retz(md); - nullpo_ret(md); - - len = clif_mob007b(md, buf); - clif_send(buf, len, md, SendWho::AREA); + Buffer buf; + clif_mob007b(md, buf); + clif_send(buf, md, SendWho::AREA); return 0; } @@ -2420,20 +2418,19 @@ int clif_movemob(dumb_ptr<mob_data> md) */ int clif_fixmobpos(dumb_ptr<mob_data> md) { - unsigned char buf[256]; - int len; - - nullpo_ret(md); + nullpo_retz(md); if (md->state.state == MS::WALK) { - len = clif_mob007b(md, buf); - clif_send(buf, len, md, SendWho::AREA); + Buffer buf; + clif_mob007b(md, buf); + clif_send(buf, md, SendWho::AREA); } else { - len = clif_mob0078(md, buf); - clif_send(buf, len, md, SendWho::AREA); + Buffer buf; + clif_mob0078(md, buf); + clif_send(buf, md, SendWho::AREA); } return 0; @@ -2445,22 +2442,21 @@ int clif_fixmobpos(dumb_ptr<mob_data> md) */ int clif_fixpcpos(dumb_ptr<map_session_data> sd) { - unsigned char buf[256]; - int len; - - nullpo_ret(sd); + nullpo_retz(sd); if (sd->walktimer) { - len = clif_set007b(sd, buf); - clif_send(buf, len, sd, SendWho::AREA); + Buffer buf; + clif_set007b(sd, buf); + clif_send(buf, sd, SendWho::AREA); } else { - len = clif_set0078(sd, buf); - clif_send(buf, len, sd, SendWho::AREA); + Buffer buf; + clif_set0078_main_1d8(sd, buf); + clif_send(buf, sd, SendWho::AREA); } - clif_changelook_accessories(sd, NULL); + clif_changelook_accessories(sd, nullptr); return 0; } @@ -2473,25 +2469,25 @@ int clif_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst, tick_t tick, interval_t sdelay, interval_t ddelay, int damage, int div, DamageType type, int damage2) { - unsigned char buf[256]; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; - nullpo_ret(src); - nullpo_ret(dst); + nullpo_retz(src); + nullpo_retz(dst); sc_data = battle_get_sc_data(dst); - WBUFW(buf, 0) = 0x8a; - WBUFL(buf, 2) = src->bl_id; - WBUFL(buf, 6) = dst->bl_id; - WBUFL(buf, 10) = tick.time_since_epoch().count(); - WBUFL(buf, 14) = sdelay.count(); - WBUFL(buf, 18) = ddelay.count(); - WBUFW(buf, 22) = (damage > 0x7fff) ? 0x7fff : damage; - WBUFW(buf, 24) = div; - WBUFB(buf, 26) = static_cast<uint8_t>(type); - WBUFW(buf, 27) = damage2; - clif_send(buf, clif_parse_func_table[0x8a].len, src, SendWho::AREA); + Packet_Fixed<0x008a> fixed_8a; + fixed_8a.src_id = src->bl_id; + fixed_8a.dst_id = dst->bl_id; + fixed_8a.tick = tick; + fixed_8a.sdelay = sdelay; + fixed_8a.ddelay = ddelay; + fixed_8a.damage = (damage > 0x7fff) ? 0x7fff : damage; + fixed_8a.div = div; + fixed_8a.damage_type = type; + fixed_8a.damage2 = damage2; + Buffer buf = create_fpacket<0x008a, 29>(fixed_8a); + clif_send(buf, src, SendWho::AREA); return 0; } @@ -2503,19 +2499,20 @@ int clif_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst, static void clif_getareachar_mob(dumb_ptr<map_session_data> sd, dumb_ptr<mob_data> md) { - int len; nullpo_retv(sd); nullpo_retv(md); if (md->state.state == MS::WALK) { - len = clif_mob007b(md, static_cast<uint8_t *>(WFIFOP(sd->sess, 0))); - WFIFOSET(sd->sess, len); + Buffer buf; + clif_mob007b(md, buf); + send_buffer(sd->sess, buf); } else { - len = clif_mob0078(md, static_cast<uint8_t *>(WFIFOP(sd->sess, 0))); - WFIFOSET(sd->sess, len); + Buffer buf; + clif_mob0078(md, buf); + send_buffer(sd->sess, buf); } } @@ -2531,18 +2528,16 @@ void clif_getareachar_item(dumb_ptr<map_session_data> sd, nullpo_retv(fitem); Session *s = sd->sess; - //009d <ID>.l <item ID>.w <identify flag>.B <X>.w <Y>.w <amount>.w <subX>.B <subY>.B - WFIFOW(s, 0) = 0x9d; - WFIFOL(s, 2) = fitem->bl_id; - WFIFOW(s, 6) = fitem->item_data.nameid; - WFIFOB(s, 8) = 0; //identify; - WFIFOW(s, 9) = fitem->bl_x; - WFIFOW(s, 11) = fitem->bl_y; - WFIFOW(s, 13) = fitem->item_data.amount; - WFIFOB(s, 15) = fitem->subx; - WFIFOB(s, 16) = fitem->suby; - - WFIFOSET(s, clif_parse_func_table[0x9d].len); + Packet_Fixed<0x009d> fixed_9d; + fixed_9d.block_id = fitem->bl_id; + fixed_9d.name_id = fitem->item_data.nameid; + fixed_9d.identify = 0; + fixed_9d.x = fitem->bl_x; + fixed_9d.y = fitem->bl_y; + fixed_9d.amount = fitem->item_data.amount; + fixed_9d.subx = fitem->subx; + fixed_9d.suby = fitem->suby; + send_fpacket<0x009d, 17>(s, fixed_9d); } /*========================================== @@ -2578,7 +2573,7 @@ void clif_getareachar(dumb_ptr<block_list> bl, dumb_ptr<map_session_data> sd) break; default: if (battle_config.error_log) - PRINTF("get area char ??? %d\n", + PRINTF("get area char ??? %d\n"_fmt, bl->bl_type); break; } @@ -2694,32 +2689,32 @@ void clif_mobinsight(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md) int clif_skillinfo(dumb_ptr<map_session_data> sd, SkillID skillid, int type, int range) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; if (!sd->status.skill[skillid].lv) return 0; - WFIFOW(s, 0) = 0x147; - WFIFOW(s, 2) = static_cast<uint16_t>(skillid); + Packet_Fixed<0x0147> fixed_147; + fixed_147.info.skill_id = skillid; if (type < 0) - WFIFOW(s, 4) = skill_get_inf(skillid); + fixed_147.info.type_or_inf = skill_get_inf(skillid); else - WFIFOW(s, 4) = type; - WFIFOW(s, 6) = 0; - WFIFOW(s, 8) = sd->status.skill[skillid].lv; - WFIFOW(s, 10) = skill_get_sp(skillid, sd->status.skill[skillid].lv); + fixed_147.info.type_or_inf = type; + fixed_147.info.flags = SkillFlags::ZERO; + fixed_147.info.level = sd->status.skill[skillid].lv; + fixed_147.info.sp = skill_get_sp(skillid, sd->status.skill[skillid].lv); if (range < 0) { range = skill_get_range(skillid, sd->status.skill[skillid].lv); if (range < 0) range = battle_get_range(sd) - (range + 1); - WFIFOW(s, 12) = range; + fixed_147.info.range = range; } else - WFIFOW(s, 12) = range; - WFIFO_ZERO(s, 14, 24); - WFIFOB(s, 38) = sd->status.skill[skillid].lv < skill_get_max_raise(skillid); - WFIFOSET(s, clif_parse_func_table[0x147].len); + fixed_147.info.range = range; + fixed_147.info.unused = ""_s; + fixed_147.info.can_raise = sd->status.skill[skillid].lv < skill_get_max_raise(skillid); + send_fpacket<0x0147, 39>(s, fixed_147); return 0; } @@ -2730,35 +2725,34 @@ int clif_skillinfo(dumb_ptr<map_session_data> sd, SkillID skillid, int type, */ void clif_skillinfoblock(dumb_ptr<map_session_data> sd) { - int len = 4, range; - nullpo_retv(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0x10f; + std::vector<Packet_Repeat<0x010f>> repeat_10f; for (SkillID i : erange(SkillID(), MAX_SKILL)) { if (sd->status.skill[i].lv && sd->tmw_version >= 1) { + Packet_Repeat<0x010f> info; // [Fate] Version 1 and later don't crash because of bad skill IDs anymore - WFIFOW(s, len) = static_cast<uint16_t>(i); - WFIFOW(s, len + 2) = skill_get_inf(i); - WFIFOW(s, len + 4) = static_cast<uint16_t>( + info.info.skill_id = i; + info.info.type_or_inf = skill_get_inf(i); + info.info.flags = ( skill_db[i].poolflags | (sd->status.skill[i].flags & SkillFlags::POOL_ACTIVATED)); - WFIFOW(s, len + 6) = sd->status.skill[i].lv; - WFIFOW(s, len + 8) = skill_get_sp(i, sd->status.skill[i].lv); - range = skill_get_range(i, sd->status.skill[i].lv); + info.info.level = sd->status.skill[i].lv; + info.info.sp = skill_get_sp(i, sd->status.skill[i].lv); + int range = skill_get_range(i, sd->status.skill[i].lv); if (range < 0) range = battle_get_range(sd) - (range + 1); - WFIFOW(s, len + 10) = range; - WFIFO_ZERO(s, len + 12, 24); - WFIFOB(s, len + 36) = sd->status.skill[i].lv < skill_get_max_raise(i); - len += 37; + info.info.range = range; + info.info.unused = ""_s; + info.info.can_raise = sd->status.skill[i].lv < skill_get_max_raise(i); + + repeat_10f.push_back(info); } } - WFIFOW(s, 2) = len; - WFIFOSET(s, len); + send_packet_repeatonly<0x010f, 4, 37>(s, repeat_10f); } /*========================================== @@ -2767,21 +2761,19 @@ void clif_skillinfoblock(dumb_ptr<map_session_data> sd) */ int clif_skillup(dumb_ptr<map_session_data> sd, SkillID skill_num) { - int range; - - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0x10e; - WFIFOW(s, 2) = uint16_t(skill_num); - WFIFOW(s, 4) = sd->status.skill[skill_num].lv; - WFIFOW(s, 6) = skill_get_sp(skill_num, sd->status.skill[skill_num].lv); - range = skill_get_range(skill_num, sd->status.skill[skill_num].lv); + Packet_Fixed<0x010e> fixed_10e; + fixed_10e.skill_id = skill_num; + fixed_10e.level = sd->status.skill[skill_num].lv; + fixed_10e.sp = skill_get_sp(skill_num, sd->status.skill[skill_num].lv); + int range = skill_get_range(skill_num, sd->status.skill[skill_num].lv); if (range < 0) range = battle_get_range(sd) - (range + 1); - WFIFOW(s, 8) = range; - WFIFOB(s, 10) = sd->status.skill[skill_num].lv < skill_get_max_raise(skill_num); - WFIFOSET(s, clif_parse_func_table[0x10e].len); + fixed_10e.range = range; + fixed_10e.can_raise = sd->status.skill[skill_num].lv < skill_get_max_raise(skill_num); + send_fpacket<0x010e, 11>(s, fixed_10e); return 0; } @@ -2792,14 +2784,11 @@ int clif_skillup(dumb_ptr<map_session_data> sd, SkillID skill_num) */ int clif_skillcastcancel(dumb_ptr<block_list> bl) { - unsigned char buf[16]; - - nullpo_ret(bl); - - WBUFW(buf, 0) = 0x1b9; - WBUFL(buf, 2) = bl->bl_id; - clif_send(buf, clif_parse_func_table[0x1b9].len, bl, SendWho::AREA); + // packet 0x01b9 was being sent with length 0, + // even though there were 6 bytes involved + // and the client ignores it anyway + (void)bl; return 0; } @@ -2810,7 +2799,7 @@ int clif_skillcastcancel(dumb_ptr<block_list> bl) int clif_skill_fail(dumb_ptr<map_session_data> sd, SkillID skill_id, int type, int btype) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; @@ -2819,13 +2808,13 @@ int clif_skill_fail(dumb_ptr<map_session_data> sd, SkillID skill_id, int type, return 0; } - WFIFOW(s, 0) = 0x110; - WFIFOW(s, 2) = uint16_t(skill_id); - WFIFOW(s, 4) = btype; - WFIFOW(s, 6) = 0; - WFIFOB(s, 8) = 0; - WFIFOB(s, 9) = type; - WFIFOSET(s, clif_parse_func_table[0x110].len); + Packet_Fixed<0x0110> fixed_110; + fixed_110.skill_id = skill_id; + fixed_110.btype = btype; + fixed_110.zero1 = 0; + fixed_110.zero2 = 0; + fixed_110.type = type; + send_fpacket<0x0110, 10>(s, fixed_110); return 0; } @@ -2838,26 +2827,26 @@ int clif_skill_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst, tick_t tick, interval_t sdelay, interval_t ddelay, int damage, int div, SkillID skill_id, int skill_lv, int type) { - unsigned char buf[64]; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; - nullpo_ret(src); - nullpo_ret(dst); + nullpo_retz(src); + nullpo_retz(dst); sc_data = battle_get_sc_data(dst); - WBUFW(buf, 0) = 0x1de; - WBUFW(buf, 2) = uint16_t(skill_id); - WBUFL(buf, 4) = src->bl_id; - WBUFL(buf, 8) = dst->bl_id; - WBUFL(buf, 12) = static_cast<uint32_t>(tick.time_since_epoch().count()); - WBUFL(buf, 16) = static_cast<uint32_t>(sdelay.count()); - WBUFL(buf, 20) = static_cast<uint32_t>(ddelay.count()); - WBUFL(buf, 24) = damage; - WBUFW(buf, 28) = skill_lv; - WBUFW(buf, 30) = div; - WBUFB(buf, 32) = (type > 0) ? type : skill_get_hit(skill_id); - clif_send(buf, clif_parse_func_table[0x1de].len, src, SendWho::AREA); + Packet_Fixed<0x01de> fixed_1de; + fixed_1de.skill_id = skill_id; + fixed_1de.src_id = src->bl_id; + fixed_1de.dst_id = dst->bl_id; + fixed_1de.tick = tick; + fixed_1de.sdelay = sdelay; + fixed_1de.ddelay = ddelay; + fixed_1de.damage = damage; + fixed_1de.skill_level = skill_lv; + fixed_1de.div = div; + fixed_1de.type_or_hit = (type > 0) ? type : skill_get_hit(skill_id); + Buffer buf = create_fpacket<0x01de, 33>(fixed_1de); + clif_send(buf, src, SendWho::AREA); return 0; } @@ -2868,15 +2857,14 @@ int clif_skill_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst, */ int clif_status_change(dumb_ptr<block_list> bl, StatusChange type, int flag) { - unsigned char buf[16]; - - nullpo_ret(bl); + nullpo_retz(bl); - WBUFW(buf, 0) = 0x0196; - WBUFW(buf, 2) = uint16_t(type); - WBUFL(buf, 4) = bl->bl_id; - WBUFB(buf, 8) = flag; - clif_send(buf, clif_parse_func_table[0x196].len, bl, SendWho::AREA); + Packet_Fixed<0x0196> fixed_196; + fixed_196.sc_type = type; + fixed_196.block_id = bl->bl_id; + fixed_196.flag = flag; + Buffer buf = create_fpacket<0x0196, 9>(fixed_196); + clif_send(buf, bl, SendWho::AREA); return 0; } @@ -2889,11 +2877,8 @@ void clif_displaymessage(Session *s, XString mes) if (mes) { // don't send a void message (it's not displaying on the client chat). @help can send void line. - WFIFOW(s, 0) = 0x8e; - size_t str_len = mes.size() + 1; // NUL (might not be NUL yet) - WFIFOW(s, 2) = 4 + str_len; - WFIFO_STRING(s, 4, mes, str_len); - WFIFOSET(s, 4 + str_len); + // This is untrue now ^ + send_packet_repeatonly<0x008e, 4, 1>(s, mes); } } @@ -2903,14 +2888,9 @@ void clif_displaymessage(Session *s, XString mes) */ void clif_GMmessage(dumb_ptr<block_list> bl, XString mes, int flag) { - size_t str_len = mes.size() + 1; - unsigned char buf[str_len + 4]; - - WBUFW(buf, 0) = 0x9a; - WBUFW(buf, 2) = str_len + 4; - WBUF_STRING(buf, 4, mes, str_len); + Buffer buf = create_packet_repeatonly<0x009a, 4, 1>(mes); flag &= 0x07; - clif_send(buf, WBUFW(buf, 2), bl, + clif_send(buf, bl, (flag == 1) ? SendWho::ALL_SAMEMAP : (flag == 2) ? SendWho::AREA : (flag == 3) ? SendWho::SELF : @@ -2923,15 +2903,14 @@ void clif_GMmessage(dumb_ptr<block_list> bl, XString mes, int flag) */ void clif_resurrection(dumb_ptr<block_list> bl, int type) { - uint8_t buf[16]; - nullpo_retv(bl); - WBUFW(buf, 0) = 0x148; - WBUFL(buf, 2) = bl->bl_id; - WBUFW(buf, 6) = type; + Packet_Fixed<0x0148> fixed_148; + fixed_148.block_id = bl->bl_id; + fixed_148.type = type; + Buffer buf = create_fpacket<0x0148, 8>(fixed_148); - clif_send(buf, clif_parse_func_table[0x148].len, bl, + clif_send(buf, bl, type == 1 ? SendWho::AREA : SendWho::AREA_WOS); } @@ -2941,12 +2920,9 @@ void clif_resurrection(dumb_ptr<block_list> bl, int type) */ void clif_wis_message(Session *s, CharName nick, XString mes) // R 0097 <len>.w <nick>.24B <message>.?B { - size_t mes_len = mes.size() + 1; - WFIFOW(s, 0) = 0x97; - WFIFOW(s, 2) = mes_len + 24 + 4; - WFIFO_STRING(s, 4, nick.to__actual(), 24); - WFIFO_STRING(s, 28, mes, mes_len); - WFIFOSET(s, WFIFOW(s, 2)); + Packet_Head<0x0097> head_97; + head_97.char_name = nick; + send_vpacket<0x0097, 28, 1>(s, head_97, mes); } /*========================================== @@ -2955,9 +2931,9 @@ void clif_wis_message(Session *s, CharName nick, XString mes) // R 0097 <len>. */ void clif_wis_end(Session *s, int flag) // R 0098 <type>.B: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target { - WFIFOW(s, 0) = 0x98; - WFIFOW(s, 2) = flag; - WFIFOSET(s, clif_parse_func_table[0x98].len); + Packet_Fixed<0x0098> fixed_98; + fixed_98.flag = flag; + send_fpacket<0x0098, 3>(s, fixed_98); } /*========================================== @@ -2974,12 +2950,12 @@ void clif_wis_end(Session *s, int flag) // R 0098 <type>.B: 0: success to send w */ int clif_party_created(dumb_ptr<map_session_data> sd, int flag) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xfa; - WFIFOB(s, 2) = flag; - WFIFOSET(s, clif_parse_func_table[0xfa].len); + Packet_Fixed<0x00fa> fixed_fa; + fixed_fa.flag = flag; + send_fpacket<0x00fa, 3>(s, fixed_fa); return 0; } @@ -2987,43 +2963,45 @@ int clif_party_created(dumb_ptr<map_session_data> sd, int flag) * パーティ情報送信 *------------------------------------------ */ -int clif_party_info(struct party *p, Session *s) +int clif_party_info(PartyPair p, Session *s) { - unsigned char buf[1024]; - int i, c; - dumb_ptr<map_session_data> sd = NULL; + int i; + dumb_ptr<map_session_data> sd = nullptr; - nullpo_ret(p); + nullpo_retz(p); - WBUFW(buf, 0) = 0xfb; - WBUF_STRING(buf, 4, p->name, 24); - for (i = c = 0; i < MAX_PARTY; i++) + Packet_Head<0x00fb> head_fb; + std::vector<Packet_Repeat<0x00fb>> repeat_fb; + head_fb.party_name = p->name; + for (i = 0; i < MAX_PARTY; i++) { - struct party_member *m = &p->member[i]; - if (m->account_id > 0) + PartyMember *m = &p->member[i]; + if (m->account_id) { - if (sd == NULL) + Packet_Repeat<0x00fb> info; + if (sd == nullptr) sd = dumb_ptr<map_session_data>(m->sd); - WBUFL(buf, 28 + c * 46) = m->account_id; - WBUF_STRING(buf, 28 + c * 46 + 4, m->name.to__actual(), 24); - WBUF_STRING(buf, 28 + c * 46 + 28, m->map, 16); - WBUFB(buf, 28 + c * 46 + 44) = (m->leader) ? 0 : 1; - WBUFB(buf, 28 + c * 46 + 45) = (m->online) ? 0 : 1; - c++; + + info.account_id = m->account_id; + info.char_name = m->name; + info.map_name = m->map; + info.leader = (m->leader) ? 0 : 1; + info.online = (m->online) ? 0 : 1; + repeat_fb.push_back(info); } } - size_t len = 28 + c * 46; - WBUFW(buf, 2) = len; if (s) { // If set, send only to fd. - WFIFO_BUF_CLONE(s, buf, len); - WFIFOSET(s, len); + send_vpacket<0x00fb, 28, 46>(s, head_fb, repeat_fb); return 9; } // else, send it to all the party, if they exist. - if (sd != NULL) - clif_send(buf, len, sd, SendWho::PARTY); + if (sd != nullptr) + { + Buffer buf = create_vpacket<0x00fb, 28, 46>(head_fb, repeat_fb); + clif_send(buf, sd, SendWho::PARTY); + } return 0; } @@ -3037,7 +3015,7 @@ int clif_party_info(struct party *p, Session *s) void clif_party_invite(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd) { - struct party *p; + PartyPair p; nullpo_retv(sd); nullpo_retv(tsd); @@ -3047,10 +3025,10 @@ void clif_party_invite(dumb_ptr<map_session_data> sd, if (!(p = party_search(sd->status.party_id))) return; - WFIFOW(s, 0) = 0xfe; - WFIFOL(s, 2) = sd->status_key.account_id; - WFIFO_STRING(s, 6, p->name, 24); - WFIFOSET(s, clif_parse_func_table[0xfe].len); + Packet_Fixed<0x00fe> fixed_fe; + fixed_fe.account_id = sd->status_key.account_id; + fixed_fe.party_name = p->name; + send_fpacket<0x00fe, 30>(s, fixed_fe); } /*========================================== @@ -3072,10 +3050,10 @@ void clif_party_inviteack(dumb_ptr<map_session_data> sd, CharName nick, int flag nullpo_retv(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xfd; - WFIFO_STRING(s, 2, nick.to__actual(), 24); - WFIFOB(s, 26) = flag; - WFIFOSET(s, clif_parse_func_table[0xfd].len); + Packet_Fixed<0x00fd> fixed_fd; + fixed_fd.char_name = nick; + fixed_fd.flag = flag; + send_fpacket<0x00fd, 27>(s, fixed_fd); } /*========================================== @@ -3085,32 +3063,30 @@ void clif_party_inviteack(dumb_ptr<map_session_data> sd, CharName nick, int flag * 0x100=一人にのみ送信 *------------------------------------------ */ -void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd, int flag) +void clif_party_option(PartyPair p, dumb_ptr<map_session_data> sd, int flag) { - unsigned char buf[16]; - nullpo_retv(p); -// if(battle_config.etc_log) -// PRINTF("clif_party_option: %d %d %d\n",p->exp,p->item,flag); - if (sd == NULL && flag == 0) + if (sd == nullptr && flag == 0) { int i; for (i = 0; i < MAX_PARTY; i++) - if ((sd = map_id2sd(p->member[i].account_id)) != NULL) + if ((sd = map_id2sd(account_to_block(p->member[i].account_id))) != nullptr) break; } - if (sd == NULL) + if (sd == nullptr) return; - WBUFW(buf, 0) = 0x101; - WBUFW(buf, 2) = ((flag & 0x01) ? 2 : p->exp); - WBUFW(buf, 4) = ((flag & 0x10) ? 2 : p->item); + Packet_Fixed<0x0101> fixed_101; + fixed_101.exp = ((flag & 0x01) ? 2 : p->exp); + fixed_101.item = ((flag & 0x10) ? 2 : p->item); if (flag == 0) - clif_send(buf, clif_parse_func_table[0x101].len, sd, SendWho::PARTY); + { + Buffer buf = create_fpacket<0x0101, 6>(fixed_101); + clif_send(buf, sd, SendWho::PARTY); + } else { - WFIFO_BUF_CLONE(sd->sess, buf, clif_parse_func_table[0x101].len); - WFIFOSET(sd->sess, clif_parse_func_table[0x101].len); + send_fpacket<0x0101, 6>(sd->sess, fixed_101); } } @@ -3118,35 +3094,36 @@ void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd, int flag) * パーティ脱退(脱退前に呼ぶこと) *------------------------------------------ */ -void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd, - int account_id, CharName name, int flag) +void clif_party_leaved(PartyPair p, dumb_ptr<map_session_data> sd, + AccountId account_id, CharName name, int flag) { - unsigned char buf[64]; int i; nullpo_retv(p); - WBUFW(buf, 0) = 0x105; - WBUFL(buf, 2) = account_id; - WBUF_STRING(buf, 6, name.to__actual(), 24); - WBUFB(buf, 30) = flag & 0x0f; + Packet_Fixed<0x0105> fixed_105; + fixed_105.account_id = account_id; + fixed_105.char_name = name; + fixed_105.flag = flag & 0x0f; if ((flag & 0xf0) == 0) { - if (sd == NULL) + if (sd == nullptr) for (i = 0; i < MAX_PARTY; i++) { sd = dumb_ptr<map_session_data>(p->member[i].sd); - if (sd != NULL) + if (sd != nullptr) break; } - if (sd != NULL) - clif_send(buf, clif_parse_func_table[0x105].len, sd, SendWho::PARTY); + if (sd != nullptr) + { + Buffer buf = create_fpacket<0x0105, 31>(fixed_105); + clif_send(buf, sd, SendWho::PARTY); + } } - else if (sd != NULL) + else if (sd != nullptr) { - WFIFO_BUF_CLONE(sd->sess, buf, clif_parse_func_table[0x105].len); - WFIFOSET(sd->sess, clif_parse_func_table[0x105].len); + send_fpacket<0x0105, 31>(sd->sess, fixed_105); } } @@ -3154,7 +3131,7 @@ void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd, * パーティメッセージ送信 *------------------------------------------ */ -void clif_party_message(struct party *p, int account_id, XString mes) +void clif_party_message(PartyPair p, AccountId account_id, XString mes) { // always set, but clang is not smart enough dumb_ptr<map_session_data> sd = nullptr; @@ -3165,18 +3142,15 @@ void clif_party_message(struct party *p, int account_id, XString mes) for (i = 0; i < MAX_PARTY; i++) { sd = dumb_ptr<map_session_data>(p->member[i].sd); - if (sd != NULL) + if (sd != nullptr) break; } - if (sd != NULL) + if (sd != nullptr) { - size_t len = mes.size() + 1; - unsigned char buf[len + 8]; - WBUFW(buf, 0) = 0x109; - WBUFW(buf, 2) = len + 8; - WBUFL(buf, 4) = account_id; - WBUF_STRING(buf, 8, mes, len); - clif_send(buf, len + 8, sd, SendWho::PARTY); + Packet_Head<0x0109> head_109; + head_109.account_id = account_id; + Buffer buf = create_vpacket<0x0109, 8, 1>(head_109, mes); + clif_send(buf, sd, SendWho::PARTY); } } @@ -3184,19 +3158,16 @@ void clif_party_message(struct party *p, int account_id, XString mes) * パーティ座標通知 *------------------------------------------ */ -int clif_party_xy(struct party *, dumb_ptr<map_session_data> sd) +int clif_party_xy(PartyPair , dumb_ptr<map_session_data> sd) { - unsigned char buf[16]; - - nullpo_ret(sd); + nullpo_retz(sd); - WBUFW(buf, 0) = 0x107; - WBUFL(buf, 2) = sd->status_key.account_id; - WBUFW(buf, 6) = sd->bl_x; - WBUFW(buf, 8) = sd->bl_y; - clif_send(buf, clif_parse_func_table[0x107].len, sd, SendWho::PARTY_SAMEMAP_WOS); -// if(battle_config.etc_log) -// PRINTF("clif_party_xy %d\n",sd->status_key.account_id); + Packet_Fixed<0x0107> fixed_107; + fixed_107.account_id = sd->status_key.account_id; + fixed_107.x = sd->bl_x; + fixed_107.y = sd->bl_y; + Buffer buf = create_fpacket<0x0107, 10>(fixed_107); + clif_send(buf, sd, SendWho::PARTY_SAMEMAP_WOS); return 0; } @@ -3204,20 +3175,17 @@ int clif_party_xy(struct party *, dumb_ptr<map_session_data> sd) * パーティHP通知 *------------------------------------------ */ -int clif_party_hp(struct party *, dumb_ptr<map_session_data> sd) +int clif_party_hp(PartyPair , dumb_ptr<map_session_data> sd) { - unsigned char buf[16]; - - nullpo_ret(sd); + nullpo_retz(sd); - WBUFW(buf, 0) = 0x106; - WBUFL(buf, 2) = sd->status_key.account_id; - WBUFW(buf, 6) = (sd->status.hp > 0x7fff) ? 0x7fff : sd->status.hp; - WBUFW(buf, 8) = + Packet_Fixed<0x0106> fixed_106; + fixed_106.account_id = sd->status_key.account_id; + fixed_106.hp = (sd->status.hp > 0x7fff) ? 0x7fff : sd->status.hp; + fixed_106.max_hp = (sd->status.max_hp > 0x7fff) ? 0x7fff : sd->status.max_hp; - clif_send(buf, clif_parse_func_table[0x106].len, sd, SendWho::PARTY_AREA_WOS); -// if(battle_config.etc_log) -// PRINTF("clif_party_hp %d\n",sd->status_key.account_id); + Buffer buf = create_fpacket<0x0106, 10>(fixed_106); + clif_send(buf, sd, SendWho::PARTY_AREA_WOS); return 0; } @@ -3227,18 +3195,18 @@ int clif_party_hp(struct party *, dumb_ptr<map_session_data> sd) */ int clif_movetoattack(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl) { - nullpo_ret(sd); - nullpo_ret(bl); + nullpo_retz(sd); + nullpo_retz(bl); Session *s = sd->sess; - WFIFOW(s, 0) = 0x139; - WFIFOL(s, 2) = bl->bl_id; - WFIFOW(s, 6) = bl->bl_x; - WFIFOW(s, 8) = bl->bl_y; - WFIFOW(s, 10) = sd->bl_x; - WFIFOW(s, 12) = sd->bl_y; - WFIFOW(s, 14) = sd->attackrange; - WFIFOSET(s, clif_parse_func_table[0x139].len); + Packet_Fixed<0x0139> fixed_139; + fixed_139.block_id = bl->bl_id; + fixed_139.bl_x = bl->bl_x; + fixed_139.bl_y = bl->bl_y; + fixed_139.sd_x = sd->bl_x; + fixed_139.sd_y = sd->bl_y; + fixed_139.range = sd->attackrange; + send_fpacket<0x0139, 16>(s, fixed_139); return 0; } @@ -3248,13 +3216,12 @@ int clif_movetoattack(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl) */ int clif_mvp_effect(dumb_ptr<map_session_data> sd) { - unsigned char buf[16]; + nullpo_retz(sd); - nullpo_ret(sd); - - WBUFW(buf, 0) = 0x10c; - WBUFL(buf, 2) = sd->bl_id; - clif_send(buf, clif_parse_func_table[0x10c].len, sd, SendWho::AREA); + Packet_Fixed<0x010c> fixed_10c; + fixed_10c.block_id = sd->bl_id; + Buffer buf = create_fpacket<0x010c, 6>(fixed_10c); + clif_send(buf, sd, SendWho::AREA); return 0; } @@ -3264,22 +3231,19 @@ int clif_mvp_effect(dumb_ptr<map_session_data> sd) */ void clif_emotion(dumb_ptr<block_list> bl, int type) { - unsigned char buf[8]; - nullpo_retv(bl); - WBUFW(buf, 0) = 0xc0; - WBUFL(buf, 2) = bl->bl_id; - WBUFB(buf, 6) = type; - clif_send(buf, clif_parse_func_table[0xc0].len, bl, SendWho::AREA); + Packet_Fixed<0x00c0> fixed_c0; + fixed_c0.block_id = bl->bl_id; + fixed_c0.type = type; + Buffer buf = create_fpacket<0x00c0, 7>(fixed_c0); + clif_send(buf, bl, SendWho::AREA); } static void clif_emotion_towards(dumb_ptr<block_list> bl, dumb_ptr<block_list> target, int type) { - unsigned char buf[8]; - int len = clif_parse_func_table[0xc0].len; dumb_ptr<map_session_data> sd = target->is_player(); nullpo_retv(bl); @@ -3288,12 +3252,11 @@ void clif_emotion_towards(dumb_ptr<block_list> bl, if (target->bl_type != BL::PC) return; - WBUFW(buf, 0) = 0xc0; - WBUFL(buf, 2) = bl->bl_id; - WBUFB(buf, 6) = type; + Packet_Fixed<0x00c0> fixed_c0; + fixed_c0.block_id = bl->bl_id; + fixed_c0.type = type; - WFIFO_BUF_CLONE(sd->sess, buf, len); - WFIFOSET(sd->sess, len); + send_fpacket<0x00c0, 7>(sd->sess, fixed_c0); } /*========================================== @@ -3302,14 +3265,13 @@ void clif_emotion_towards(dumb_ptr<block_list> bl, */ void clif_sitting(Session *, dumb_ptr<map_session_data> sd) { - unsigned char buf[64]; - nullpo_retv(sd); - WBUFW(buf, 0) = 0x8a; - WBUFL(buf, 2) = sd->bl_id; - WBUFB(buf, 26) = 2; - clif_send(buf, clif_parse_func_table[0x8a].len, sd, SendWho::AREA); + Packet_Fixed<0x008a> fixed_8a; + fixed_8a.src_id = sd->bl_id; + fixed_8a.damage_type = DamageType::SIT; + Buffer buf = create_fpacket<0x008a, 29>(fixed_8a); + clif_send(buf, sd, SendWho::AREA); } /*========================================== @@ -3317,30 +3279,30 @@ void clif_sitting(Session *, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -int clif_GM_kickack(dumb_ptr<map_session_data> sd, int id) +int clif_GM_kickack(dumb_ptr<map_session_data> sd, AccountId id) { - nullpo_ret(sd); + nullpo_retz(sd); Session *s = sd->sess; - WFIFOW(s, 0) = 0xcd; - WFIFOL(s, 2) = id; - WFIFOSET(s, clif_parse_func_table[0xcd].len); + Packet_Fixed<0x00cd> fixed_cd; + fixed_cd.account_id = id; + send_fpacket<0x00cd, 6>(s, fixed_cd); return 0; } static -void clif_parse_QuitGame(Session *s, dumb_ptr<map_session_data> sd); +void clif_do_quit_game(Session *s, dumb_ptr<map_session_data> sd); int clif_GM_kick(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd, int type) { - nullpo_ret(tsd); + nullpo_retz(tsd); if (type) clif_GM_kickack(sd, tsd->status_key.account_id); tsd->opt1 = Opt1::ZERO; tsd->opt2 = Opt2::ZERO; - clif_parse_QuitGame(tsd->sess, tsd); + clif_do_quit_game(tsd->sess, tsd); return 0; } @@ -3348,15 +3310,12 @@ int clif_GM_kick(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd, // displaying special effects (npcs, weather, etc) [Valaris] int clif_specialeffect(dumb_ptr<block_list> bl, int type, int flag) { - unsigned char buf[24]; - - nullpo_ret(bl); + nullpo_retz(bl); - WBUF_ZERO(buf, 0, clif_parse_func_table[0x19b].len); - - WBUFW(buf, 0) = 0x19b; - WBUFL(buf, 2) = bl->bl_id; - WBUFL(buf, 6) = type; + Packet_Fixed<0x019b> fixed_19b; + fixed_19b.block_id = bl->bl_id; + fixed_19b.type = type; + Buffer buf = create_fpacket<0x019b, 10>(fixed_19b); if (flag == 2) { @@ -3371,9 +3330,9 @@ int clif_specialeffect(dumb_ptr<block_list> bl, int type, int flag) } } else if (flag == 1) - clif_send(buf, clif_parse_func_table[0x19b].len, bl, SendWho::SELF); + clif_send(buf, bl, SendWho::SELF); else if (!flag) - clif_send(buf, clif_parse_func_table[0x19b].len, bl, SendWho::AREA); + clif_send(buf, bl, SendWho::AREA); return 0; @@ -3388,35 +3347,39 @@ int clif_specialeffect(dumb_ptr<block_list> bl, int type, int flag) *------------------------------------------ */ static -void clif_parse_WantToConnection(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_WantToConnection(Session *s, dumb_ptr<map_session_data> sd) { - int account_id; // account_id in the packet + AccountId account_id; // account_id in the packet if (sd) { if (battle_config.error_log) - PRINTF("clif_parse_WantToConnection : invalid request?\n"); - return; + PRINTF("clif_parse_WantToConnection : invalid request?\n"_fmt); + return RecvResult::Error; } - if (RFIFOW(s, 0) == 0x72) + Packet_Fixed<0x0072> fixed; + RecvResult rv = recv_fpacket<0x0072, 19>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + { - account_id = RFIFOL(s, 2); + account_id = fixed.account_id; } - else - return; // Not the auth packet - WFIFOL(s, 0) = account_id; - WFIFOSET(s, 4); + // formerly: account id + Packet_Payload<0x8000> special; + special.magic_packet_length = 4; + send_ppacket<0x8000>(s, special); // if same account already connected, we disconnect the 2 sessions - dumb_ptr<map_session_data> old_sd = map_id2sd(account_id); + dumb_ptr<map_session_data> old_sd = map_id2sd(account_to_block(account_id)); if (old_sd) { clif_authfail_fd(s, 2); // same id clif_authfail_fd(old_sd->sess, 2); // same id - PRINTF("clif_parse_WantToConnection: Double connection for account %d (sessions: #%d (new) and #%d (old)).\n", - account_id, s, old_sd->sess); + PRINTF("clif_parse_WantToConnection: Double connection for account %d (sessions: #%d (new) and #%d (old)).\n"_fmt, + account_id, s, old_sd->sess); } else { @@ -3424,16 +3387,16 @@ void clif_parse_WantToConnection(Session *s, dumb_ptr<map_session_data> sd) s->session_data.reset(sd.operator->()); sd->sess = s; - pc_setnewpc(sd, account_id, RFIFOL(s, 6), RFIFOL(s, 10), - tick_t(static_cast<interval_t>(RFIFOL(s, 14))), - static_cast<SEX>(RFIFOB(s, 18))); + pc_setnewpc(sd, account_id, fixed.char_id, fixed.login_id1, + fixed.client_tick, + fixed.sex); map_addiddb(sd); chrif_authreq(sd); } - return; + return RecvResult::Complete; } /*========================================== @@ -3442,12 +3405,15 @@ void clif_parse_WantToConnection(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_LoadEndAck(Session *, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_LoadEndAck(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + if (sd->bl_prev != nullptr) + return RecvResult::Error; - if (sd->bl_prev != NULL) - return; + Packet_Fixed<0x007d> fixed; + RecvResult rv = recv_fpacket<0x007d, 2>(s, fixed); + if (rv != RecvResult::Complete) + return rv; // 接続ok時 //clif_authok(); @@ -3494,7 +3460,7 @@ void clif_parse_LoadEndAck(Session *, dumb_ptr<map_session_data> sd) if (!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris] - sd->pvp_timer = Timer(gettick() + std::chrono::milliseconds(200), + sd->pvp_timer = Timer(gettick() + 200_ms, std::bind(pc_calc_pvprank_timer, ph::_1, ph::_2, sd->bl_id)); sd->pvp_rank = 0; @@ -3519,7 +3485,7 @@ void clif_parse_LoadEndAck(Session *, dumb_ptr<map_session_data> sd) clif_changeoption(sd); // broken equipment -// clif_changelook_accessories(sd, NULL); +// clif_changelook_accessories(sd, nullptr); map_foreachinarea(std::bind(clif_getareachar, ph::_1, sd), sd->bl_m, @@ -3529,6 +3495,8 @@ void clif_parse_LoadEndAck(Session *, dumb_ptr<map_session_data> sd) if (!sd->state.seen_motd) pc_show_motd(sd); + + return rv; } /*========================================== @@ -3536,13 +3504,18 @@ void clif_parse_LoadEndAck(Session *, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_TickSend(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_TickSend(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + Packet_Fixed<0x007e> fixed; + RecvResult rv = recv_fpacket<0x007e, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; - sd->client_tick = tick_t(static_cast<interval_t>(RFIFOL(s, 2))); - sd->server_tick = gettick(); + uint32_t client_tick = fixed.client_tick; + (void)client_tick; clif_servertick(sd); + + return rv; } /*========================================== @@ -3550,71 +3523,83 @@ void clif_parse_TickSend(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_WalkToXY(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_WalkToXY(Session *s, dumb_ptr<map_session_data> sd) { - int x, y; - - nullpo_retv(sd); + Packet_Fixed<0x0085> fixed; + RecvResult rv = recv_fpacket<0x0085, 5>(s, fixed); + if (rv != RecvResult::Complete) + return rv; if (pc_isdead(sd)) { clif_clearchar(sd, BeingRemoveWhy::DEAD); - return; + return rv; } - if (sd->npc_id != 0 || sd->state.storage_open) - return; + if (sd->npc_id || sd->state.storage_open) + return rv; if (sd->canmove_tick > gettick()) - return; + return rv; // ステータス異常やハイディング中(トンネルドライブ無)で動けない if (bool(sd->opt1) && sd->opt1 != (Opt1::_stone6)) - return; + return rv; if (sd->invincible_timer) pc_delinvincibletimer(sd); pc_stopattack(sd); - x = RFIFOB(s, 2) * 4 + (RFIFOB(s, 3) >> 6); - y = ((RFIFOB(s, 3) & 0x3f) << 4) + (RFIFOB(s, 4) >> 4); + int x = fixed.pos.x; + int y = fixed.pos.y; pc_walktoxy(sd, x, y); + return rv; } /*========================================== * *------------------------------------------ */ -void clif_parse_QuitGame(Session *s, dumb_ptr<map_session_data> sd) +static +RecvResult clif_parse_QuitGame(Session *s, dumb_ptr<map_session_data> sd) { - tick_t tick = gettick(); + Packet_Fixed<0x018a> fixed; + RecvResult rv = recv_fpacket<0x018a, 4>(s, fixed); + if (rv != RecvResult::Complete) + return rv; - nullpo_retv(sd); + clif_do_quit_game(s, sd); + return rv; +} + +void clif_do_quit_game(Session *s, dumb_ptr<map_session_data> sd) +{ + + tick_t tick = gettick(); - WFIFOW(s, 0) = 0x18b; + Packet_Fixed<0x018b> fixed_18b; if ((!pc_isdead(sd) && (sd->opt1 != Opt1::ZERO || sd->opt2 != Opt2::ZERO)) || (tick < sd->canact_tick)) { - WFIFOW(s, 2) = 1; - WFIFOSET(s, clif_parse_func_table[0x18b].len); + fixed_18b.okay = 1; + send_fpacket<0x018b, 4>(s, fixed_18b); return; } /* Rovert's prevent logout option fixed [Valaris] */ if (!battle_config.prevent_logout - || tick >= sd->canlog_tick + std::chrono::seconds(10)) + || tick >= sd->canlog_tick + 10_s) { clif_setwaitclose(s); - WFIFOW(s, 2) = 0; + fixed_18b.okay = 0; } else { - WFIFOW(s, 2) = 1; + fixed_18b.okay = 1; } - WFIFOSET(s, clif_parse_func_table[0x18b].len); - + send_fpacket<0x018b, 4>(s, fixed_18b); } /*========================================== @@ -3622,18 +3607,23 @@ void clif_parse_QuitGame(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd) { + Packet_Fixed<0x0094> fixed; + RecvResult rv = recv_fpacket<0x0094, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + dumb_ptr<block_list> bl; - int account_id; + BlockId account_id; - account_id = RFIFOL(s, 2); + account_id = fixed.block_id; bl = map_id2bl(account_id); - if (bl == NULL) - return; + if (bl == nullptr) + return rv; - WFIFOW(s, 0) = 0x95; - WFIFOL(s, 2) = account_id; + Packet_Fixed<0x0095> fixed_95; + fixed_95.block_id = account_id; switch (bl->bl_type) { @@ -3641,21 +3631,21 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd) { dumb_ptr<map_session_data> ssd = bl->is_player(); - nullpo_retv(ssd); + nullpo_retr(rv, ssd); if (ssd->state.shroud_active) - WFIFO_STRING(s, 6, "", 24); + fixed_95.char_name = CharName(); else - WFIFO_STRING(s, 6, ssd->status_key.name.to__actual(), 24); - WFIFOSET(s, clif_parse_func_table[0x95].len); + fixed_95.char_name = ssd->status_key.name; + send_fpacket<0x0095, 30>(s, fixed_95); - struct party *p = NULL; + PartyPair p; PartyName party_name; int send = 0; - if (ssd->status.party_id > 0 && (p = party_search(ssd->status.party_id)) != NULL) + if (ssd->status.party_id && (p = party_search(ssd->status.party_id))) { party_name = p->name; send = 1; @@ -3663,30 +3653,28 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd) if (send) { - WFIFOW(s, 0) = 0x195; - WFIFOL(s, 2) = account_id; - WFIFO_STRING(s, 6, party_name, 24); - WFIFO_STRING(s, 30, "", 24); - WFIFO_STRING(s, 54, "", 24); - WFIFO_STRING(s, 78, "", 24); // We send this value twice because the client expects it - WFIFOSET(s, clif_parse_func_table[0x195].len); - + Packet_Fixed<0x0195> fixed_195; + fixed_195.block_id = account_id; + fixed_195.party_name = party_name; + fixed_195.guild_name = ""_s; + fixed_195.guild_pos = ""_s; + fixed_195.guild_pos = ""_s; // We send this value twice because the client expects it + send_fpacket<0x0195, 102>(s, fixed_195); } - if (pc_isGM(sd) >= battle_config.hack_info_GM_level) + if (pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.hack_info_GM_level)))) { IP4Address ip = ssd->get_ip(); - WFIFOW(s, 0) = 0x20C; + Packet_Fixed<0x020c> fixed_20c; // Mask the IP using the char-server password if (battle_config.mask_ip_gms) ip = MD5_ip(ip); - WFIFOL(s, 2) = account_id; - WFIFOIP(s, 6) = ip; - WFIFOSET(s, clif_parse_func_table[0x20C].len); + fixed_20c.block_id = account_id; + fixed_20c.ip = ip; + send_fpacket<0x020c, 10>(s, fixed_20c); } - } break; case BL::NPC: @@ -3694,26 +3682,28 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd) NpcName name = bl->is_npc()->name; // [fate] elim hashed out/invisible names for the client auto it = std::find(name.begin(), name.end(), '#'); - WFIFO_STRING(s, 6, name.xislice_h(it), 24); - WFIFOSET(s, clif_parse_func_table[0x95].len); + fixed_95.char_name = stringish<CharName>(name.xislice_h(it)); + send_fpacket<0x0095, 30>(s, fixed_95); } break; case BL::MOB: { dumb_ptr<mob_data> md = bl->is_mob(); - nullpo_retv(md); + nullpo_retr(rv, md); - WFIFO_STRING(s, 6, md->name, 24); - WFIFOSET(s, clif_parse_func_table[0x95].len); + fixed_95.char_name = stringish<CharName>(md->name); + send_fpacket<0x0095, 30>(s, fixed_95); } break; default: if (battle_config.error_log) - PRINTF("clif_parse_GetCharNameRequest : bad type %d (%d)\n", + PRINTF("clif_parse_GetCharNameRequest : bad type %d (%d)\n"_fmt, bl->bl_type, account_id); break; } + + return rv; } /*========================================== @@ -3724,63 +3714,60 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_GlobalMessage(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_GlobalMessage(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + AString repeat; + RecvResult rv = recv_packet_repeatonly<0x008c, 4, 1>(s, repeat); + if (rv != RecvResult::Complete) + return rv; - AString mbuf = clif_validate_chat(sd, ChatType::Global); + AString mbuf = clif_validate_chat(sd, ChatType::Global, repeat); if (!mbuf) { - clif_displaymessage(s, "Your message could not be sent."); - return; + clif_displaymessage(s, "Your message could not be sent."_s); + return rv; } - if (is_atcommand(s, sd, mbuf, 0)) - return; + if (is_atcommand(s, sd, mbuf, GmLevel())) + return rv; if (!magic_message(sd, mbuf)) { /* Don't send chat that results in an automatic ban. */ if (tmw_CheckChatSpam(sd, mbuf)) { - clif_displaymessage(s, "Your message could not be sent."); - return; + clif_displaymessage(s, "Your message could not be sent."_s); + return rv; } /* It's not a spell/magic message, so send the message to others. */ - size_t mbuf_size = mbuf.size() + 1; - uint8_t sendbuf[mbuf_size + 8]; - WBUFW(sendbuf, 0) = 0x8d; - WBUFW(sendbuf, 2) = mbuf_size + 8; /* Header(2) + length(2) + ID(4). */ - WBUFL(sendbuf, 4) = sd->bl_id; - WBUF_STRING(sendbuf, 8, mbuf, mbuf_size); - - clif_send(sendbuf, mbuf_size + 8, sd, SendWho::AREA_CHAT_WOC); + Packet_Head<0x008d> head_8d; + head_8d.block_id = sd->bl_id; + XString repeat_8d = mbuf; + Buffer sendbuf = create_vpacket<0x008d, 8, 1>(head_8d, repeat_8d); + + clif_send(sendbuf, sd, SendWho::AREA_CHAT_WOC); } /* Send the message back to the speaker. */ - size_t len = RFIFOW(s, 2); - RFIFO_WFIFO_CLONE(s, s, len); - WFIFOW(s, 0) = 0x8e; - WFIFOSET(s, len); + send_packet_repeatonly<0x008e, 4, 1>(s, repeat); + + return rv; } void clif_message(dumb_ptr<block_list> bl, XString msg) { size_t msg_len = msg.size() + 1; - uint8_t buf[512]; - if (msg_len + 16 > 512) return; nullpo_retv(bl); - WBUFW(buf, 0) = 0x8d; - WBUFW(buf, 2) = msg_len + 8; - WBUFL(buf, 4) = bl->bl_id; - WBUF_STRING(buf, 8, msg, msg_len); + Packet_Head<0x008d> head_8d; + head_8d.block_id = bl->bl_id; + Buffer buf = create_vpacket<0x008d, 8, 1>(head_8d, msg); - clif_send(buf, WBUFW(buf, 2), bl, SendWho::AREA); + clif_send(buf, bl, SendWho::AREA); } /*========================================== @@ -3788,16 +3775,17 @@ void clif_message(dumb_ptr<block_list> bl, XString msg) *------------------------------------------ */ static -void clif_parse_ChangeDir(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_ChangeDir(Session *s, dumb_ptr<map_session_data> sd) { - unsigned char buf[64]; + Packet_Fixed<0x009b> fixed; + RecvResult rv = recv_fpacket<0x009b, 5>(s, fixed); + if (rv != RecvResult::Complete) + return rv; - nullpo_retv(sd); - - // RFIFOW(fd, 2) and WBUFW(buf, 6) are always 0 + // RFIFOW(fd,2) and WBUFW(buf,6) are always 0 // TODO perhaps we could use that to remove this hack? DIR dir; - uint8_t client_dir = RFIFOB(s, 4); + uint8_t client_dir = fixed.client_dir; // the client uses a diffenent direction enum ... ugh switch (client_dir) { @@ -3810,21 +3798,22 @@ void clif_parse_ChangeDir(Session *s, dumb_ptr<map_session_data> sd) case 0 | 8: dir = DIR::E; break; // right case 1 | 8: dir = DIR::SE; break; default: - return; + return rv; } if (dir == sd->dir) - return; + return rv; pc_setdir(sd, dir); - WBUFW(buf, 0) = 0x9c; - WBUFL(buf, 2) = sd->bl_id; - WBUFW(buf, 6) = 0; - WBUFB(buf, 8) = client_dir; + Packet_Fixed<0x009c> fixed_9c; + fixed_9c.block_id = sd->bl_id; + fixed_9c.client_dir = client_dir; + Buffer buf = create_fpacket<0x009c, 9>(fixed_9c); - clif_send(buf, clif_parse_func_table[0x9c].len, sd, SendWho::AREA_WOS); + clif_send(buf, sd, SendWho::AREA_WOS); + return rv; } /*========================================== @@ -3832,23 +3821,27 @@ void clif_parse_ChangeDir(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_Emotion(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_Emotion(Session *s, dumb_ptr<map_session_data> sd) { - unsigned char buf[64]; - - nullpo_retv(sd); + Packet_Fixed<0x00bf> fixed; + RecvResult rv = recv_fpacket<0x00bf, 3>(s, fixed); + if (rv != RecvResult::Complete) + return rv; if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, SkillID::NV_EMOTE) >= 1) { - uint8_t emote = RFIFOB(s, 2); - WBUFW(buf, 0) = 0xc0; - WBUFL(buf, 2) = sd->bl_id; - WBUFB(buf, 6) = emote; - clif_send(buf, clif_parse_func_table[0xc0].len, sd, SendWho::AREA); + uint8_t emote = fixed.emote; + Packet_Fixed<0x00c0> fixed_c0; + fixed_c0.block_id = sd->bl_id; + fixed_c0.type = emote; + Buffer buf = create_fpacket<0x00c0, 7>(fixed_c0); + clif_send(buf, sd, SendWho::AREA); } else clif_skill_fail(sd, SkillID::ONE, 0, 1); + + return rv; } /*========================================== @@ -3856,11 +3849,18 @@ void clif_parse_Emotion(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_HowManyConnections(Session *s, dumb_ptr<map_session_data>) +RecvResult clif_parse_HowManyConnections(Session *s, dumb_ptr<map_session_data>) { - WFIFOW(s, 0) = 0xc2; - WFIFOL(s, 2) = map_getusers(); - WFIFOSET(s, clif_parse_func_table[0xc2].len); + Packet_Fixed<0x00c1> fixed; + RecvResult rv = recv_fpacket<0x00c1, 2>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + Packet_Fixed<0x00c2> fixed_c2; + fixed_c2.users = map_getusers(); + send_fpacket<0x00c2, 6>(s, fixed_c2); + + return rv; } /*========================================== @@ -3868,64 +3868,69 @@ void clif_parse_HowManyConnections(Session *s, dumb_ptr<map_session_data>) *------------------------------------------ */ static -void clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd) { - unsigned char buf[64]; - int action_type, target_id; + Packet_Fixed<0x0089> fixed; + RecvResult rv = recv_fpacket<0x0089, 7>(s, fixed); + if (rv != RecvResult::Complete) + return rv; - nullpo_retv(sd); + DamageType action_type; + BlockId target_id; if (pc_isdead(sd)) { clif_clearchar(sd, BeingRemoveWhy::DEAD); - return; + return rv; } - if (sd->npc_id != 0 + if (sd->npc_id || bool(sd->opt1) || sd->state.storage_open) - return; + return rv; tick_t tick = gettick(); pc_stop_walking(sd, 0); pc_stopattack(sd); - target_id = RFIFOL(s, 2); - action_type = RFIFOB(s, 6); + target_id = fixed.target_id; + action_type = fixed.action; switch (action_type) { - case 0x00: // once attack - case 0x07: // continuous attack + case DamageType::NORMAL: + case DamageType::CONTINUOUS: if (bool(sd->status.option & Option::HIDE)) - return; + return rv; if (!battle_config.skill_delay_attack_enable) { if (tick < sd->canact_tick) { clif_skill_fail(sd, SkillID::ONE, 4, 0); - return; + return rv; } } if (sd->invincible_timer) pc_delinvincibletimer(sd); - if (sd->attacktarget > 0) // [Valaris] - sd->attacktarget = 0; - pc_attack(sd, target_id, action_type != 0); + sd->attacktarget = BlockId(); + pc_attack(sd, target_id, action_type != DamageType::NORMAL); break; - case 0x02: // sitdown + case DamageType::SIT: pc_stop_walking(sd, 1); pc_setsit(sd); clif_sitting(s, sd); break; - case 0x03: // standup + case DamageType::STAND: pc_setstand(sd); - WBUFW(buf, 0) = 0x8a; - WBUFL(buf, 2) = sd->bl_id; - WBUFB(buf, 26) = 3; - clif_send(buf, clif_parse_func_table[0x8a].len, sd, SendWho::AREA); + Packet_Fixed<0x008a> fixed_8a; + fixed_8a.src_id = sd->bl_id; + fixed_8a.damage_type = DamageType::STAND; + Buffer buf = create_fpacket<0x008a, 29>(fixed_8a); + clif_send(buf, sd, SendWho::AREA); break; } + + return rv; } /*========================================== @@ -3933,11 +3938,14 @@ void clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_Restart(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_Restart(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + Packet_Fixed<0x00b2> fixed; + RecvResult rv = recv_fpacket<0x00b2, 3>(s, fixed); + if (rv != RecvResult::Complete) + return rv; - switch (RFIFOB(s, 2)) + switch (fixed.flag) { case 0x00: if (pc_isdead(sd)) @@ -3961,19 +3969,21 @@ void clif_parse_Restart(Session *s, dumb_ptr<map_session_data> sd) case 0x01: /* Rovert's Prevent logout option - Fixed [Valaris] */ if (!battle_config.prevent_logout - || gettick() >= sd->canlog_tick + std::chrono::seconds(10)) + || gettick() >= sd->canlog_tick + 10_s) { chrif_charselectreq(sd); } else { - WFIFOW(s, 0) = 0x18b; - WFIFOW(s, 2) = 1; + Packet_Fixed<0x018b> fixed_18b; + fixed_18b.okay = 1; - WFIFOSET(s, clif_parse_func_table[0x018b].len); + send_fpacket<0x018b, 4>(s, fixed_18b); } break; } + + return rv; } /*========================================== @@ -3987,29 +3997,33 @@ void clif_parse_Restart(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd) { - dumb_ptr<map_session_data> dstsd = NULL; + Packet_Head<0x0096> head; + AString repeat; + RecvResult rv = recv_vpacket<0x0096, 28, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; - nullpo_retv(sd); + dumb_ptr<map_session_data> dstsd = nullptr; - AString mbuf = clif_validate_chat(sd, ChatType::Whisper); + AString mbuf = clif_validate_chat(sd, ChatType::Whisper, repeat); if (!mbuf) { - clif_displaymessage(s, "Your message could not be sent."); - return; + clif_displaymessage(s, "Your message could not be sent."_s); + return rv; } - if (is_atcommand(s, sd, mbuf, 0)) + if (is_atcommand(s, sd, mbuf, GmLevel())) { - return; + return rv; } /* Don't send chat that results in an automatic ban. */ if (tmw_CheckChatSpam(sd, mbuf)) { - clif_displaymessage(s, "Your message could not be sent."); - return; + clif_displaymessage(s, "Your message could not be sent."_s); + return rv; } /* @@ -4018,7 +4032,7 @@ void clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd) * conflict (for instance, "Test" versus "test"), the char-server must * settle the discrepancy. */ - CharName tname = stringish<CharName>(RFIFO_STRING<24>(s, 4)); + CharName tname = head.target_name; if (!(dstsd = map_nick2sd(tname)) || dstsd->status_key.name != tname) intif_wis_message(sd, tname, mbuf); @@ -4027,7 +4041,7 @@ void clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd) /* Refuse messages addressed to self. */ if (dstsd->sess == s) { - ZString mes = "You cannot page yourself."; + ZString mes = "You cannot page yourself."_s; clif_wis_message(s, wisp_server_name, mes); } else @@ -4042,6 +4056,8 @@ void clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd) } } } + + return rv; } /*========================================== @@ -4049,37 +4065,41 @@ void clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_TakeItem(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_TakeItem(Session *s, dumb_ptr<map_session_data> sd) { - dumb_ptr<flooritem_data> fitem; - int map_object_id; + Packet_Fixed<0x009f> fixed; + RecvResult rv = recv_fpacket<0x009f, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; - nullpo_retv(sd); + dumb_ptr<flooritem_data> fitem; - map_object_id = RFIFOL(s, 2); + BlockId map_object_id = fixed.object_id; fitem = map_id_is_item(map_object_id); if (pc_isdead(sd)) { clif_clearchar(sd, BeingRemoveWhy::DEAD); - return; + return rv; } - if (sd->npc_id != 0 + if (sd->npc_id || sd->opt1 != Opt1::ZERO) //会話禁止 - return; + return rv; - if (fitem == NULL || fitem->bl_m != sd->bl_m) - return; + if (fitem == nullptr || fitem->bl_m != sd->bl_m) + return rv; if (abs(sd->bl_x - fitem->bl_x) >= 2 || abs(sd->bl_y - fitem->bl_y) >= 2) - return; // too far away to pick up + return rv; // too far away to pick up if (sd->state.shroud_active && sd->state.shroud_disappears_on_pickup) magic_unshroud(sd); pc_takeitem(sd, fitem); + + return rv; } /*========================================== @@ -4087,33 +4107,38 @@ void clif_parse_TakeItem(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_DropItem(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_DropItem(Session *s, dumb_ptr<map_session_data> sd) { - int item_index, item_amount; - - nullpo_retv(sd); + Packet_Fixed<0x00a2> fixed; + RecvResult rv = recv_fpacket<0x00a2, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; if (pc_isdead(sd)) { clif_clearchar(sd, BeingRemoveWhy::DEAD); - return; + return rv; } if (sd->bl_m->flag.get(MapFlag::NO_PLAYER_DROPS)) { - clif_displaymessage(sd->sess, "Can't drop items here."); - return; + clif_displaymessage(sd->sess, "Can't drop items here."_s); + return rv; } - if (sd->npc_id != 0 + if (sd->npc_id || sd->opt1 != Opt1::ZERO) { - clif_displaymessage(sd->sess, "Can't drop items right now."); - return; + clif_displaymessage(sd->sess, "Can't drop items right now."_s); + return rv; } - item_index = RFIFOW(s, 2) - 2; - item_amount = RFIFOW(s, 4); + if (!fixed.ioff2.ok()) + return RecvResult::Error; + IOff0 item_index = fixed.ioff2.unshift(); + int item_amount = fixed.amount; pc_dropitem(sd, item_index, item_amount); + + return rv; } /*========================================== @@ -4121,23 +4146,30 @@ void clif_parse_DropItem(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_UseItem(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_UseItem(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + Packet_Fixed<0x00a7> fixed; + RecvResult rv = recv_fpacket<0x00a7, 8>(s, fixed); + if (rv != RecvResult::Complete) + return rv; if (pc_isdead(sd)) { clif_clearchar(sd, BeingRemoveWhy::DEAD); - return; + return rv; } - if (sd->npc_id != 0 + if (sd->npc_id || sd->opt1 != Opt1::ZERO) //会話禁止 - return; + return rv; if (sd->invincible_timer) pc_delinvincibletimer(sd); - pc_useitem(sd, RFIFOW(s, 2) - 2); + if (!fixed.ioff2.ok()) + return RecvResult::Error; + pc_useitem(sd, fixed.ioff2.unshift()); + + return rv; } /*========================================== @@ -4145,30 +4177,35 @@ void clif_parse_UseItem(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_EquipItem(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_EquipItem(Session *s, dumb_ptr<map_session_data> sd) { - int index; - - nullpo_retv(sd); + Packet_Fixed<0x00a9> fixed; + RecvResult rv = recv_fpacket<0x00a9, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; if (pc_isdead(sd)) { clif_clearchar(sd, BeingRemoveWhy::DEAD); - return; + return rv; } - index = RFIFOW(s, 2) - 2; - if (sd->npc_id != 0) - return; + if (!fixed.ioff2.ok()) + return RecvResult::Error; + IOff0 index = fixed.ioff2.unshift(); + if (sd->npc_id) + return rv; if (sd->inventory_data[index]) { - EPOS epos = EPOS(RFIFOW(s, 4)); + EPOS epos = fixed.epos_ignored; if (sd->inventory_data[index]->type == ItemType::ARROW) epos = EPOS::ARROW; // Note: the EPOS argument to pc_equipitem is actually ignored pc_equipitem(sd, index, epos); } + + return rv; } /*========================================== @@ -4176,23 +4213,28 @@ void clif_parse_EquipItem(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_UnequipItem(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_UnequipItem(Session *s, dumb_ptr<map_session_data> sd) { - int index; - - nullpo_retv(sd); + Packet_Fixed<0x00ab> fixed; + RecvResult rv = recv_fpacket<0x00ab, 4>(s, fixed); + if (rv != RecvResult::Complete) + return rv; if (pc_isdead(sd)) { clif_clearchar(sd, BeingRemoveWhy::DEAD); - return; + return rv; } - index = RFIFOW(s, 2) - 2; + if (!fixed.ioff2.ok()) + return RecvResult::Error; + IOff0 index = fixed.ioff2.unshift(); - if (sd->npc_id != 0 + if (sd->npc_id || sd->opt1 != Opt1::ZERO) - return; + return rv; pc_unequipitem(sd, index, CalcStatus::NOW); + + return rv; } /*========================================== @@ -4200,18 +4242,23 @@ void clif_parse_UnequipItem(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_NpcClicked(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_NpcClicked(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + Packet_Fixed<0x0090> fixed; + RecvResult rv = recv_fpacket<0x0090, 7>(s, fixed); + if (rv != RecvResult::Complete) + return rv; if (pc_isdead(sd)) { clif_clearchar(sd, BeingRemoveWhy::DEAD); - return; + return rv; } - if (sd->npc_id != 0) - return; - npc_click(sd, RFIFOL(s, 2)); + if (sd->npc_id) + return rv; + npc_click(sd, fixed.block_id); + + return rv; } /*========================================== @@ -4219,9 +4266,16 @@ void clif_parse_NpcClicked(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_NpcBuySellSelected(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_NpcBuySellSelected(Session *s, dumb_ptr<map_session_data> sd) { - npc_buysellsel(sd, RFIFOL(s, 2), RFIFOB(s, 6)); + Packet_Fixed<0x00c5> fixed; + RecvResult rv = recv_fpacket<0x00c5, 7>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + npc_buysellsel(sd, fixed.block_id, fixed.type); + + return rv; } /*========================================== @@ -4229,17 +4283,20 @@ void clif_parse_NpcBuySellSelected(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_NpcBuyListSend(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_NpcBuyListSend(Session *s, dumb_ptr<map_session_data> sd) { - int n = (RFIFOW(s, 2) - 4) / 4; - // really an array of pairs of uint16_t - const uint16_t *item_list = static_cast<const uint16_t *>(RFIFOP(s, 4)); + std::vector<Packet_Repeat<0x00c8>> repeat; + RecvResult rv = recv_packet_repeatonly<0x00c8, 4, 4>(s, repeat); + if (rv != RecvResult::Complete) + return rv; - int fail = npc_buylist(sd, n, item_list); + int fail = npc_buylist(sd, repeat); - WFIFOW(s, 0) = 0xca; - WFIFOB(s, 2) = fail; - WFIFOSET(s, clif_parse_func_table[0xca].len); + Packet_Fixed<0x00ca> fixed_ca; + fixed_ca.fail = fail; + send_fpacket<0x00ca, 3>(s, fixed_ca); + + return rv; } /*========================================== @@ -4247,17 +4304,20 @@ void clif_parse_NpcBuyListSend(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_NpcSellListSend(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_NpcSellListSend(Session *s, dumb_ptr<map_session_data> sd) { - int n = (RFIFOW(s, 2) - 4) / 4; - // really an array of pairs of uint16_t - const uint16_t *item_list = static_cast<const uint16_t *>(RFIFOP(s, 4)); + std::vector<Packet_Repeat<0x00c9>> repeat; + RecvResult rv = recv_packet_repeatonly<0x00c9, 4, 4>(s, repeat); + if (rv != RecvResult::Complete) + return rv; + + int fail = npc_selllist(sd, repeat); - int fail = npc_selllist(sd, n, item_list); + Packet_Fixed<0x00cb> fixed_cb; + fixed_cb.fail = fail; + send_fpacket<0x00cb, 3>(s, fixed_cb); - WFIFOW(s, 0) = 0xcb; - WFIFOB(s, 2) = fail; - WFIFOSET(s, clif_parse_func_table[0xcb].len); + return rv; } /*========================================== @@ -4265,17 +4325,22 @@ void clif_parse_NpcSellListSend(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_TradeRequest(Session *, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_TradeRequest(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + Packet_Fixed<0x00e4> fixed; + RecvResult rv = recv_fpacket<0x00e4, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, SkillID::NV_TRADE) >= 1) { - trade_traderequest(sd, RFIFOL(sd->sess, 2)); + trade_traderequest(sd, fixed.block_id); } else clif_skill_fail(sd, SkillID::ONE, 0, 0); + + return rv; } /*========================================== @@ -4283,11 +4348,16 @@ void clif_parse_TradeRequest(Session *, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_TradeAck(Session *, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_TradeAck(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + Packet_Fixed<0x00e6> fixed; + RecvResult rv = recv_fpacket<0x00e6, 3>(s, fixed); + if (rv != RecvResult::Complete) + return rv; - trade_tradeack(sd, RFIFOB(sd->sess, 2)); + trade_tradeack(sd, fixed.type); + + return rv; } /*========================================== @@ -4295,11 +4365,18 @@ void clif_parse_TradeAck(Session *, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_TradeAddItem(Session *, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_TradeAddItem(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + Packet_Fixed<0x00e8> fixed; + RecvResult rv = recv_fpacket<0x00e8, 8>(s, fixed); + if (rv != RecvResult::Complete) + return rv; - trade_tradeadditem(sd, RFIFOW(sd->sess, 2), RFIFOL(sd->sess, 4)); + if (fixed.zeny_or_ioff2.index != 0 && !fixed.zeny_or_ioff2.ok()) + return RecvResult::Error; + trade_tradeadditem(sd, fixed.zeny_or_ioff2, fixed.amount); + + return rv; } /*========================================== @@ -4307,9 +4384,16 @@ void clif_parse_TradeAddItem(Session *, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_TradeOk(Session *, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_TradeOk(Session *s, dumb_ptr<map_session_data> sd) { + Packet_Fixed<0x00eb> fixed; + RecvResult rv = recv_fpacket<0x00eb, 2>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + trade_tradeok(sd); + + return rv; } /*========================================== @@ -4317,9 +4401,16 @@ void clif_parse_TradeOk(Session *, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_TradeCansel(Session *, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_TradeCansel(Session *s, dumb_ptr<map_session_data> sd) { + Packet_Fixed<0x00ed> fixed; + RecvResult rv = recv_fpacket<0x00ed, 2>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + trade_tradecancel(sd); + + return rv; } /*========================================== @@ -4327,9 +4418,16 @@ void clif_parse_TradeCansel(Session *, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_TradeCommit(Session *, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_TradeCommit(Session *s, dumb_ptr<map_session_data> sd) { + Packet_Fixed<0x00ef> fixed; + RecvResult rv = recv_fpacket<0x00ef, 2>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + trade_tradecommit(sd); + + return rv; } /*========================================== @@ -4337,9 +4435,16 @@ void clif_parse_TradeCommit(Session *, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_StopAttack(Session *, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_StopAttack(Session *s, dumb_ptr<map_session_data> sd) { + Packet_Fixed<0x0118> fixed; + RecvResult rv = recv_fpacket<0x0118, 2>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + pc_stopattack(sd); + + return rv; } /*========================================== @@ -4347,9 +4452,16 @@ void clif_parse_StopAttack(Session *, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_StatusUp(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_StatusUp(Session *s, dumb_ptr<map_session_data> sd) { - pc_statusup(sd, SP(RFIFOW(s, 2))); + Packet_Fixed<0x00bb> fixed; + RecvResult rv = recv_fpacket<0x00bb, 5>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + pc_statusup(sd, fixed.asp); + + return rv; } /*========================================== @@ -4357,9 +4469,16 @@ void clif_parse_StatusUp(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_SkillUp(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_SkillUp(Session *s, dumb_ptr<map_session_data> sd) { - pc_skillup(sd, SkillID(RFIFOW(s, 2))); + Packet_Fixed<0x0112> fixed; + RecvResult rv = recv_fpacket<0x0112, 4>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + pc_skillup(sd, fixed.skill_id); + + return rv; } /*========================================== @@ -4367,12 +4486,17 @@ void clif_parse_SkillUp(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_NpcSelectMenu(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_NpcSelectMenu(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + Packet_Fixed<0x00b8> fixed; + RecvResult rv = recv_fpacket<0x00b8, 7>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + sd->npc_menu = fixed.menu_entry; + map_scriptcont(sd, fixed.npc_id); - sd->npc_menu = RFIFOB(s, 6); - map_scriptcont(sd, RFIFOL(s, 2)); + return rv; } /*========================================== @@ -4380,9 +4504,16 @@ void clif_parse_NpcSelectMenu(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_NpcNextClicked(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_NpcNextClicked(Session *s, dumb_ptr<map_session_data> sd) { - map_scriptcont(sd, RFIFOL(s, 2)); + Packet_Fixed<0x00b9> fixed; + RecvResult rv = recv_fpacket<0x00b9, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + map_scriptcont(sd, fixed.npc_id); + + return rv; } /*========================================== @@ -4390,12 +4521,17 @@ void clif_parse_NpcNextClicked(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_NpcAmountInput(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_NpcAmountInput(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + Packet_Fixed<0x0143> fixed; + RecvResult rv = recv_fpacket<0x0143, 10>(s, fixed); + if (rv != RecvResult::Complete) + return rv; - sd->npc_amount = RFIFOL(s, 6); - map_scriptcont(sd, RFIFOL(s, 2)); + sd->npc_amount = fixed.input_int_value; + map_scriptcont(sd, fixed.block_id); + + return rv; } /*========================================== @@ -4405,22 +4541,19 @@ void clif_parse_NpcAmountInput(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_NpcStringInput(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_NpcStringInput(Session *s, dumb_ptr<map_session_data> sd) { - int len; - nullpo_retv(sd); + Packet_Head<0x01d5> head; + AString repeat; + RecvResult rv = recv_vpacket<0x01d5, 8, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; - len = RFIFOW(s, 2) - 8; + sd->npc_str = repeat; - /* - * If we check for equal to 0, too, we'll freeze clients that send (or - * claim to have sent) an "empty" message. - */ - if (len < 0) - return; - sd->npc_str = RFIFO_STRING(s, 8, len); + map_scriptcont(sd, head.block_id); - map_scriptcont(sd, RFIFOL(s, 4)); + return rv; } /*========================================== @@ -4428,9 +4561,16 @@ void clif_parse_NpcStringInput(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_NpcCloseClicked(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_NpcCloseClicked(Session *s, dumb_ptr<map_session_data> sd) { - map_scriptcont(sd, RFIFOL(s, 2)); + Packet_Fixed<0x0146> fixed; + RecvResult rv = recv_fpacket<0x0146, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + map_scriptcont(sd, fixed.block_id); + + return rv; } /*========================================== @@ -4438,21 +4578,26 @@ void clif_parse_NpcCloseClicked(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_MoveToKafra(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_MoveToKafra(Session *s, dumb_ptr<map_session_data> sd) { - int item_index, item_amount; + Packet_Fixed<0x00f3> fixed; + RecvResult rv = recv_fpacket<0x00f3, 8>(s, fixed); + if (rv != RecvResult::Complete) + return rv; - nullpo_retv(sd); - - item_index = RFIFOW(s, 2) - 2; - item_amount = RFIFOL(s, 4); + if (!fixed.ioff2.ok()) + return RecvResult::Error; + IOff0 item_index = fixed.ioff2.unshift(); + int item_amount = fixed.amount; - if ((sd->npc_id != 0 && !sd->npc_flags.storage) || sd->trade_partner != 0 + if ((sd->npc_id && !sd->npc_flags.storage) || sd->trade_partner || !sd->state.storage_open) - return; + return rv; if (sd->state.storage_open) storage_storageadd(sd, item_index, item_amount); + + return rv; } /*========================================== @@ -4460,21 +4605,26 @@ void clif_parse_MoveToKafra(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_MoveFromKafra(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_MoveFromKafra(Session *s, dumb_ptr<map_session_data> sd) { - int item_index, item_amount; - - nullpo_retv(sd); + Packet_Fixed<0x00f5> fixed; + RecvResult rv = recv_fpacket<0x00f5, 8>(s, fixed); + if (rv != RecvResult::Complete) + return rv; - item_index = RFIFOW(s, 2) - 1; - item_amount = RFIFOL(s, 4); + if (!fixed.soff1.ok()) + return RecvResult::Error; + SOff0 item_index = fixed.soff1.unshift(); + int item_amount = fixed.amount; - if ((sd->npc_id != 0 && !sd->npc_flags.storage) || sd->trade_partner != 0 + if ((sd->npc_id && !sd->npc_flags.storage) || sd->trade_partner || !sd->state.storage_open) - return; + return rv; if (sd->state.storage_open) storage_storageget(sd, item_index, item_amount); + + return rv; } /*========================================== @@ -4482,12 +4632,17 @@ void clif_parse_MoveFromKafra(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_CloseKafra(Session *, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_CloseKafra(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + Packet_Fixed<0x00f7> fixed; + RecvResult rv = recv_fpacket<0x00f7, 2>(s, fixed); + if (rv != RecvResult::Complete) + return rv; if (sd->state.storage_open) storage_storageclose(sd); + + return rv; } /*========================================== @@ -4498,16 +4653,23 @@ void clif_parse_CloseKafra(Session *, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_CreateParty(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_CreateParty(Session *s, dumb_ptr<map_session_data> sd) { + Packet_Fixed<0x00f9> fixed; + RecvResult rv = recv_fpacket<0x00f9, 26>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, SkillID::NV_PARTY) >= 2) { - PartyName name = stringish<PartyName>(RFIFO_STRING<24>(s, 2)); + PartyName name = fixed.party_name; party_create(sd, name); } else clif_skill_fail(sd, SkillID::ONE, 0, 4); + + return rv; } /*========================================== @@ -4518,9 +4680,16 @@ void clif_parse_CreateParty(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_PartyInvite(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_PartyInvite(Session *s, dumb_ptr<map_session_data> sd) { - party_invite(sd, RFIFOL(s, 2)); + Packet_Fixed<0x00fc> fixed; + RecvResult rv = recv_fpacket<0x00fc, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + party_invite(sd, fixed.account_id); + + return rv; } /*========================================== @@ -4531,18 +4700,25 @@ void clif_parse_PartyInvite(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_ReplyPartyInvite(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_ReplyPartyInvite(Session *s, dumb_ptr<map_session_data> sd) { + Packet_Fixed<0x00ff> fixed; + RecvResult rv = recv_fpacket<0x00ff, 10>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, SkillID::NV_PARTY) >= 1) { - party_reply_invite(sd, RFIFOL(s, 2), RFIFOL(s, 6)); + party_reply_invite(sd, fixed.account_id, fixed.flag); } else { - party_reply_invite(sd, RFIFOL(s, 2), 0); + party_reply_invite(sd, fixed.account_id, 0); clif_skill_fail(sd, SkillID::ONE, 0, 4); } + + return rv; } /*========================================== @@ -4550,9 +4726,16 @@ void clif_parse_ReplyPartyInvite(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_LeaveParty(Session *, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_LeaveParty(Session *s, dumb_ptr<map_session_data> sd) { + Packet_Fixed<0x0100> fixed; + RecvResult rv = recv_fpacket<0x0100, 2>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + party_leave(sd); + + return rv; } /*========================================== @@ -4560,11 +4743,18 @@ void clif_parse_LeaveParty(Session *, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_RemovePartyMember(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_RemovePartyMember(Session *s, dumb_ptr<map_session_data> sd) { - int account_id = RFIFOL(s, 2); - // unused RFIFO_STRING<24>(fd, 6); + Packet_Fixed<0x0103> fixed; + RecvResult rv = recv_fpacket<0x0103, 30>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + AccountId account_id = fixed.account_id; + // unused fixed.unusedchar_name; party_removemember(sd, account_id); + + return rv; } /*========================================== @@ -4572,9 +4762,16 @@ void clif_parse_RemovePartyMember(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_PartyChangeOption(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_PartyChangeOption(Session *s, dumb_ptr<map_session_data> sd) { - party_changeoption(sd, RFIFOW(s, 2), RFIFOW(s, 4)); + Packet_Fixed<0x0102> fixed; + RecvResult rv = recv_fpacket<0x0102, 6>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + party_changeoption(sd, fixed.exp, fixed.item); + + return rv; } /*========================================== @@ -4586,582 +4783,604 @@ void clif_parse_PartyChangeOption(Session *s, dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void clif_parse_PartyMessage(Session *s, dumb_ptr<map_session_data> sd) +RecvResult clif_parse_PartyMessage(Session *s, dumb_ptr<map_session_data> sd) { - nullpo_retv(sd); + AString repeat; + RecvResult rv = recv_packet_repeatonly<0x0108, 4, 1>(s, repeat); + if (rv != RecvResult::Complete) + return rv; - AString mbuf = clif_validate_chat(sd, ChatType::Party); + AString mbuf = clif_validate_chat(sd, ChatType::Party, repeat); if (!mbuf) { - clif_displaymessage(s, "Your message could not be sent."); - return; + clif_displaymessage(s, "Your message could not be sent."_s); + return rv; } - if (is_atcommand(s, sd, mbuf, 0)) - return; + if (is_atcommand(s, sd, mbuf, GmLevel())) + return rv; /* Don't send chat that results in an automatic ban. */ if (tmw_CheckChatSpam(sd, mbuf)) { - clif_displaymessage(s, "Your message could not be sent."); - return; + clif_displaymessage(s, "Your message could not be sent."_s); + return rv; } party_send_message(sd, mbuf); + + return rv; } func_table clif_parse_func_table[0x0220] = { - {0, 10, NULL, }, // 0x0000 - {0, 0, NULL, }, // 0x0001 - {0, 0, NULL, }, // 0x0002 - {0, 0, NULL, }, // 0x0003 - {0, 0, NULL, }, // 0x0004 - {0, 0, NULL, }, // 0x0005 - {0, 0, NULL, }, // 0x0006 - {0, 0, NULL, }, // 0x0007 - {0, 0, NULL, }, // 0x0008 - {0, 0, NULL, }, // 0x0009 - {0, 0, NULL, }, // 0x000a - {0, 0, NULL, }, // 0x000b - {0, 0, NULL, }, // 0x000c - {0, 0, NULL, }, // 0x000d - {0, 0, NULL, }, // 0x000e - {0, 0, NULL, }, // 0x000f - {0, 0, NULL, }, // 0x0010 - {0, 0, NULL, }, // 0x0011 - {0, 0, NULL, }, // 0x0012 - {0, 0, NULL, }, // 0x0013 - {0, 0, NULL, }, // 0x0014 - {0, 0, NULL, }, // 0x0015 - {0, 0, NULL, }, // 0x0016 - {0, 0, NULL, }, // 0x0017 - {0, 0, NULL, }, // 0x0018 - {0, 0, NULL, }, // 0x0019 - {0, 0, NULL, }, // 0x001a - {0, 0, NULL, }, // 0x001b - {0, 0, NULL, }, // 0x001c - {0, 0, NULL, }, // 0x001d - {0, 0, NULL, }, // 0x001e - {0, 0, NULL, }, // 0x001f - {0, 0, NULL, }, // 0x0020 - {0, 0, NULL, }, // 0x0021 - {0, 0, NULL, }, // 0x0022 - {0, 0, NULL, }, // 0x0023 - {0, 0, NULL, }, // 0x0024 - {0, 0, NULL, }, // 0x0025 - {0, 0, NULL, }, // 0x0026 - {0, 0, NULL, }, // 0x0027 - {0, 0, NULL, }, // 0x0028 - {0, 0, NULL, }, // 0x0029 - {0, 0, NULL, }, // 0x002a - {0, 0, NULL, }, // 0x002b - {0, 0, NULL, }, // 0x002c - {0, 0, NULL, }, // 0x002d - {0, 0, NULL, }, // 0x002e - {0, 0, NULL, }, // 0x002f - {0, 0, NULL, }, // 0x0030 - {0, 0, NULL, }, // 0x0031 - {0, 0, NULL, }, // 0x0032 - {0, 0, NULL, }, // 0x0033 - {0, 0, NULL, }, // 0x0034 - {0, 0, NULL, }, // 0x0035 - {0, 0, NULL, }, // 0x0036 - {0, 0, NULL, }, // 0x0037 - {0, 0, NULL, }, // 0x0038 - {0, 0, NULL, }, // 0x0039 - {0, 0, NULL, }, // 0x003a - {0, 0, NULL, }, // 0x003b - {0, 0, NULL, }, // 0x003c - {0, 0, NULL, }, // 0x003d - {0, 0, NULL, }, // 0x003e - {0, 0, NULL, }, // 0x003f - {0, 0, NULL, }, // 0x0040 - {0, 0, NULL, }, // 0x0041 - {0, 0, NULL, }, // 0x0042 - {0, 0, NULL, }, // 0x0043 - {0, 0, NULL, }, // 0x0044 - {0, 0, NULL, }, // 0x0045 - {0, 0, NULL, }, // 0x0046 - {0, 0, NULL, }, // 0x0047 - {0, 0, NULL, }, // 0x0048 - {0, 0, NULL, }, // 0x0049 - {0, 0, NULL, }, // 0x004a - {0, 0, NULL, }, // 0x004b - {0, 0, NULL, }, // 0x004c - {0, 0, NULL, }, // 0x004d - {0, 0, NULL, }, // 0x004e - {0, 0, NULL, }, // 0x004f - {0, 0, NULL, }, // 0x0050 - {0, 0, NULL, }, // 0x0051 - {0, 0, NULL, }, // 0x0052 - {0, 0, NULL, }, // 0x0053 - {0, 0, NULL, }, // 0x0054 - {0, 0, NULL, }, // 0x0055 - {0, 0, NULL, }, // 0x0056 - {0, 0, NULL, }, // 0x0057 - {0, 0, NULL, }, // 0x0058 - {0, 0, NULL, }, // 0x0059 - {0, 0, NULL, }, // 0x005a - {0, 0, NULL, }, // 0x005b - {0, 0, NULL, }, // 0x005c - {0, 0, NULL, }, // 0x005d - {0, 0, NULL, }, // 0x005e - {0, 0, NULL, }, // 0x005f - {0, 0, NULL, }, // 0x0060 - {0, 0, NULL, }, // 0x0061 - {0, 0, NULL, }, // 0x0062 - {0, VAR,NULL, }, // 0x0063 - {0, 55, NULL, }, // 0x0064 - {0, 17, NULL, }, // 0x0065 - {0, 3, NULL, }, // 0x0066 - {0, 37, NULL, }, // 0x0067 - {0, 46, NULL, }, // 0x0068 - {0, VAR,NULL, }, // 0x0069 - {0, 23, NULL, }, // 0x006a - {0, VAR,NULL, }, // 0x006b - {0, 3, NULL, }, // 0x006c - {0, 108,NULL, }, // 0x006d - {0, 3, NULL, }, // 0x006e - {0, 2, NULL, }, // 0x006f - {0, 3, NULL, }, // 0x0070 - {0, 28, NULL, }, // 0x0071 + {0, 10, nullptr, }, // 0x0000 + {0, 0, nullptr, }, // 0x0001 + {0, 0, nullptr, }, // 0x0002 + {0, 0, nullptr, }, // 0x0003 + {0, 0, nullptr, }, // 0x0004 + {0, 0, nullptr, }, // 0x0005 + {0, 0, nullptr, }, // 0x0006 + {0, 0, nullptr, }, // 0x0007 + {0, 0, nullptr, }, // 0x0008 + {0, 0, nullptr, }, // 0x0009 + {0, 0, nullptr, }, // 0x000a + {0, 0, nullptr, }, // 0x000b + {0, 0, nullptr, }, // 0x000c + {0, 0, nullptr, }, // 0x000d + {0, 0, nullptr, }, // 0x000e + {0, 0, nullptr, }, // 0x000f + {0, 0, nullptr, }, // 0x0010 + {0, 0, nullptr, }, // 0x0011 + {0, 0, nullptr, }, // 0x0012 + {0, 0, nullptr, }, // 0x0013 + {0, 0, nullptr, }, // 0x0014 + {0, 0, nullptr, }, // 0x0015 + {0, 0, nullptr, }, // 0x0016 + {0, 0, nullptr, }, // 0x0017 + {0, 0, nullptr, }, // 0x0018 + {0, 0, nullptr, }, // 0x0019 + {0, 0, nullptr, }, // 0x001a + {0, 0, nullptr, }, // 0x001b + {0, 0, nullptr, }, // 0x001c + {0, 0, nullptr, }, // 0x001d + {0, 0, nullptr, }, // 0x001e + {0, 0, nullptr, }, // 0x001f + {0, 0, nullptr, }, // 0x0020 + {0, 0, nullptr, }, // 0x0021 + {0, 0, nullptr, }, // 0x0022 + {0, 0, nullptr, }, // 0x0023 + {0, 0, nullptr, }, // 0x0024 + {0, 0, nullptr, }, // 0x0025 + {0, 0, nullptr, }, // 0x0026 + {0, 0, nullptr, }, // 0x0027 + {0, 0, nullptr, }, // 0x0028 + {0, 0, nullptr, }, // 0x0029 + {0, 0, nullptr, }, // 0x002a + {0, 0, nullptr, }, // 0x002b + {0, 0, nullptr, }, // 0x002c + {0, 0, nullptr, }, // 0x002d + {0, 0, nullptr, }, // 0x002e + {0, 0, nullptr, }, // 0x002f + {0, 0, nullptr, }, // 0x0030 + {0, 0, nullptr, }, // 0x0031 + {0, 0, nullptr, }, // 0x0032 + {0, 0, nullptr, }, // 0x0033 + {0, 0, nullptr, }, // 0x0034 + {0, 0, nullptr, }, // 0x0035 + {0, 0, nullptr, }, // 0x0036 + {0, 0, nullptr, }, // 0x0037 + {0, 0, nullptr, }, // 0x0038 + {0, 0, nullptr, }, // 0x0039 + {0, 0, nullptr, }, // 0x003a + {0, 0, nullptr, }, // 0x003b + {0, 0, nullptr, }, // 0x003c + {0, 0, nullptr, }, // 0x003d + {0, 0, nullptr, }, // 0x003e + {0, 0, nullptr, }, // 0x003f + {0, 0, nullptr, }, // 0x0040 + {0, 0, nullptr, }, // 0x0041 + {0, 0, nullptr, }, // 0x0042 + {0, 0, nullptr, }, // 0x0043 + {0, 0, nullptr, }, // 0x0044 + {0, 0, nullptr, }, // 0x0045 + {0, 0, nullptr, }, // 0x0046 + {0, 0, nullptr, }, // 0x0047 + {0, 0, nullptr, }, // 0x0048 + {0, 0, nullptr, }, // 0x0049 + {0, 0, nullptr, }, // 0x004a + {0, 0, nullptr, }, // 0x004b + {0, 0, nullptr, }, // 0x004c + {0, 0, nullptr, }, // 0x004d + {0, 0, nullptr, }, // 0x004e + {0, 0, nullptr, }, // 0x004f + {0, 0, nullptr, }, // 0x0050 + {0, 0, nullptr, }, // 0x0051 + {0, 0, nullptr, }, // 0x0052 + {0, 0, nullptr, }, // 0x0053 + {0, 0, nullptr, }, // 0x0054 + {0, 0, nullptr, }, // 0x0055 + {0, 0, nullptr, }, // 0x0056 + {0, 0, nullptr, }, // 0x0057 + {0, 0, nullptr, }, // 0x0058 + {0, 0, nullptr, }, // 0x0059 + {0, 0, nullptr, }, // 0x005a + {0, 0, nullptr, }, // 0x005b + {0, 0, nullptr, }, // 0x005c + {0, 0, nullptr, }, // 0x005d + {0, 0, nullptr, }, // 0x005e + {0, 0, nullptr, }, // 0x005f + {0, 0, nullptr, }, // 0x0060 + {0, 0, nullptr, }, // 0x0061 + {0, 0, nullptr, }, // 0x0062 + {0, VAR,nullptr, }, // 0x0063 + {0, 55, nullptr, }, // 0x0064 + {0, 17, nullptr, }, // 0x0065 + {0, 3, nullptr, }, // 0x0066 + {0, 37, nullptr, }, // 0x0067 + {0, 46, nullptr, }, // 0x0068 + {0, VAR,nullptr, }, // 0x0069 + {0, 23, nullptr, }, // 0x006a + {0, VAR,nullptr, }, // 0x006b + {0, 3, nullptr, }, // 0x006c + {0, 108,nullptr, }, // 0x006d + {0, 3, nullptr, }, // 0x006e + {0, 2, nullptr, }, // 0x006f + {0, 3, nullptr, }, // 0x0070 + {0, 28, nullptr, }, // 0x0071 {0, 19, clif_parse_WantToConnection, }, // 0x0072 - {0, 11, NULL, }, // 0x0073 - {0, 3, NULL, }, // 0x0074 - {0, VAR,NULL, }, // 0x0075 - {0, 9, NULL, }, // 0x0076 - {0, 5, NULL, }, // 0x0077 - {0, 54, NULL, }, // 0x0078 - {0, 53, NULL, }, // 0x0079 - {0, 58, NULL, }, // 0x007a - {0, 60, NULL, }, // 0x007b - {0, 41, NULL, }, // 0x007c + {0, 11, nullptr, }, // 0x0073 + {0, 3, nullptr, }, // 0x0074 + {0, VAR,nullptr, }, // 0x0075 + {0, 9, nullptr, }, // 0x0076 + {0, 5, nullptr, }, // 0x0077 + {0, 54, nullptr, }, // 0x0078 + {0, 53, nullptr, }, // 0x0079 + {0, 58, nullptr, }, // 0x007a + {0, 60, nullptr, }, // 0x007b + {0, 41, nullptr, }, // 0x007c {-1, 2, clif_parse_LoadEndAck, }, // 0x007d {0, 6, clif_parse_TickSend, }, // 0x007e - {0, 6, NULL, }, // 0x007f - {0, 7, NULL, }, // 0x0080 - {0, 3, NULL, }, // 0x0081 - {0, 2, NULL, }, // 0x0082 - {0, 2, NULL, }, // 0x0083 - {0, 2, NULL, }, // 0x0084 + {0, 6, nullptr, }, // 0x007f + {0, 7, nullptr, }, // 0x0080 + {0, 3, nullptr, }, // 0x0081 + {0, 2, nullptr, }, // 0x0082 + {0, 2, nullptr, }, // 0x0083 + {0, 2, nullptr, }, // 0x0084 {-1, 5, clif_parse_WalkToXY, }, // 0x0085 Walk code limits this on it's own - {0, 16, NULL, }, // 0x0086 - {0, 12, NULL, }, // 0x0087 - {0, 10, NULL, }, // 0x0088 + {0, 16, nullptr, }, // 0x0086 + {0, 12, nullptr, }, // 0x0087 + {0, 10, nullptr, }, // 0x0088 {1000, 7, clif_parse_ActionRequest, }, // 0x0089 Special case - see below - {0, 29, NULL, }, // 0x008a - {0, 23, NULL, }, // 0x008b unknown... size 2 or 23? + {0, 29, nullptr, }, // 0x008a + {0, 23, nullptr, }, // 0x008b unknown... size 2 or 23? {300, VAR,clif_parse_GlobalMessage, }, // 0x008c - {0, VAR,NULL, }, // 0x008d - {0, VAR,NULL, }, // 0x008e - {0, 0, NULL, }, // 0x008f + {0, VAR,nullptr, }, // 0x008d + {0, VAR,nullptr, }, // 0x008e + {0, 0, nullptr, }, // 0x008f {500, 7, clif_parse_NpcClicked, }, // 0x0090 - {0, 22, NULL, }, // 0x0091 - {0, 28, NULL, }, // 0x0092 - {0, 2, NULL, }, // 0x0093 + {0, 22, nullptr, }, // 0x0091 + {0, 28, nullptr, }, // 0x0092 + {0, 2, nullptr, }, // 0x0093 {-1, 6, clif_parse_GetCharNameRequest, }, // 0x0094 - {0, 30, NULL, }, // 0x0095 + {0, 30, nullptr, }, // 0x0095 {300, VAR,clif_parse_Wis, }, // 0x0096 - {0, VAR,NULL, }, // 0x0097 - {0, 3, NULL, }, // 0x0098 - {300, VAR,NULL, }, // 0x0099 - {0, VAR,NULL, }, // 0x009a + {0, VAR,nullptr, }, // 0x0097 + {0, 3, nullptr, }, // 0x0098 + {300, VAR,nullptr, }, // 0x0099 + {0, VAR,nullptr, }, // 0x009a {-1, 5, clif_parse_ChangeDir, }, // 0x009b - {0, 9, NULL, }, // 0x009c - {0, 17, NULL, }, // 0x009d - {0, 17, NULL, }, // 0x009e + {0, 9, nullptr, }, // 0x009c + {0, 17, nullptr, }, // 0x009d + {0, 17, nullptr, }, // 0x009e {400, 6, clif_parse_TakeItem, }, // 0x009f - {0, 23, NULL, }, // 0x00a0 - {0, 6, NULL, }, // 0x00a1 + {0, 23, nullptr, }, // 0x00a0 + {0, 6, nullptr, }, // 0x00a1 {50, 6, clif_parse_DropItem, }, // 0x00a2 - {0, VAR,NULL, }, // 0x00a3 - {0, VAR,NULL, }, // 0x00a4 - {0, VAR,NULL, }, // 0x00a5 - {0, VAR,NULL, }, // 0x00a6 + {0, VAR,nullptr, }, // 0x00a3 + {0, VAR,nullptr, }, // 0x00a4 + {0, VAR,nullptr, }, // 0x00a5 + {0, VAR,nullptr, }, // 0x00a6 {0, 8, clif_parse_UseItem, }, // 0x00a7 - {0, 7, NULL, }, // 0x00a8 + {0, 7, nullptr, }, // 0x00a8 {-1, 6, clif_parse_EquipItem, }, // 0x00a9 Special case - outfit window (not implemented yet - needs to allow bursts) - {0, 7, NULL, }, // 0x00aa + {0, 7, nullptr, }, // 0x00aa {-1, 4, clif_parse_UnequipItem, }, // 0x00ab Special case - outfit window (not implemented yet - needs to allow bursts) - {0, 7, NULL, }, // 0x00ac - {0, 0, NULL, }, // 0x00ad - {0, VAR,NULL, }, // 0x00ae - {0, 6, NULL, }, // 0x00af - {0, 8, NULL, }, // 0x00b0 - {0, 8, NULL, }, // 0x00b1 + {0, 7, nullptr, }, // 0x00ac + {0, 0, nullptr, }, // 0x00ad + {0, VAR,nullptr, }, // 0x00ae + {0, 6, nullptr, }, // 0x00af + {0, 8, nullptr, }, // 0x00b0 + {0, 8, nullptr, }, // 0x00b1 {0, 3, clif_parse_Restart, }, // 0x00b2 - {0, 3, NULL, }, // 0x00b3 - {0, VAR,NULL, }, // 0x00b4 - {0, 6, NULL, }, // 0x00b5 - {0, 6, NULL, }, // 0x00b6 - {0, VAR,NULL, }, // 0x00b7 + {0, 3, nullptr, }, // 0x00b3 + {0, VAR,nullptr, }, // 0x00b4 + {0, 6, nullptr, }, // 0x00b5 + {0, 6, nullptr, }, // 0x00b6 + {0, VAR,nullptr, }, // 0x00b7 {0, 7, clif_parse_NpcSelectMenu, }, // 0x00b8 {-1, 6, clif_parse_NpcNextClicked, }, // 0x00b9 - {0, 2, NULL, }, // 0x00ba + {0, 2, nullptr, }, // 0x00ba {-1, 5, clif_parse_StatusUp, }, // 0x00bb People click this very quickly - {0, 6, NULL, }, // 0x00bc - {0, 44, NULL, }, // 0x00bd - {0, 5, NULL, }, // 0x00be + {0, 6, nullptr, }, // 0x00bc + {0, 44, nullptr, }, // 0x00bd + {0, 5, nullptr, }, // 0x00be {1000, 3, clif_parse_Emotion, }, // 0x00bf - {0, 7, NULL, }, // 0x00c0 + {0, 7, nullptr, }, // 0x00c0 {0, 2, clif_parse_HowManyConnections, }, // 0x00c1 - {0, 6, NULL, }, // 0x00c2 - {0, 8, NULL, }, // 0x00c3 - {0, 6, NULL, }, // 0x00c4 + {0, 6, nullptr, }, // 0x00c2 + {0, 8, nullptr, }, // 0x00c3 + {0, 6, nullptr, }, // 0x00c4 {0, 7, clif_parse_NpcBuySellSelected, }, // 0x00c5 - {0, VAR,NULL, }, // 0x00c6 - {0, VAR,NULL, }, // 0x00c7 + {0, VAR,nullptr, }, // 0x00c6 + {0, VAR,nullptr, }, // 0x00c7 {-1, VAR,clif_parse_NpcBuyListSend, }, // 0x00c8 {-1, VAR,clif_parse_NpcSellListSend, }, // 0x00c9 Selling multiple 1-slot items - {0, 3, NULL, }, // 0x00ca - {0, 3, NULL, }, // 0x00cb - {0, 6, NULL, }, // 0x00cc - {0, 6, NULL, }, // 0x00cd - {0, 2, NULL, }, // 0x00ce - {0, 27, NULL, }, // 0x00cf - {0, 3, NULL, }, // 0x00d0 - {0, 4, NULL, }, // 0x00d1 - {0, 4, NULL, }, // 0x00d2 - {0, 2, NULL, }, // 0x00d3 - {0, VAR,NULL, }, // 0x00d4 - {0, VAR,NULL, }, // 0x00d5 - {0, 3, NULL, }, // 0x00d6 - {0, VAR,NULL, }, // 0x00d7 - {0, 6, NULL, }, // 0x00d8 - {0, 14, NULL, }, // 0x00d9 - {0, 3, NULL, }, // 0x00da - {0, VAR,NULL, }, // 0x00db - {0, 28, NULL, }, // 0x00dc - {0, 29, NULL, }, // 0x00dd - {0, VAR,NULL, }, // 0x00de - {0, VAR,NULL, }, // 0x00df - {0, 30, NULL, }, // 0x00e0 - {0, 30, NULL, }, // 0x00e1 - {0, 26, NULL, }, // 0x00e2 - {0, 2, NULL, }, // 0x00e3 + {0, 3, nullptr, }, // 0x00ca + {0, 3, nullptr, }, // 0x00cb + {0, 6, nullptr, }, // 0x00cc + {0, 6, nullptr, }, // 0x00cd + {0, 2, nullptr, }, // 0x00ce + {0, 27, nullptr, }, // 0x00cf + {0, 3, nullptr, }, // 0x00d0 + {0, 4, nullptr, }, // 0x00d1 + {0, 4, nullptr, }, // 0x00d2 + {0, 2, nullptr, }, // 0x00d3 + {0, VAR,nullptr, }, // 0x00d4 + {0, VAR,nullptr, }, // 0x00d5 + {0, 3, nullptr, }, // 0x00d6 + {0, VAR,nullptr, }, // 0x00d7 + {0, 6, nullptr, }, // 0x00d8 + {0, 14, nullptr, }, // 0x00d9 + {0, 3, nullptr, }, // 0x00da + {0, VAR,nullptr, }, // 0x00db + {0, 28, nullptr, }, // 0x00dc + {0, 29, nullptr, }, // 0x00dd + {0, VAR,nullptr, }, // 0x00de + {0, VAR,nullptr, }, // 0x00df + {0, 30, nullptr, }, // 0x00e0 + {0, 30, nullptr, }, // 0x00e1 + {0, 26, nullptr, }, // 0x00e2 + {0, 2, nullptr, }, // 0x00e3 {2000, 6, clif_parse_TradeRequest, }, // 0x00e4 - {0, 26, NULL, }, // 0x00e5 + {0, 26, nullptr, }, // 0x00e5 {0, 3, clif_parse_TradeAck, }, // 0x00e6 - {0, 3, NULL, }, // 0x00e7 + {0, 3, nullptr, }, // 0x00e7 {0, 8, clif_parse_TradeAddItem, }, // 0x00e8 - {0, 19, NULL, }, // 0x00e9 - {0, 5, NULL, }, // 0x00ea + {0, 19, nullptr, }, // 0x00e9 + {0, 5, nullptr, }, // 0x00ea {0, 2, clif_parse_TradeOk, }, // 0x00eb - {0, 3, NULL, }, // 0x00ec + {0, 3, nullptr, }, // 0x00ec {0, 2, clif_parse_TradeCansel, }, // 0x00ed - {0, 2, NULL, }, // 0x00ee + {0, 2, nullptr, }, // 0x00ee {0, 2, clif_parse_TradeCommit, }, // 0x00ef - {0, 3, NULL, }, // 0x00f0 - {0, 2, NULL, }, // 0x00f1 - {0, 6, NULL, }, // 0x00f2 + {0, 3, nullptr, }, // 0x00f0 + {0, 2, nullptr, }, // 0x00f1 + {0, 6, nullptr, }, // 0x00f2 {-1, 8, clif_parse_MoveToKafra, }, // 0x00f3 - {0, 21, NULL, }, // 0x00f4 + {0, 21, nullptr, }, // 0x00f4 {-1, 8, clif_parse_MoveFromKafra, }, // 0x00f5 - {0, 8, NULL, }, // 0x00f6 + {0, 8, nullptr, }, // 0x00f6 {0, 2, clif_parse_CloseKafra, }, // 0x00f7 - {0, 2, NULL, }, // 0x00f8 + {0, 2, nullptr, }, // 0x00f8 {2000, 26, clif_parse_CreateParty, }, // 0x00f9 - {0, 3, NULL, }, // 0x00fa - {0, VAR,NULL, }, // 0x00fb + {0, 3, nullptr, }, // 0x00fa + {0, VAR,nullptr, }, // 0x00fb {2000, 6, clif_parse_PartyInvite, }, // 0x00fc - {0, 27, NULL, }, // 0x00fd - {0, 30, NULL, }, // 0x00fe + {0, 27, nullptr, }, // 0x00fd + {0, 30, nullptr, }, // 0x00fe {0, 10, clif_parse_ReplyPartyInvite, }, // 0x00ff {0, 2, clif_parse_LeaveParty, }, // 0x0100 - {0, 6, NULL, }, // 0x0101 + {0, 6, nullptr, }, // 0x0101 {0, 6, clif_parse_PartyChangeOption, }, // 0x0102 {0, 30, clif_parse_RemovePartyMember, }, // 0x0103 - {0, 79, NULL, }, // 0x0104 - {0, 31, NULL, }, // 0x0105 - {0, 10, NULL, }, // 0x0106 - {0, 10, NULL, }, // 0x0107 + {0, 79, nullptr, }, // 0x0104 + {0, 31, nullptr, }, // 0x0105 + {0, 10, nullptr, }, // 0x0106 + {0, 10, nullptr, }, // 0x0107 {300, VAR,clif_parse_PartyMessage, }, // 0x0108 - {0, VAR,NULL, }, // 0x0109 - {0, 4, NULL, }, // 0x010a - {0, 6, NULL, }, // 0x010b - {0, 6, NULL, }, // 0x010c - {0, 2, NULL, }, // 0x010d - {0, 11, NULL, }, // 0x010e - {0, VAR,NULL, }, // 0x010f - {0, 10, NULL, }, // 0x0110 - {0, 39, NULL, }, // 0x0111 + {0, VAR,nullptr, }, // 0x0109 + {0, 4, nullptr, }, // 0x010a + {0, 6, nullptr, }, // 0x010b + {0, 6, nullptr, }, // 0x010c + {0, 2, nullptr, }, // 0x010d + {0, 11, nullptr, }, // 0x010e + {0, VAR,nullptr, }, // 0x010f + {0, 10, nullptr, }, // 0x0110 + {0, 39, nullptr, }, // 0x0111 {-1, 4, clif_parse_SkillUp, }, // 0x0112 - {0, 10, NULL, }, // 0x0113 - {0, 31, NULL, }, // 0x0114 - {0, 35, NULL, }, // 0x0115 - {0, 10, NULL, }, // 0x0116 - {0, 18, NULL, }, // 0x0117 + {0, 10, nullptr, }, // 0x0113 + {0, 31, nullptr, }, // 0x0114 + {0, 35, nullptr, }, // 0x0115 + {0, 10, nullptr, }, // 0x0116 + {0, 18, nullptr, }, // 0x0117 {0, 2, clif_parse_StopAttack, }, // 0x0118 - {0, 13, NULL, }, // 0x0119 - {0, 15, NULL, }, // 0x011a - {0, 20, NULL, }, // 0x011b - {0, 68, NULL, }, // 0x011c - {0, 2, NULL, }, // 0x011d - {0, 3, NULL, }, // 0x011e - {0, 16, NULL, }, // 0x011f - {0, 6, NULL, }, // 0x0120 - {0, 14, NULL, }, // 0x0121 - {0, VAR,NULL, }, // 0x0122 - {0, VAR,NULL, }, // 0x0123 - {0, 21, NULL, }, // 0x0124 - {0, 8, NULL, }, // 0x0125 - {0, 8, NULL, }, // 0x0126 - {0, 8, NULL, }, // 0x0127 - {0, 8, NULL, }, // 0x0128 - {0, 8, NULL, }, // 0x0129 - {0, 2, NULL, }, // 0x012a - {0, 2, NULL, }, // 0x012b - {0, 3, NULL, }, // 0x012c - {0, 4, NULL, }, // 0x012d - {0, 2, NULL, }, // 0x012e - {0, VAR,NULL, }, // 0x012f - {0, 6, NULL, }, // 0x0130 - {0, 86, NULL, }, // 0x0131 - {0, 6, NULL, }, // 0x0132 - {0, VAR,NULL, }, // 0x0133 - {0, VAR,NULL, }, // 0x0134 - {0, 7, NULL, }, // 0x0135 - {0, VAR,NULL, }, // 0x0136 - {0, 6, NULL, }, // 0x0137 - {0, 3, NULL, }, // 0x0138 - {0, 16, NULL, }, // 0x0139 - {0, 4, NULL, }, // 0x013a - {0, 4, NULL, }, // 0x013b - {0, 4, NULL, }, // 0x013c - {0, 6, NULL, }, // 0x013d - {0, 24, NULL, }, // 0x013e - {0, 26, NULL, }, // 0x013f - {0, 22, NULL, }, // 0x0140 - {0, 14, NULL, }, // 0x0141 - {0, 6, NULL, }, // 0x0142 + {0, 13, nullptr, }, // 0x0119 + {0, 15, nullptr, }, // 0x011a + {0, 20, nullptr, }, // 0x011b + {0, 68, nullptr, }, // 0x011c + {0, 2, nullptr, }, // 0x011d + {0, 3, nullptr, }, // 0x011e + {0, 16, nullptr, }, // 0x011f + {0, 6, nullptr, }, // 0x0120 + {0, 14, nullptr, }, // 0x0121 + {0, VAR,nullptr, }, // 0x0122 + {0, VAR,nullptr, }, // 0x0123 + {0, 21, nullptr, }, // 0x0124 + {0, 8, nullptr, }, // 0x0125 + {0, 8, nullptr, }, // 0x0126 + {0, 8, nullptr, }, // 0x0127 + {0, 8, nullptr, }, // 0x0128 + {0, 8, nullptr, }, // 0x0129 + {0, 2, nullptr, }, // 0x012a + {0, 2, nullptr, }, // 0x012b + {0, 3, nullptr, }, // 0x012c + {0, 4, nullptr, }, // 0x012d + {0, 2, nullptr, }, // 0x012e + {0, VAR,nullptr, }, // 0x012f + {0, 6, nullptr, }, // 0x0130 + {0, 86, nullptr, }, // 0x0131 + {0, 6, nullptr, }, // 0x0132 + {0, VAR,nullptr, }, // 0x0133 + {0, VAR,nullptr, }, // 0x0134 + {0, 7, nullptr, }, // 0x0135 + {0, VAR,nullptr, }, // 0x0136 + {0, 6, nullptr, }, // 0x0137 + {0, 3, nullptr, }, // 0x0138 + {0, 16, nullptr, }, // 0x0139 + {0, 4, nullptr, }, // 0x013a + {0, 4, nullptr, }, // 0x013b + {0, 4, nullptr, }, // 0x013c + {0, 6, nullptr, }, // 0x013d + {0, 24, nullptr, }, // 0x013e + {0, 26, nullptr, }, // 0x013f + {0, 22, nullptr, }, // 0x0140 + {0, 14, nullptr, }, // 0x0141 + {0, 6, nullptr, }, // 0x0142 {300, 10, clif_parse_NpcAmountInput, }, // 0x0143 - {0, 23, NULL, }, // 0x0144 - {0, 19, NULL, }, // 0x0145 + {0, 23, nullptr, }, // 0x0144 + {0, 19, nullptr, }, // 0x0145 {300, 6, clif_parse_NpcCloseClicked, }, // 0x0146 - {0, 39, NULL, }, // 0x0147 - {0, 8, NULL, }, // 0x0148 - {0, 9, NULL, }, // 0x0149 - {0, 6, NULL, }, // 0x014a - {0, 27, NULL, }, // 0x014b - {0, VAR,NULL, }, // 0x014c - {0, 2, NULL, }, // 0x014d - {0, 6, NULL, }, // 0x014e - {0, 6, NULL, }, // 0x014f - {0, 110,NULL, }, // 0x0150 - {0, 6, NULL, }, // 0x0151 - {0, VAR,NULL, }, // 0x0152 - {0, VAR,NULL, }, // 0x0153 - {0, VAR,NULL, }, // 0x0154 - {0, VAR,NULL, }, // 0x0155 - {0, VAR,NULL, }, // 0x0156 - {0, 6, NULL, }, // 0x0157 - {0, VAR,NULL, }, // 0x0158 - {0, 54, NULL, }, // 0x0159 - {0, 66, NULL, }, // 0x015a - {0, 54, NULL, }, // 0x015b - {0, 90, NULL, }, // 0x015c - {0, 42, NULL, }, // 0x015d - {0, 6, NULL, }, // 0x015e - {0, 42, NULL, }, // 0x015f - {0, VAR,NULL, }, // 0x0160 - {0, VAR,NULL, }, // 0x0161 - {0, VAR,NULL, }, // 0x0162 - {0, VAR,NULL, }, // 0x0163 - {0, VAR,NULL, }, // 0x0164 - {0, 30, NULL, }, // 0x0165 - {0, VAR,NULL, }, // 0x0166 - {0, 3, NULL, }, // 0x0167 - {0, 14, NULL, }, // 0x0168 - {0, 3, NULL, }, // 0x0169 - {0, 30, NULL, }, // 0x016a - {0, 10, NULL, }, // 0x016b - {0, 43, NULL, }, // 0x016c - {0, 14, NULL, }, // 0x016d - {0, 186,NULL, }, // 0x016e - {0, 182,NULL, }, // 0x016f - {0, 14, NULL, }, // 0x0170 - {0, 30, NULL, }, // 0x0171 - {0, 10, NULL, }, // 0x0172 - {0, 3, NULL, }, // 0x0173 - {0, VAR,NULL, }, // 0x0174 - {0, 6, NULL, }, // 0x0175 - {0, 106,NULL, }, // 0x0176 - {0, VAR,NULL, }, // 0x0177 - {0, 4, NULL, }, // 0x0178 - {0, 5, NULL, }, // 0x0179 - {0, 4, NULL, }, // 0x017a - {0, VAR,NULL, }, // 0x017b - {0, 6, NULL, }, // 0x017c - {0, 7, NULL, }, // 0x017d - {0, VAR,NULL, }, // 0x017e - {0, VAR,NULL, }, // 0x017f - {0, 6, NULL, }, // 0x0180 - {0, 3, NULL, }, // 0x0181 - {0, 106,NULL, }, // 0x0182 - {0, 10, NULL, }, // 0x0183 - {0, 10, NULL, }, // 0x0184 - {0, 34, NULL, }, // 0x0185 - {0, 0, NULL, }, // 0x0186 - {0, 6, NULL, }, // 0x0187 - {0, 8, NULL, }, // 0x0188 - {0, 4, NULL, }, // 0x0189 + {0, 39, nullptr, }, // 0x0147 + {0, 8, nullptr, }, // 0x0148 + {0, 9, nullptr, }, // 0x0149 + {0, 6, nullptr, }, // 0x014a + {0, 27, nullptr, }, // 0x014b + {0, VAR,nullptr, }, // 0x014c + {0, 2, nullptr, }, // 0x014d + {0, 6, nullptr, }, // 0x014e + {0, 6, nullptr, }, // 0x014f + {0, 110,nullptr, }, // 0x0150 + {0, 6, nullptr, }, // 0x0151 + {0, VAR,nullptr, }, // 0x0152 + {0, VAR,nullptr, }, // 0x0153 + {0, VAR,nullptr, }, // 0x0154 + {0, VAR,nullptr, }, // 0x0155 + {0, VAR,nullptr, }, // 0x0156 + {0, 6, nullptr, }, // 0x0157 + {0, VAR,nullptr, }, // 0x0158 + {0, 54, nullptr, }, // 0x0159 + {0, 66, nullptr, }, // 0x015a + {0, 54, nullptr, }, // 0x015b + {0, 90, nullptr, }, // 0x015c + {0, 42, nullptr, }, // 0x015d + {0, 6, nullptr, }, // 0x015e + {0, 42, nullptr, }, // 0x015f + {0, VAR,nullptr, }, // 0x0160 + {0, VAR,nullptr, }, // 0x0161 + {0, VAR,nullptr, }, // 0x0162 + {0, VAR,nullptr, }, // 0x0163 + {0, VAR,nullptr, }, // 0x0164 + {0, 30, nullptr, }, // 0x0165 + {0, VAR,nullptr, }, // 0x0166 + {0, 3, nullptr, }, // 0x0167 + {0, 14, nullptr, }, // 0x0168 + {0, 3, nullptr, }, // 0x0169 + {0, 30, nullptr, }, // 0x016a + {0, 10, nullptr, }, // 0x016b + {0, 43, nullptr, }, // 0x016c + {0, 14, nullptr, }, // 0x016d + {0, 186,nullptr, }, // 0x016e + {0, 182,nullptr, }, // 0x016f + {0, 14, nullptr, }, // 0x0170 + {0, 30, nullptr, }, // 0x0171 + {0, 10, nullptr, }, // 0x0172 + {0, 3, nullptr, }, // 0x0173 + {0, VAR,nullptr, }, // 0x0174 + {0, 6, nullptr, }, // 0x0175 + {0, 106,nullptr, }, // 0x0176 + {0, VAR,nullptr, }, // 0x0177 + {0, 4, nullptr, }, // 0x0178 + {0, 5, nullptr, }, // 0x0179 + {0, 4, nullptr, }, // 0x017a + {0, VAR,nullptr, }, // 0x017b + {0, 6, nullptr, }, // 0x017c + {0, 7, nullptr, }, // 0x017d + {0, VAR,nullptr, }, // 0x017e + {0, VAR,nullptr, }, // 0x017f + {0, 6, nullptr, }, // 0x0180 + {0, 3, nullptr, }, // 0x0181 + {0, 106,nullptr, }, // 0x0182 + {0, 10, nullptr, }, // 0x0183 + {0, 10, nullptr, }, // 0x0184 + {0, 34, nullptr, }, // 0x0185 + {0, 0, nullptr, }, // 0x0186 + {0, 6, nullptr, }, // 0x0187 + {0, 8, nullptr, }, // 0x0188 + {0, 4, nullptr, }, // 0x0189 {0, 4, clif_parse_QuitGame, }, // 0x018a - {0, 4, NULL, }, // 0x018b - {0, 29, NULL, }, // 0x018c - {0, VAR,NULL, }, // 0x018d - {0, 10, NULL, }, // 0x018e - {0, 6, NULL, }, // 0x018f - {0, 90, NULL, }, // 0x0190 - {0, 86, NULL, }, // 0x0191 - {0, 24, NULL, }, // 0x0192 - {0, 6, NULL, }, // 0x0193 - {0, 30, NULL, }, // 0x0194 - {0, 102,NULL, }, // 0x0195 - {0, 9, NULL, }, // 0x0196 - {0, 4, NULL, }, // 0x0197 - {0, 8, NULL, }, // 0x0198 - {0, 4, NULL, }, // 0x0199 - {0, 14, NULL, }, // 0x019a - {0, 10, NULL, }, // 0x019b - {0, VAR,NULL, }, // 0x019c - {300, 6, NULL, }, // 0x019d - {0, 2, NULL, }, // 0x019e - {0, 6, NULL, }, // 0x019f - {0, 3, NULL, }, // 0x01a0 - {0, 3, NULL, }, // 0x01a1 - {0, 35, NULL, }, // 0x01a2 - {0, 5, NULL, }, // 0x01a3 - {0, 11, NULL, }, // 0x01a4 - {0, 26, NULL, }, // 0x01a5 - {0, VAR,NULL, }, // 0x01a6 - {0, 4, NULL, }, // 0x01a7 - {0, 4, NULL, }, // 0x01a8 - {0, 6, NULL, }, // 0x01a9 - {0, 10, NULL, }, // 0x01aa - {0, 12, NULL, }, // 0x01ab - {0, 6, NULL, }, // 0x01ac - {0, VAR,NULL, }, // 0x01ad - {0, 4, NULL, }, // 0x01ae - {0, 4, NULL, }, // 0x01af - {0, 11, NULL, }, // 0x01b0 - {0, 7, NULL, }, // 0x01b1 - {0, VAR,NULL, }, // 0x01b2 - {0, 67, NULL, }, // 0x01b3 - {0, 12, NULL, }, // 0x01b4 - {0, 18, NULL, }, // 0x01b5 - {0, 114,NULL, }, // 0x01b6 - {0, 6, NULL, }, // 0x01b7 - {0, 3, NULL, }, // 0x01b8 - {0, 6, NULL, }, // 0x01b9 - {0, 26, NULL, }, // 0x01ba - {0, 26, NULL, }, // 0x01bb - {0, 26, NULL, }, // 0x01bc - {0, 26, NULL, }, // 0x01bd - {0, 2, NULL, }, // 0x01be - {0, 3, NULL, }, // 0x01bf - {0, 2, NULL, }, // 0x01c0 - {0, 14, NULL, }, // 0x01c1 - {0, 10, NULL, }, // 0x01c2 - {0, VAR,NULL, }, // 0x01c3 - {0, 22, NULL, }, // 0x01c4 - {0, 22, NULL, }, // 0x01c5 - {0, 4, NULL, }, // 0x01c6 - {0, 2, NULL, }, // 0x01c7 - {0, 13, NULL, }, // 0x01c8 - {0, 97, NULL, }, // 0x01c9 - {0, 0, NULL, }, // 0x01ca - {0, 9, NULL, }, // 0x01cb - {0, 9, NULL, }, // 0x01cc - {0, 30, NULL, }, // 0x01cd - {0, 6, NULL, }, // 0x01ce - {0, 28, NULL, }, // 0x01cf - {0, 8, NULL, }, // 0x01d0 - {0, 14, NULL, }, // 0x01d1 - {0, 10, NULL, }, // 0x01d2 - {0, 35, NULL, }, // 0x01d3 - {0, 6, NULL, }, // 0x01d4 + {0, 4, nullptr, }, // 0x018b + {0, 29, nullptr, }, // 0x018c + {0, VAR,nullptr, }, // 0x018d + {0, 10, nullptr, }, // 0x018e + {0, 6, nullptr, }, // 0x018f + {0, 90, nullptr, }, // 0x0190 + {0, 86, nullptr, }, // 0x0191 + {0, 24, nullptr, }, // 0x0192 + {0, 6, nullptr, }, // 0x0193 + {0, 30, nullptr, }, // 0x0194 + {0, 102,nullptr, }, // 0x0195 + {0, 9, nullptr, }, // 0x0196 + {0, 4, nullptr, }, // 0x0197 + {0, 8, nullptr, }, // 0x0198 + {0, 4, nullptr, }, // 0x0199 + {0, 14, nullptr, }, // 0x019a + {0, 10, nullptr, }, // 0x019b + {0, VAR,nullptr, }, // 0x019c + {300, 6, nullptr, }, // 0x019d + {0, 2, nullptr, }, // 0x019e + {0, 6, nullptr, }, // 0x019f + {0, 3, nullptr, }, // 0x01a0 + {0, 3, nullptr, }, // 0x01a1 + {0, 35, nullptr, }, // 0x01a2 + {0, 5, nullptr, }, // 0x01a3 + {0, 11, nullptr, }, // 0x01a4 + {0, 26, nullptr, }, // 0x01a5 + {0, VAR,nullptr, }, // 0x01a6 + {0, 4, nullptr, }, // 0x01a7 + {0, 4, nullptr, }, // 0x01a8 + {0, 6, nullptr, }, // 0x01a9 + {0, 10, nullptr, }, // 0x01aa + {0, 12, nullptr, }, // 0x01ab + {0, 6, nullptr, }, // 0x01ac + {0, VAR,nullptr, }, // 0x01ad + {0, 4, nullptr, }, // 0x01ae + {0, 4, nullptr, }, // 0x01af + {0, 11, nullptr, }, // 0x01b0 + {0, 7, nullptr, }, // 0x01b1 + {0, VAR,nullptr, }, // 0x01b2 + {0, 67, nullptr, }, // 0x01b3 + {0, 12, nullptr, }, // 0x01b4 + {0, 18, nullptr, }, // 0x01b5 + {0, 114,nullptr, }, // 0x01b6 + {0, 6, nullptr, }, // 0x01b7 + {0, 3, nullptr, }, // 0x01b8 + {0, 6, nullptr, }, // 0x01b9 + {0, 26, nullptr, }, // 0x01ba + {0, 26, nullptr, }, // 0x01bb + {0, 26, nullptr, }, // 0x01bc + {0, 26, nullptr, }, // 0x01bd + {0, 2, nullptr, }, // 0x01be + {0, 3, nullptr, }, // 0x01bf + {0, 2, nullptr, }, // 0x01c0 + {0, 14, nullptr, }, // 0x01c1 + {0, 10, nullptr, }, // 0x01c2 + {0, VAR,nullptr, }, // 0x01c3 + {0, 22, nullptr, }, // 0x01c4 + {0, 22, nullptr, }, // 0x01c5 + {0, 4, nullptr, }, // 0x01c6 + {0, 2, nullptr, }, // 0x01c7 + {0, 13, nullptr, }, // 0x01c8 + {0, 97, nullptr, }, // 0x01c9 + {0, 0, nullptr, }, // 0x01ca + {0, 9, nullptr, }, // 0x01cb + {0, 9, nullptr, }, // 0x01cc + {0, 30, nullptr, }, // 0x01cd + {0, 6, nullptr, }, // 0x01ce + {0, 28, nullptr, }, // 0x01cf + {0, 8, nullptr, }, // 0x01d0 + {0, 14, nullptr, }, // 0x01d1 + {0, 10, nullptr, }, // 0x01d2 + {0, 35, nullptr, }, // 0x01d3 + {0, 6, nullptr, }, // 0x01d4 {300, VAR,clif_parse_NpcStringInput, }, // 0x01d5 - set to -1 - {0, 4, NULL, }, // 0x01d6 - {0, 11, NULL, }, // 0x01d7 - {0, 54, NULL, }, // 0x01d8 - {0, 53, NULL, }, // 0x01d9 - {0, 60, NULL, }, // 0x01da - {0, 2, NULL, }, // 0x01db - {0, VAR,NULL, }, // 0x01dc - {0, 47, NULL, }, // 0x01dd - {0, 33, NULL, }, // 0x01de - {0, 6, NULL, }, // 0x01df - {0, 30, NULL, }, // 0x01e0 - {0, 8, NULL, }, // 0x01e1 - {0, 34, NULL, }, // 0x01e2 - {0, 14, NULL, }, // 0x01e3 - {0, 2, NULL, }, // 0x01e4 - {0, 6, NULL, }, // 0x01e5 - {0, 26, NULL, }, // 0x01e6 - {0, 2, NULL, }, // 0x01e7 - {0, 28, NULL, }, // 0x01e8 - {0, 81, NULL, }, // 0x01e9 - {0, 6, NULL, }, // 0x01ea - {0, 10, NULL, }, // 0x01eb - {0, 26, NULL, }, // 0x01ec - {0, 2, NULL, }, // 0x01ed - {0, VAR,NULL, }, // 0x01ee - {0, VAR,NULL, }, // 0x01ef - {0, VAR,NULL, }, // 0x01f0 - {0, VAR,NULL, }, // 0x01f1 - {0, 20, NULL, }, // 0x01f2 - {0, 10, NULL, }, // 0x01f3 - {0, 32, NULL, }, // 0x01f4 - {0, 9, NULL, }, // 0x01f5 - {0, 34, NULL, }, // 0x01f6 - {0, 14, NULL, }, // 0x01f7 - {0, 2, NULL, }, // 0x01f8 - {0, 6, NULL, }, // 0x01f9 - {0, 48, NULL, }, // 0x01fa - {0, 56, NULL, }, // 0x01fb - {0, VAR,NULL, }, // 0x01fc - {0, 4, NULL, }, // 0x01fd - {0, 5, NULL, }, // 0x01fe - {0, 10, NULL, }, // 0x01ff - {0, 26, NULL, }, // 0x0200 - {0, VAR,NULL, }, // 0x0201 - {0, 26, NULL, }, // 0x0202 - {0, 10, NULL, }, // 0x0203 - {0, 18, NULL, }, // 0x0204 - {0, 26, NULL, }, // 0x0205 - {0, 11, NULL, }, // 0x0206 - {0, 34, NULL, }, // 0x0207 - {0, 14, NULL, }, // 0x0208 - {0, 36, NULL, }, // 0x0209 - {0, 10, NULL, }, // 0x020a - {0, 19, NULL, }, // 0x020b - {0, 10, NULL, }, // 0x020c - {0, VAR,NULL, }, // 0x020d - {0, 24, NULL, }, // 0x020e - {0, 0, NULL, }, // 0x020f - {0, 0, NULL, }, // 0x0210 - {0, 0, NULL, }, // 0x0211 - {0, 0, NULL, }, // 0x0212 - {0, 0, NULL, }, // 0x0213 - {0, 0, NULL, }, // 0x0214 - {0, 0, NULL, }, // 0x0215 - {0, 0, NULL, }, // 0x0216 - {0, 0, NULL, }, // 0x0217 - {0, 0, NULL, }, // 0x0218 - {0, 0, NULL, }, // 0x0219 - {0, 0, NULL, }, // 0x021a - {0, 0, NULL, }, // 0x021b - {0, 0, NULL, }, // 0x021c - {0, 0, NULL, }, // 0x021d - {0, 0, NULL, }, // 0x021e - {0, 0, NULL, }, // 0x021f + {0, 4, nullptr, }, // 0x01d6 + {0, 11, nullptr, }, // 0x01d7 + {0, 54, nullptr, }, // 0x01d8 + {0, 53, nullptr, }, // 0x01d9 + {0, 60, nullptr, }, // 0x01da + {0, 2, nullptr, }, // 0x01db + {0, VAR,nullptr, }, // 0x01dc + {0, 47, nullptr, }, // 0x01dd + {0, 33, nullptr, }, // 0x01de + {0, 6, nullptr, }, // 0x01df + {0, 30, nullptr, }, // 0x01e0 + {0, 8, nullptr, }, // 0x01e1 + {0, 34, nullptr, }, // 0x01e2 + {0, 14, nullptr, }, // 0x01e3 + {0, 2, nullptr, }, // 0x01e4 + {0, 6, nullptr, }, // 0x01e5 + {0, 26, nullptr, }, // 0x01e6 + {0, 2, nullptr, }, // 0x01e7 + {0, 28, nullptr, }, // 0x01e8 + {0, 81, nullptr, }, // 0x01e9 + {0, 6, nullptr, }, // 0x01ea + {0, 10, nullptr, }, // 0x01eb + {0, 26, nullptr, }, // 0x01ec + {0, 2, nullptr, }, // 0x01ed + {0, VAR,nullptr, }, // 0x01ee + {0, VAR,nullptr, }, // 0x01ef + {0, VAR,nullptr, }, // 0x01f0 + {0, VAR,nullptr, }, // 0x01f1 + {0, 20, nullptr, }, // 0x01f2 + {0, 10, nullptr, }, // 0x01f3 + {0, 32, nullptr, }, // 0x01f4 + {0, 9, nullptr, }, // 0x01f5 + {0, 34, nullptr, }, // 0x01f6 + {0, 14, nullptr, }, // 0x01f7 + {0, 2, nullptr, }, // 0x01f8 + {0, 6, nullptr, }, // 0x01f9 + {0, 48, nullptr, }, // 0x01fa + {0, 56, nullptr, }, // 0x01fb + {0, VAR,nullptr, }, // 0x01fc + {0, 4, nullptr, }, // 0x01fd + {0, 5, nullptr, }, // 0x01fe + {0, 10, nullptr, }, // 0x01ff + {0, 26, nullptr, }, // 0x0200 + {0, VAR,nullptr, }, // 0x0201 + {0, 26, nullptr, }, // 0x0202 + {0, 10, nullptr, }, // 0x0203 + {0, 18, nullptr, }, // 0x0204 + {0, 26, nullptr, }, // 0x0205 + {0, 11, nullptr, }, // 0x0206 + {0, 34, nullptr, }, // 0x0207 + {0, 14, nullptr, }, // 0x0208 + {0, 36, nullptr, }, // 0x0209 + {0, 10, nullptr, }, // 0x020a + {0, 19, nullptr, }, // 0x020b + {0, 10, nullptr, }, // 0x020c + {0, VAR,nullptr, }, // 0x020d + {0, 24, nullptr, }, // 0x020e + {0, 0, nullptr, }, // 0x020f + {0, 0, nullptr, }, // 0x0210 + {0, 0, nullptr, }, // 0x0211 + {0, 0, nullptr, }, // 0x0212 + {0, 0, nullptr, }, // 0x0213 + {0, 0, nullptr, }, // 0x0214 + {0, 0, nullptr, }, // 0x0215 + {0, 0, nullptr, }, // 0x0216 + {0, 0, nullptr, }, // 0x0217 + {0, 0, nullptr, }, // 0x0218 + {0, 0, nullptr, }, // 0x0219 + {0, 0, nullptr, }, // 0x021a + {0, 0, nullptr, }, // 0x021b + {0, 0, nullptr, }, // 0x021c + {0, 0, nullptr, }, // 0x021d + {0, 0, nullptr, }, // 0x021e + {0, 0, nullptr, }, // 0x021f }; // Checks for packet flooding static -int clif_check_packet_flood(Session *s, int cmd) +uint16_t clif_check_packet_flood(Session *s, int cmd) { + uint16_t len = clif_parse_func_table[cmd].len_unused; + if (len == VAR) + { + Little16 netlen; + if (!packet_fetch(s, 2, reinterpret_cast<Byte *>(&netlen), 2)) + { + return 0; + } + if (!network_to_native(&len, netlen)) + { + s->set_eof(); + return 0; + } + } + if (packet_avail(s) < len) + return 0; + dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get())); tick_t tick = gettick(); @@ -5182,30 +5401,28 @@ int clif_check_packet_flood(Session *s, int cmd) // Default rate is 100ms interval_t rate = clif_parse_func_table[cmd].rate; if (rate == interval_t::zero()) - rate = std::chrono::milliseconds(100); + rate = 100_ms; // ActionRequest - attacks are allowed a faster rate than sit/stand if (cmd == 0x89) { - int action_type = RFIFOB(s, 6); - if (action_type == 0x00 || action_type == 0x07) - rate = std::chrono::milliseconds(20); + DamageType damage_type; + Byte action_type; + if (!packet_fetch(s, 6, &action_type, 1)) + return 0; + if (!network_to_native(&damage_type, action_type)) + { + s->set_eof(); + return 0; + } + if (damage_type == DamageType::NORMAL || damage_type == DamageType::CONTINUOUS) + rate = 20_ms; else - rate = std::chrono::seconds(1); + rate = 1_s; } -// Restore this code when mana1.0 is released -#if 0 - // ChangeDir - only apply limit if not walking - if (cmd == 0x9b) - { - // .29 clients spam this packet when walking into a blocked tile - if (RFIFOB(fd, 4) == sd->dir || sd->walktimer != -1) - return 0; - - rate = 500; - } -#endif + // Restore this code when mana1.0 is released + // nope, nuh-uh // They are flooding if (tick < sd->flood_rates[cmd] + rate) @@ -5223,16 +5440,16 @@ int clif_check_packet_flood(Session *s, int cmd) if (sd->packet_flood_in >= battle_config.packet_spam_flood) { - PRINTF("packet flood detected from %s [0x%x]\n", sd->status_key.name, cmd); + PRINTF("packet flood detected from %s [0x%x]\n"_fmt, sd->status_key.name, cmd); if (battle_config.packet_spam_kick) { s->set_eof(); - return 1; + return len; } sd->packet_flood_in = 0; } - return 1; + return len; } sd->flood_rates[cmd] = tick; @@ -5240,9 +5457,9 @@ int clif_check_packet_flood(Session *s, int cmd) } inline -void WARN_MALFORMED_MSG(dumb_ptr<map_session_data> sd, const char *msg) +void WARN_MALFORMED_MSG(dumb_ptr<map_session_data> sd, ZString msg) { - PRINTF("clif_validate_chat(): %s (ID %d) sent a malformed message: %s.\n", + PRINTF("clif_validate_chat(): %s (ID %d) sent a malformed message: %s.\n"_fmt, sd->status_key.name, sd->status_key.account_id, msg); } /** @@ -5256,7 +5473,7 @@ void WARN_MALFORMED_MSG(dumb_ptr<map_session_data> sd, const char *msg) * @return a dynamically allocated copy of the message, or empty string upon failure */ static -AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type) +AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type, XString buf) { nullpo_retr(AString(), sd); /* @@ -5267,54 +5484,8 @@ AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type) return AString(); Session *s = sd->sess; - size_t msg_len = RFIFOW(s, 2) - 4; size_t name_len = sd->status_key.name.to__actual().size(); - /* - * At least one character is required in all instances. - * Notes for length checks: - * - * For all types, header (2) + length (2) is considered empty. - * For type 1, the message must be longer than the maximum name length (24) - * to be valid. - * For type 2, the message must be longer than the sender's name length - * plus the length of the separator (" : "). - */ - size_t min_len = - (type == ChatType::Whisper) ? 24 - : (type == ChatType::Global) ? name_len + 3 - : 0; - - /* The player just sent the header (2) and length (2) words. */ - if (!msg_len) - { - WARN_MALFORMED_MSG(sd, "no message sent"); - return AString(); - } - - /* The client sent (or claims to have sent) an empty message. */ - if (msg_len == min_len) - { - WARN_MALFORMED_MSG(sd, "empty message"); - return AString(); - } - - /* The protocol specifies that the target must be 24 bytes long. */ - if (type == ChatType::Whisper && msg_len < min_len) - { - /* Disallow malformed messages. */ - clif_setwaitclose(s); - WARN_MALFORMED_MSG(sd, "illegal target name"); - return AString(); - } - - size_t pstart = 4; - size_t buf_len = msg_len; - if (type == ChatType::Whisper) - { - pstart += 24; - buf_len -= 24; - } - AString pbuf = RFIFO_STRING(s, pstart, buf_len); + XString pbuf = buf; /* * The client attempted to exceed the maximum message length. @@ -5323,20 +5494,21 @@ AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type) * is truncated. But the previous behavior was to drop the message, so * we'll do that, too. */ - if (buf_len >= battle_config.chat_maxline) + // TODO this cuts global chat short by (name_length + 3) + if (buf.size() >= battle_config.chat_maxline) { - WARN_MALFORMED_MSG(sd, "exceeded maximum message length"); + WARN_MALFORMED_MSG(sd, "exceeded maximum message length"_s); return AString(); } if (type == ChatType::Global) { XString p = pbuf; - if (!(p.startswith(sd->status_key.name.to__actual()) && p.xslice_t(name_len).startswith(" : "))) + if (!(p.startswith(sd->status_key.name.to__actual()) && p.xslice_t(name_len).startswith(" : "_s))) { /* Disallow malformed/spoofed messages. */ clif_setwaitclose(s); - WARN_MALFORMED_MSG(sd, "spoofed name/invalid format"); + WARN_MALFORMED_MSG(sd, "spoofed name/invalid format"_s); return AString(); } /* Step beyond the separator. */ @@ -5354,19 +5526,39 @@ AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type) static void clif_parse(Session *s) { - int packet_len = 0, cmd = 0; + // old code: + // no while loop (can hang if more than one packet) + // handles 0x7530 and 0x7532 specially, also 0x0072 + // checks packet length table + // checks rate limiter + // dispatches to actual function, unchecked + // interstitial code: + // introduces while loop + // checks rate limiter + // dispatches to actual function + // if incomplete, unchecks rate limiter + // if error, close socket + // future code: + // hoists while loop + // treats all packets as variable-length, except a hard-coded list + // reads packet of that length unconditionally into a buffer + // does rate-limit check (hoisted?) + // dispatches to actual function + // if error, close socket + dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get())); if (!sd || (sd && !sd->state.auth)) { - if (RFIFOREST(s) < 2) - { // too small a packet disconnect - s->set_eof(); - } - if (RFIFOW(s, 0) != 0x72 && RFIFOW(s, 0) != 0x7530) + uint16_t packet_id; + if (!packet_peek_id(s, &packet_id)) + return; + + if (packet_id != 0x0072 && packet_id != 0x7530) { // first packet must be auth or finger s->set_eof(); + return; } } @@ -5375,100 +5567,89 @@ void clif_parse(Session *s) s->set_eof(); return; } - - if (RFIFOREST(s) < 2) - return; // Too small (no packet number) - - cmd = RFIFOW(s, 0); - - // 管理用パケット処理 - if (cmd >= 30000) + if (sd && sd->state.auth == 1 && sd->state.waitingdisconnect == 1) { - switch (cmd) - { - case 0x7530: // Athena情報所得 - WFIFOW(s, 0) = 0x7531; - WFIFO_STRUCT(s, 2, CURRENT_MAP_SERVER_VERSION); - WFIFOSET(s, 10); - RFIFOSKIP(s, 2); - break; - case 0x7532: // 接続の切断 - s->set_eof(); - break; - } + packet_discard(s, packet_avail(s)); return; } - else if (cmd >= 0x200) - return; - // パケット長を計算 - packet_len = clif_parse_func_table[cmd].len; - if (packet_len == VAR) + uint16_t packet_id; + RecvResult rv = RecvResult::Complete; + while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id)) { - if (RFIFOREST(s) < 4) + switch (packet_id) { - return; // Runt packet (variable length without a length sent) + case 0x7530: + { + Packet_Fixed<0x7530> fixed; + rv = recv_fpacket<0x7530, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + + Packet_Fixed<0x7531> fixed_31; + fixed_31.version = CURRENT_MAP_SERVER_VERSION; + send_fpacket<0x7531, 10>(s, fixed_31); + break; + } + case 0x7532: + { + Packet_Fixed<0x7532> fixed; + rv = recv_fpacket<0x7532, 2>(s, fixed); + if (rv != RecvResult::Complete) + break; + + s->set_eof(); + break; + } } - packet_len = RFIFOW(s, 2); - if (packet_len < 4 || packet_len > 32768) + if (packet_id < 0x0220) { - s->set_eof(); - return; // Runt packet (variable out of bounds) + if (uint16_t len = clif_check_packet_flood(s, packet_id)) + { + // Packet flood: skip packet + packet_discard(s, len); + rv = RecvResult::Complete; + } + else + { + clif_func func = clif_parse_func_table[packet_id].func; + if (!func) + goto unknown_packet; + rv = func(s, sd); + } } + else + goto unknown_packet; } - if (RFIFOREST(s) < packet_len) - { - return; // Runt packet (sent legnth is too small) - } - - if (sd && sd->state.auth == 1 && sd->state.waitingdisconnect == 1) - { // 切断待ちの場合パケットを処理しない - - } - else if (clif_parse_func_table[cmd].func) - { - if (clif_check_packet_flood(s, cmd)) - { - // Flood triggered. Skip packet. - RFIFOSKIP(sd->sess, packet_len); - return; - } + if (rv == RecvResult::Error) + s->set_eof(); + return; - clif_parse_func_table[cmd].func(s, sd); - } - else +unknown_packet: { - // 不明なパケット if (battle_config.error_log) { if (s) - PRINTF("\nclif_parse: session #%d, packet 0x%x, lenght %d\n", - s, cmd, packet_len); -#ifdef DUMP_UNKNOWN_PACKET + PRINTF("\nclif_parse: session #%d, packet 0x%x, lenght %zu\n"_fmt, + s, packet_id, packet_avail(s)); { - int i; - ZString packet_txt = "save/packet.txt"; - PRINTF("---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F"); - for (i = 0; i < packet_len; i++) - { - if ((i & 15) == 0) - PRINTF("\n%04X ", i); - PRINTF("%02X ", RFIFOB(s, i)); - } + ZString packet_txt = "save/packet.txt"_s; if (sd && sd->state.auth) { - PRINTF("\nAccount ID %d, character ID %d, player name %s.\n", + PRINTF("Unknown packet: Account ID %d, character ID %d, player name %s.\n"_fmt, sd->status_key.account_id, sd->status_key.char_id, sd->status_key.name); } else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified) - PRINTF("\nAccount ID %d.\n", sd->bl_id); + PRINTF("Unkonwn packet (unauthenticated): Account ID %d.\n"_fmt, sd->bl_id); + else + PRINTF("Unknown packet (unknown)\n"_fmt); io::AppendFile fp(packet_txt); if (!fp.is_open()) { - PRINTF("clif.c: cant write [%s] !!! data is lost !!!\n", + PRINTF("clif.c: cant write [%s] !!! data is lost !!!\n"_fmt, packet_txt); return; } @@ -5479,34 +5660,29 @@ void clif_parse(Session *s) if (sd && sd->state.auth) { FPRINTF(fp, - "%s\nPlayer with account ID %d (character ID %d, player name %s) sent wrong packet:\n", + "%s\nPlayer with account ID %d (character ID %d, player name %s) sent wrong packet:\n"_fmt, now, sd->status_key.account_id, sd->status_key.char_id, sd->status_key.name); } else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified) FPRINTF(fp, - "%s\nPlayer with account ID %d sent wrong packet:\n", + "%s\nUnauthenticated player with account ID %d sent wrong packet:\n"_fmt, now, sd->bl_id); + else + FPRINTF(fp, + "%s\nUnknown connection sent wrong packet:\n"_fmt, + now); - FPRINTF(fp, - "\t---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F"); - for (i = 0; i < packet_len; i++) - { - if ((i & 15) == 0) - FPRINTF(fp, "\n\t%04X ", i); - FPRINTF(fp, "%02X ", RFIFOB(s, i)); - } - FPRINTF(fp, "\n\n"); + packet_dump(fp, s); } } -#endif } } - RFIFOSKIP(s, packet_len); } void do_init_clif(void) { - make_listen_port(map_port, SessionParsers{func_parse: clif_parse, func_delete: clif_delete}); + make_listen_port(map_port, SessionParsers{.func_parse= clif_parse, .func_delete= clif_delete}); } +} // namespace tmwa diff --git a/src/map/clif.hpp b/src/map/clif.hpp index 1fdd67c..adb4889 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_CLIF_HPP -#define TMWA_MAP_CLIF_HPP +#pragma once // clif.hpp - Network interface to the client. // // Copyright © ????-2004 Athena Dev Teams @@ -21,22 +20,29 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "clif.t.hpp" +#include "clif.t.hpp" -# include <functional> +#include <functional> -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "../mmo/ip.hpp" -# include "../mmo/timer.t.hpp" +#include "../generic/fwd.hpp" -# include "battle.t.hpp" -# include "map.hpp" -# include "pc.t.hpp" -# include "skill.t.hpp" +#include "../net/timer.t.hpp" +#include "../mmo/fwd.hpp" +#include "../mmo/mmo.hpp" + +#include "battle.t.hpp" +#include "map.t.hpp" +#include "pc.t.hpp" +#include "skill.t.hpp" + + +namespace tmwa +{ void clif_setip(IP4Address); void clif_setport(int); @@ -47,16 +53,16 @@ void clif_setwaitclose(Session *); int clif_authok(dumb_ptr<map_session_data>); int clif_authfail_fd(Session *, int); -int clif_charselectok(int); +int clif_charselectok(BlockId); int clif_dropflooritem(dumb_ptr<flooritem_data>); int clif_clearflooritem(dumb_ptr<flooritem_data>, Session *); int clif_clearchar(dumb_ptr<block_list>, BeingRemoveWhy); // area or fd int clif_clearchar_delay(tick_t, dumb_ptr<block_list>, BeingRemoveWhy); -void clif_clearchar_id(int, BeingRemoveWhy, Session *); +void clif_clearchar_id(BlockId, BeingRemoveWhy, Session *); int clif_spawnpc(dumb_ptr<map_session_data>); //area int clif_spawnnpc(dumb_ptr<npc_data>); // area int clif_spawn_fake_npc_for_player(dumb_ptr<map_session_data> sd, - int fake_npc_id); + BlockId fake_npc_id); int clif_spawnmob(dumb_ptr<mob_data>); // area int clif_walkok(dumb_ptr<map_session_data>); // self int clif_movechar(dumb_ptr<map_session_data>); // area @@ -66,18 +72,18 @@ void clif_changemapserver(dumb_ptr<map_session_data>, MapName, int, int, IP4Addr void clif_fixpos(dumb_ptr<block_list>); // area int clif_fixmobpos(dumb_ptr<mob_data> md); int clif_fixpcpos(dumb_ptr<map_session_data> sd); -int clif_npcbuysell(dumb_ptr<map_session_data>, int); //self +int clif_npcbuysell(dumb_ptr<map_session_data>, BlockId); //self int clif_buylist(dumb_ptr<map_session_data>, dumb_ptr<npc_data_shop>); //self int clif_selllist(dumb_ptr<map_session_data>); //self -void clif_scriptmes(dumb_ptr<map_session_data>, int, XString); //self -void clif_scriptnext(dumb_ptr<map_session_data>, int); //self -void clif_scriptclose(dumb_ptr<map_session_data>, int); //self -void clif_scriptmenu(dumb_ptr<map_session_data>, int, XString); //self -void clif_scriptinput(dumb_ptr<map_session_data>, int); //self -void clif_scriptinputstr(dumb_ptr<map_session_data> sd, int npcid); // self -void clif_viewpoint(dumb_ptr<map_session_data>, int, int, int, int, int, int); //self -int clif_additem(dumb_ptr<map_session_data>, int, int, PickupFail); //self -void clif_delitem(dumb_ptr<map_session_data>, int, int); //self +void clif_scriptmes(dumb_ptr<map_session_data>, BlockId, XString); //self +void clif_scriptnext(dumb_ptr<map_session_data>, BlockId); //self +void clif_scriptclose(dumb_ptr<map_session_data>, BlockId); //self +void clif_scriptmenu(dumb_ptr<map_session_data>, BlockId, XString); //self +void clif_scriptinput(dumb_ptr<map_session_data>, BlockId); //self +void clif_scriptinputstr(dumb_ptr<map_session_data> sd, BlockId npcid); // self + +int clif_additem(dumb_ptr<map_session_data>, IOff0, int, PickupFail); //self +void clif_delitem(dumb_ptr<map_session_data>, IOff0, int); //self int clif_updatestatus(dumb_ptr<map_session_data>, SP); //self int clif_damage(dumb_ptr<block_list>, dumb_ptr<block_list>, tick_t, interval_t, interval_t, @@ -89,14 +95,14 @@ int clif_takeitem(dumb_ptr<block_list> src, dumb_ptr<block_list> dst) } int clif_changelook(dumb_ptr<block_list>, LOOK, int); // area void clif_changelook_accessories(dumb_ptr<block_list> bl, dumb_ptr<map_session_data> dst); // area or target; list gloves, boots etc. -int clif_arrowequip(dumb_ptr<map_session_data> sd, int val); //self +int clif_arrowequip(dumb_ptr<map_session_data> sd, IOff0 val); //self int clif_arrow_fail(dumb_ptr<map_session_data> sd, int type); //self int clif_statusupack(dumb_ptr<map_session_data>, SP, int, int); // self -int clif_equipitemack(dumb_ptr<map_session_data>, int, EPOS, int); // self -int clif_unequipitemack(dumb_ptr<map_session_data>, int, EPOS, int); // self +int clif_equipitemack(dumb_ptr<map_session_data>, IOff0, EPOS, int); // self +int clif_unequipitemack(dumb_ptr<map_session_data>, IOff0, EPOS, int); // self int clif_misceffect(dumb_ptr<block_list>, int); // area int clif_changeoption(dumb_ptr<block_list>); // area -int clif_useitemack(dumb_ptr<map_session_data>, int, int, int); // self +int clif_useitemack(dumb_ptr<map_session_data>, IOff0, int, int); // self void clif_emotion(dumb_ptr<block_list> bl, int type); void clif_sitting(Session *, dumb_ptr<map_session_data> sd); @@ -105,22 +111,22 @@ void clif_sitting(Session *, dumb_ptr<map_session_data> sd); void clif_traderequest(dumb_ptr<map_session_data> sd, CharName name); void clif_tradestart(dumb_ptr<map_session_data> sd, int type); void clif_tradeadditem(dumb_ptr<map_session_data> sd, - dumb_ptr<map_session_data> tsd, int index, int amount); -int clif_tradeitemok(dumb_ptr<map_session_data> sd, int index, int amount, + dumb_ptr<map_session_data> tsd, IOff2 index2, int amount); +int clif_tradeitemok(dumb_ptr<map_session_data> sd, IOff2 index, int amount, int fail); int clif_tradedeal_lock(dumb_ptr<map_session_data> sd, int fail); int clif_tradecancelled(dumb_ptr<map_session_data> sd); int clif_tradecompleted(dumb_ptr<map_session_data> sd, int fail); // storage -int clif_storageitemlist(dumb_ptr<map_session_data> sd, struct storage *stor); +int clif_storageitemlist(dumb_ptr<map_session_data> sd, Storage *stor); int clif_storageequiplist(dumb_ptr<map_session_data> sd, - struct storage *stor); + Storage *stor); int clif_updatestorageamount(dumb_ptr<map_session_data> sd, - struct storage *stor); -int clif_storageitemadded(dumb_ptr<map_session_data> sd, struct storage *stor, - int index, int amount); -int clif_storageitemremoved(dumb_ptr<map_session_data> sd, int index, + Storage *stor); +int clif_storageitemadded(dumb_ptr<map_session_data> sd, Storage *stor, + SOff0 index, int amount); +int clif_storageitemremoved(dumb_ptr<map_session_data> sd, SOff0 index, int amount); int clif_storageclose(dumb_ptr<map_session_data> sd); @@ -157,17 +163,17 @@ int clif_movetoattack(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl); // party int clif_party_created(dumb_ptr<map_session_data> sd, int flag); -int clif_party_info(struct party *p, Session *s); +int clif_party_info(PartyPair p, Session *s); void clif_party_invite(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd); void clif_party_inviteack(dumb_ptr<map_session_data> sd, CharName nick, int flag); -void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd, +void clif_party_option(PartyPair p, dumb_ptr<map_session_data> sd, int flag); -void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd, - int account_id, CharName name, int flag); -void clif_party_message(struct party *p, int account_id, XString mes); -int clif_party_xy(struct party *p, dumb_ptr<map_session_data> sd); -int clif_party_hp(struct party *p, dumb_ptr<map_session_data> sd); +void clif_party_leaved(PartyPair p, dumb_ptr<map_session_data> sd, + AccountId account_id, CharName name, int flag); +void clif_party_message(PartyPair p, AccountId account_id, XString mes); +int clif_party_xy(PartyPair p, dumb_ptr<map_session_data> sd); +int clif_party_hp(PartyPair p, dumb_ptr<map_session_data> sd); // atcommand void clif_displaymessage(Session *s, XString mes); @@ -183,5 +189,4 @@ int clif_GM_kick(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd, int clif_foreachclient(std::function<void(dumb_ptr<map_session_data>)>); void do_init_clif(void); - -#endif // TMWA_MAP_CLIF_HPP +} // namespace tmwa diff --git a/src/map/clif.t.hpp b/src/map/clif.t.hpp index 5cb06ad..1789ee8 100644 --- a/src/map/clif.t.hpp +++ b/src/map/clif.t.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_CLIF_T_HPP -#define TMWA_MAP_CLIF_T_HPP +#pragma once // clif.t.hpp - Network interface to the client. // // Copyright © ????-2004 Athena Dev Teams @@ -21,9 +20,99 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdint> +#include <cstdint> + +#include "../ints/little.hpp" + +#include "../compat/iter.hpp" + +#include "../generic/enum.hpp" + +#include "../mmo/consts.hpp" +#include "../mmo/enums.hpp" + + +namespace tmwa +{ +namespace e +{ +// [Fate] status.option properties. These are persistent status changes. +// IDs that are not listed are not used in the code (to the best of my knowledge) +enum class Option : uint16_t +{ + ZERO = 0x0000, + + // [Fate] This is the GM `@hide' flag + HIDE = 0x0040, + // [Fate] Complete invisibility to other clients + INVISIBILITY = 0x1000, + + // ? + REAL_ANY_HIDE = HIDE, +}; +enum class Opt1 : uint16_t +{ + ZERO = 0, + _stone1 = 1, + _freeze = 2, + _stan = 3, + _sleep = 4, + _stone6 = 6, +}; +enum class Opt2 : uint16_t +{ + ZERO = 0x0000, + _poison = 0x0001, + _curse = 0x0002, + _silence = 0x0004, + BLIND = 0x0010, + _speedpotion0 = 0x0020, + _signumcrucis = 0x0040, + _atkpot = 0x0080, + _heal = 0x0100, + _slowpoison = 0x0200, +}; +enum class Opt3 : uint16_t +{ + ZERO = 0x0000, + _concentration = 0x0001, + _overthrust = 0x0002, + _energycoat = 0x0004, + _explosionspirits = 0x0008, + _steelbody = 0x0010, + _berserk = 0x0080, + + _marionette = 0x0400, + _assumptio = 0x0800, +}; + +ENUM_BITWISE_OPERATORS(Option) +ENUM_BITWISE_OPERATORS(Opt2) +ENUM_BITWISE_OPERATORS(Opt3) +} +using e::Option; +using e::Opt1; +using e::Opt2; +using e::Opt3; + + +enum class ItemType : uint8_t +{ + USE = 0, // in eA, healing only + _1 = 1, // unused + _2 = 2, // in eA, other usable items + JUNK = 3, // "useless" items (e.g. quests) + WEAPON = 4, // all weapons + ARMOR = 5, // all other equipment + _6 = 6, // in eA, card + _7 = 7, // in eA, pet egg + _8 = 8, // in eA, pet equipment + _9 = 9, // unused + ARROW = 10, // ammo + _11 = 11, // in eA, delayed use (special script) +}; enum class BeingRemoveWhy : uint8_t { @@ -40,4 +129,589 @@ enum class BeingRemoveWhy : uint8_t NEGATIVE1 = 0xff, }; -#endif // TMWA_MAP_CLIF_T_HPP +enum class PickupFail : uint8_t +{ + OKAY = 0, + BAD_ITEM = 1, + TOO_HEAVY = 2, + TOO_FAR = 3, + INV_FULL = 4, + STACK_FULL = 5, + DROP_STEAL = 6, +}; + +// this is used for both input and output +// different values are valid in 0x0089 vs 0x008a +enum class DamageType : uint8_t +{ + NORMAL = 0x00, + TAKEITEM = 0x01, + SIT = 0x02, + STAND = 0x03, + RETURNED = 0x04, + CONTINUOUS = 0x07, + DOUBLED = 0x08, + CRITICAL = 0x0a, + FLEE2 = 0x0b, +}; + +enum class LOOK : uint8_t +{ + BASE = 0, + HAIR = 1, + WEAPON = 2, + HEAD_BOTTOM = 3, + HEAD_TOP = 4, + HEAD_MID = 5, + HAIR_COLOR = 6, + CLOTHES_COLOR = 7, + SHIELD = 8, + SHOES = 9, + GLOVES = 10, + CAPE = 11, + MISC1 = 12, + MISC2 = 13, + + COUNT, +}; + +// Note: there is also a typedef by this name in <dirent.h> +// but we should be fine since we never include it. +// (in the long term we should still rename this though) +enum class DIR : uint8_t +{ + S = 0, + SW = 1, + W = 2, + NW = 3, + N = 4, + NE = 5, + E = 6, + SE = 7, + + COUNT, +}; + +constexpr +earray<int, DIR, DIR::COUNT> dirx //= +{{ + 0, -1, -1, -1, 0, 1, 1, 1, +}}, diry //= +{{ + 1, 1, 0, -1, -1, -1, 0, 1, +}}; + +constexpr +bool dir_is_diagonal(DIR d) +{ + return static_cast<uint8_t>(d) & 1; +} + + +enum class SP : uint16_t +{ + // sent to client + SPEED = 0, + + // when used as "no stat" + ZERO = 0, + + // sent to client + BASEEXP = 1, + // sent to client + JOBEXP = 2, +#if 0 + KARMA = 3, +#endif + + // sent to client + HP = 5, + // sent to client + MAXHP = 6, + // sent to client + SP = 7, + // sent to client + MAXSP = 8, + // sent to client + STATUSPOINT = 9, + + // sent to client + BASELEVEL = 11, + // sent to client + SKILLPOINT = 12, + // sent to client + STR = 13, + // sent to client + AGI = 14, + // sent to client + VIT = 15, + // sent to client + INT = 16, + // sent to client + DEX = 17, + // sent to client + LUK = 18, + CLASS = 19, + // sent to client + ZENY = 20, + SEX = 21, + // sent to client + NEXTBASEEXP = 22, + // sent to client + NEXTJOBEXP = 23, + // sent to client + WEIGHT = 24, + // sent to client + MAXWEIGHT = 25, + + // sent to client + USTR = 32, + // sent to client + UAGI = 33, + // sent to client + UVIT = 34, + // sent to client + UINT = 35, + // sent to client + UDEX = 36, + // sent to client + ULUK = 37, + + // sent to client + ATK1 = 41, + // sent to client + ATK2 = 42, + // sent to client + MATK1 = 43, + // sent to client + MATK2 = 44, + // sent to client + DEF1 = 45, + // sent to client + DEF2 = 46, + // sent to client + MDEF1 = 47, + // sent to client + MDEF2 = 48, + // sent to client + HIT = 49, + // sent to client + FLEE1 = 50, + // sent to client + FLEE2 = 51, + // sent to client + CRITICAL = 52, + // sent to client + ASPD = 53, + + // sent to client + JOBLEVEL = 55, + +#if 0 + PARTNER = 57, + CART = 58, + FAME = 59, + UNBREAKABLE = 60, +#endif + + DEAF = 70, + + // sent to client + GM = 500, + + // sent to client + ATTACKRANGE = 1000, +#if 0 + ATKELE = 1001, +#endif +#if 0 + DEFELE = 1002, +#endif +#if 0 + CASTRATE = 1003, +#endif + MAXHPRATE = 1004, +#if 0 + MAXSPRATE = 1005, +#endif +#if 0 + SPRATE = 1006, +#endif + +#if 0 + ADDEFF = 1012, +#endif +#if 0 + RESEFF = 1013, +#endif + BASE_ATK = 1014, + ASPD_RATE = 1015, + HP_RECOV_RATE = 1016, +#if 0 + SP_RECOV_RATE = 1017, +#endif +#if 0 + SPEED_RATE = 1018, +#endif + CRITICAL_DEF = 1019, +#if 0 + NEAR_ATK_DEF = 1020, +#endif +#if 0 + LONG_ATK_DEF = 1021, +#endif +#if 0 + DOUBLE_RATE = 1022, +#endif + DOUBLE_ADD_RATE = 1023, +#if 0 + MATK = 1024, +#endif +#if 0 + MATK_RATE = 1025, +#endif +#if 0 + IGNORE_DEF_ELE = 1026, +#endif +#if 0 + IGNORE_DEF_RACE = 1027, +#endif +#if 0 + ATK_RATE = 1028, +#endif + SPEED_ADDRATE = 1029, +#if 0 + ASPD_ADDRATE = 1030, +#endif +#if 0 + MAGIC_ATK_DEF = 1031, +#endif +#if 0 + MISC_ATK_DEF = 1032, +#endif +#if 0 + IGNORE_MDEF_ELE = 1033, +#endif +#if 0 + IGNORE_MDEF_RACE = 1034, +#endif + +#if 0 + PERFECT_HIT_RATE = 1038, +#endif +#if 0 + PERFECT_HIT_ADD_RATE = 1039, +#endif +#if 0 + CRITICAL_RATE = 1040, +#endif +#if 0 + GET_ZENY_NUM = 1041, +#endif +#if 0 + ADD_GET_ZENY_NUM = 1042, +#endif + +#if 0 + ADD_MONSTER_DROP_ITEM = 1047, +#endif +#if 0 + DEF_RATIO_ATK_ELE = 1048, +#endif +#if 0 + DEF_RATIO_ATK_RACE = 1049, +#endif +#if 0 + ADD_SPEED = 1050, +#endif +#if 0 + HIT_RATE = 1051, +#endif +#if 0 + FLEE_RATE = 1052, +#endif +#if 0 + FLEE2_RATE = 1053, +#endif + DEF_RATE = 1054, + DEF2_RATE = 1055, +#if 0 + MDEF_RATE = 1056, +#endif +#if 0 + MDEF2_RATE = 1057, +#endif +#if 0 + SPLASH_RANGE = 1058, +#endif +#if 0 + SPLASH_ADD_RANGE = 1059, +#endif + + HP_DRAIN_RATE = 1061, +#if 0 + SP_DRAIN_RATE = 1062, +#endif +#if 0 + SHORT_WEAPON_DAMAGE_RETURN = 1063, +#endif +#if 0 + LONG_WEAPON_DAMAGE_RETURN = 1064, +#endif + +#if 0 + ADDEFF2 = 1067, +#endif + BREAK_WEAPON_RATE = 1068, + BREAK_ARMOR_RATE = 1069, + ADD_STEAL_RATE = 1070, + MAGIC_DAMAGE_RETURN = 1071, +#if 0 + RANDOM_ATTACK_INCREASE = 1072, +#endif +}; + +constexpr +SP attr_to_sp(ATTR attr) +{ + return static_cast<SP>(static_cast<uint16_t>(attr) + static_cast<uint16_t>(SP::STR)); +} + +constexpr +ATTR sp_to_attr(SP sp) +{ + return static_cast<ATTR>(static_cast<uint16_t>(sp) - static_cast<uint16_t>(SP::STR)); +} + +constexpr +SP attr_to_usp(ATTR attr) +{ + return static_cast<SP>(static_cast<uint16_t>(attr) + static_cast<uint16_t>(SP::USTR)); +} + +constexpr +ATTR usp_to_attr(SP sp) +{ + return static_cast<ATTR>(static_cast<uint16_t>(sp) - static_cast<uint16_t>(SP::USTR)); +} + +constexpr +SP sp_to_usp(SP sp) +{ + return attr_to_usp(sp_to_attr(sp)); +} + +constexpr +SP usp_to_sp(SP sp) +{ + return attr_to_sp(usp_to_attr(sp)); +} + + +// xxxx xxxx xxyy yyyy yyyy dddd +struct NetPosition1 +{ + Byte data[3]; +}; + +struct Position1 +{ + uint16_t x, y; + DIR dir; +}; + +inline +bool native_to_network(NetPosition1 *network, Position1 native) +{ + uint16_t x = native.x; + uint16_t y = native.y; + uint8_t d = static_cast<uint8_t>(native.dir); + + uint8_t *p = reinterpret_cast<uint8_t *>(network); + p[0] = x >> 2; + p[1] = (x << 6) | ((y >> 4) & 0x3f); + p[2] = y << 4 | d; + + return x < 1024 && y < 1024 && d < 16; +} + +inline +bool network_to_native(Position1 *native, NetPosition1 network) +{ + const uint8_t *p = reinterpret_cast<const uint8_t *>(&network); + native->x = (p[0] & (0x3ff >> 2)) << 2 | p[1] >> (8 - 2); + native->y = (p[1] & (0x3ff >> 4)) << 4 | p[2] >> (8 - 4); + uint8_t d = p[2] & 0x0f; + native->dir = static_cast<DIR>(d); + return d < 8; +} + +// x0xx xxxx xxy0 yyyy yyyy x1xx xxxx xxy1 yyyy yyyy +struct NetPosition2 +{ + Byte data[5]; +}; + +struct Position2 +{ + uint16_t x0, y0; + uint16_t x1, y1; +}; + +inline +bool native_to_network(NetPosition2 *network, Position2 native) +{ + uint16_t x0 = native.x0; + uint16_t y0 = native.y0; + uint16_t x1 = native.x1; + uint16_t y1 = native.y1; + + uint8_t *p = reinterpret_cast<uint8_t *>(network); + p[0] = x0 >> 2; + p[1] = (x0 << 6) | ((y0 >> 4) & 0x3f); + p[2] = (y0 << 4) | ((x1 >> 6) & 0x0f); + p[3] = (x1 << 2) | ((y1 >> 8) & 0x03); + p[4] = y1; + + return x0 < 1024 && y0 < 1024 && x1 < 1024 && y1 < 1024; +} + +inline +bool network_to_native(Position2 *native, NetPosition2 network) +{ + const uint8_t *p = reinterpret_cast<const uint8_t *>(&network); + native->x0 = (p[0] & (0x3ff >> 2)) << 2 | p[1] >> (8 - 2); + native->y0 = (p[1] & (0x3ff >> 4)) << 4 | p[2] >> (8 - 4); + native->x1 = (p[2] & (0x3ff >> 6)) << 6 | p[3] >> (8 - 6); + native->y1 = (p[3] & (0x3ff >> 8)) << 8 | p[4] >> (8 - 8); + return true; +} + +struct IOff2; +struct SOff1; + +struct IOff0 +{ + uint16_t index; + + bool ok() const + { return get0() < MAX_INVENTORY; } + uint16_t get0() const + { return index; } + static IOff0 from(uint16_t i) + { return IOff0{i}; } + static IteratorPair<ValueIterator<IOff0>> iter() + { return {IOff0::from(0), IOff0::from(MAX_INVENTORY)}; } + friend uint16_t convert_for_printf(IOff0 i0) { return i0.index; } + + IOff0& operator ++() { ++index; return *this; } + friend bool operator == (IOff0 l, IOff0 r) { return l.index == r.index; } + friend bool operator != (IOff0 l, IOff0 r) { return !(l == r); } + IOff2 shift() const; + + IOff0() : index(0) {} +private: + explicit IOff0(uint16_t i) : index(i) {} +}; + +struct SOff0 +{ + uint16_t index; + + bool ok() const + { return get0() < MAX_STORAGE; } + uint16_t get0() const + { return index; } + static SOff0 from(uint16_t i) + { return SOff0{i}; } + static IteratorPair<ValueIterator<SOff0>> iter() + { return {SOff0::from(0), SOff0::from(MAX_STORAGE)}; } + friend uint16_t convert_for_printf(SOff0 s0) { return s0.index; } + + SOff0& operator ++() { ++index; return *this; } + friend bool operator == (SOff0 l, SOff0 r) { return l.index == r.index; } + friend bool operator != (SOff0 l, SOff0 r) { return !(l == r); } + SOff1 shift() const; + + SOff0() : index(0) {} +private: + explicit SOff0(uint16_t i) : index(i) {} +}; + +struct IOff2 +{ + uint16_t index; + + bool ok() const + { return get2() < MAX_INVENTORY; } + uint16_t get2() const + { return index - 2; } + static IOff2 from(uint16_t i) + { return IOff2{static_cast<uint16_t>(i + 2)}; } + static IteratorPair<ValueIterator<IOff2>> iter() + { return {IOff2::from(0), IOff2::from(MAX_INVENTORY)}; } + + IOff2& operator ++() { ++index; return *this; } + friend bool operator == (IOff2 l, IOff2 r) { return l.index == r.index; } + friend bool operator != (IOff2 l, IOff2 r) { return !(l == r); } + IOff0 unshift() const + { return IOff0::from(get2()); } + + IOff2() : index(0) {} +private: + explicit IOff2(uint16_t i) : index(i) {} +}; + +struct SOff1 +{ + uint16_t index; + + bool ok() const + { return get1() < MAX_STORAGE; } + uint16_t get1() const + { return index - 1; } + static SOff1 from(uint16_t i) + { return SOff1{static_cast<uint16_t>(i + 1)}; } + static IteratorPair<ValueIterator<SOff1>> iter() + { return {SOff1::from(0), SOff1::from(MAX_STORAGE)}; } + + SOff1& operator ++() { ++index; return *this; } + friend bool operator == (SOff1 l, SOff1 r) { return l.index == r.index; } + friend bool operator != (SOff1 l, SOff1 r) { return !(l == r); } + SOff0 unshift() const + { return SOff0::from(get1()); } + + SOff1() : index(0) {} +private: + explicit SOff1(uint16_t i) : index(i) {} +}; + +inline IOff2 IOff0::shift() const +{ return IOff2::from(get0()); } +inline SOff1 SOff0::shift() const +{ return SOff1::from(get0()); } + +inline +bool native_to_network(Little16 *network, IOff2 native) +{ + return native_to_network(network, native.index); +} + +inline +bool network_to_native(IOff2 *native, Little16 network) +{ + return network_to_native(&native->index, network); +} + +inline +bool native_to_network(Little16 *network, SOff1 native) +{ + return native_to_network(network, native.index); +} + +inline +bool network_to_native(SOff1 *native, Little16 network) +{ + return network_to_native(&native->index, network); +} +} // namespace tmwa diff --git a/src/map/fwd.hpp b/src/map/fwd.hpp new file mode 100644 index 0000000..fe66b15 --- /dev/null +++ b/src/map/fwd.hpp @@ -0,0 +1,57 @@ +#pragma once +// map/fwd.hpp - list of type names for map server +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +// meh, add more when I feel like it +class BlockId; +struct block_list; +struct map_session_data; +struct npc_data; +struct mob_data; +struct flooritem_data; +struct invocation; +struct map_local; +class npc_data_script; +class npc_data_shop; +class npc_data_warp; +class npc_data_message; +struct NpcEvent; + +struct item_data; + +// magic +struct fun_t; +struct op_t; +struct expr_t; +struct val_t; +struct location_t; +struct area_t; +struct spell_t; +struct invocation; +struct teleport_anchor_t; +struct env_t; +struct magic_conf_t; +struct component_t; +struct effect_set_t; +} // namespace tmwa diff --git a/src/map/grfio.cpp b/src/map/grfio.cpp index c3d1e40..4a1656b 100644 --- a/src/map/grfio.cpp +++ b/src/map/grfio.cpp @@ -20,28 +20,29 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <sys/stat.h> - #include <fcntl.h> #include <unistd.h> #include <cassert> -#include <cstdio> -#include <cstring> #include <map> #include "../strings/mstring.hpp" #include "../strings/rstring.hpp" #include "../strings/astring.hpp" +#include "../strings/zstring.hpp" #include "../io/cxxstdio.hpp" #include "../io/read.hpp" #include "../mmo/extract.hpp" +#include "../mmo/mmo.hpp" #include "../poison.hpp" + +namespace tmwa +{ static std::map<MapName, RString> resnametable; @@ -50,7 +51,7 @@ bool load_resnametable(ZString filename) io::ReadFile in(filename); if (!in.is_open()) { - FPRINTF(stderr, "Missing %s\n", filename); + FPRINTF(stderr, "Missing %s\n"_fmt, filename); return false; } @@ -63,7 +64,7 @@ bool load_resnametable(ZString filename) if (!extract(line, record<'#'>(&key, &value))) { - PRINTF("Bad resnametable line: %s\n", line); + PRINTF("Bad resnametable line: %s\n"_fmt, line); rv = false; continue; } @@ -85,7 +86,7 @@ std::vector<uint8_t> grfio_reads(MapName rname) { MString lfname_; // TODO ... instead of here - lfname_ += "data/"; + lfname_ += "data/"_s; lfname_ += grfio_resnametable(rname); AString lfname = AString(lfname_); @@ -93,7 +94,7 @@ std::vector<uint8_t> grfio_reads(MapName rname) int fd = open(lfname.c_str(), O_RDONLY); if (fd == -1) { - FPRINTF(stderr, "Resource %s (file %s) not found\n", + FPRINTF(stderr, "Resource %s (file %s) not found\n"_fmt, rname, lfname); return {}; } @@ -105,3 +106,4 @@ std::vector<uint8_t> grfio_reads(MapName rname) close(fd); return buffer; } +} // namespace tmwa diff --git a/src/map/grfio.hpp b/src/map/grfio.hpp index 9b6d5e2..d2ab058 100644 --- a/src/map/grfio.hpp +++ b/src/map/grfio.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_GRFIO_HPP -#define TMWA_MAP_GRFIO_HPP +#pragma once // grfio.hpp - Don't read GRF files, just name-map .wlk files. // // Copyright © ????-2004 Athena Dev Teams @@ -21,19 +20,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdint> +#include <cstdint> -# include <vector> +#include <vector> -# include "../mmo/mmo.hpp" +#include "../strings/fwd.hpp" +#include "../mmo/fwd.hpp" + + +namespace tmwa +{ bool load_resnametable(ZString filename); /// Load a resource into memory, subject to data/resnametable.txt. /// Normally, resourcename is xxx-y.gat and the file is xxx-y.wlk. /// Currently there is exactly one .wlk per .gat, but multiples are fine. std::vector<uint8_t> grfio_reads(MapName resourcename); - -#endif // TMWA_MAP_GRFIO_HPP +} // namespace tmwa diff --git a/src/map/intif.cpp b/src/map/intif.cpp index 2cae2ad..314db24 100644 --- a/src/map/intif.cpp +++ b/src/map/intif.cpp @@ -20,18 +20,21 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <cstdlib> -#include <cstring> - #include "../compat/nullpo.hpp" #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" +#include "../strings/literal.hpp" #include "../io/cxxstdio.hpp" -#include "../mmo/socket.hpp" +#include "../net/packets.hpp" +#include "../net/socket.hpp" + +#include "../mmo/mmo.hpp" + +#include "../proto2/char-map.hpp" #include "battle.hpp" #include "chrif.hpp" @@ -43,32 +46,19 @@ #include "../poison.hpp" -static -const int packet_len_table[] = -{ - -1, -1, 27, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1, 7, 0, 0, 0, 0, 0, 0, -1, 11, 0, 0, 0, 0, 0, 0, - 35, -1, 11, 15, 34, 29, 7, -1, 0, 0, 0, 0, 0, 0, 0, 0, - 10, -1, 15, 0, 79, 19, 7, -1, 0, -1, -1, -1, 14, 67, 186, -1, - 9, 9, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 11, -1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - +namespace tmwa +{ //----------------------------------------------------------------- // inter serverへの送信 // Message for all GMs on all map servers void intif_GMmessage(XString mes) { - WFIFOW(char_session, 0) = 0x3000; - size_t len = mes.size() + 1; - WFIFOW(char_session, 2) = 4 + len; - WFIFO_STRING(char_session, 4, mes, len); - WFIFOSET(char_session, WFIFOW(char_session, 2)); + if (!char_session) + return; + + send_packet_repeatonly<0x3000, 4, 1>(char_session, mes); } // The transmission of Wisp/Page to inter-server (player not found on this server) @@ -76,65 +66,69 @@ void intif_wis_message(dumb_ptr<map_session_data> sd, CharName nick, ZString mes { nullpo_retv(sd); - size_t mes_len = mes.size() + 1; - WFIFOW(char_session, 0) = 0x3001; - WFIFOW(char_session, 2) = mes_len + 52; - WFIFO_STRING(char_session, 4, sd->status_key.name.to__actual(), 24); - WFIFO_STRING(char_session, 28, nick.to__actual(), 24); - WFIFO_STRING(char_session, 52, mes, mes_len); - WFIFOSET(char_session, WFIFOW(char_session, 2)); + if (!char_session) + return; + + Packet_Head<0x3001> head_01; + head_01.from_char_name = sd->status_key.name; + head_01.to_char_name = nick; + send_vpacket<0x3001, 52, 1>(char_session, head_01, mes); if (battle_config.etc_log) - PRINTF("intif_wis_message from %s to %s)\n", + PRINTF("intif_wis_message from %s to %s)\n"_fmt, sd->status_key.name, nick); } // The reply of Wisp/page static -void intif_wis_replay(int id, int flag) +void intif_wis_replay(CharId id, int flag) { - WFIFOW(char_session, 0) = 0x3002; - WFIFOL(char_session, 2) = id; - WFIFOB(char_session, 6) = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - WFIFOSET(char_session, 7); + if (!char_session) + return; + + Packet_Fixed<0x3002> fixed_02; + fixed_02.char_id = id; + fixed_02.flag = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + send_fpacket<0x3002, 7>(char_session, fixed_02); if (battle_config.etc_log) - PRINTF("intif_wis_replay: id: %d, flag:%d\n", id, flag); + PRINTF("intif_wis_replay: id: %d, flag:%d\n"_fmt, id, flag); } // The transmission of GM only Wisp/Page from server to inter-server -void intif_wis_message_to_gm(CharName Wisp_name, int min_gm_level, ZString mes) +void intif_wis_message_to_gm(CharName Wisp_name, GmLevel min_gm_level, ZString mes) { - size_t mes_len = mes.size() + 1; - WFIFOW(char_session, 0) = 0x3003; - WFIFOW(char_session, 2) = mes_len + 30; - WFIFO_STRING(char_session, 4, Wisp_name.to__actual(), 24); - WFIFOW(char_session, 28) = min_gm_level; - WFIFO_STRING(char_session, 30, mes, mes_len); - WFIFOSET(char_session, WFIFOW(char_session, 2)); + if (!char_session) + return; + + Packet_Head<0x3003> head_03; + head_03.char_name = Wisp_name; + head_03.min_gm_level = min_gm_level; + send_vpacket<0x3003, 30, 1>(char_session, head_03, mes); if (battle_config.etc_log) - PRINTF("intif_wis_message_to_gm: from: '%s', min level: %d, message: '%s'.\n", + PRINTF("intif_wis_message_to_gm: from: '%s', min level: %d, message: '%s'.\n"_fmt, Wisp_name, min_gm_level, mes); } // アカウント変数送信 void intif_saveaccountreg(dumb_ptr<map_session_data> sd) { - int j, p; - nullpo_retv(sd); + if (!char_session) + return; + assert (sd->status.account_reg_num < ACCOUNT_REG_NUM); - WFIFOW(char_session, 0) = 0x3004; - WFIFOL(char_session, 4) = sd->bl_id; - for (j = 0, p = 8; j < sd->status.account_reg_num; j++, p += 36) + Packet_Head<0x3004> head_04; + head_04.account_id = block_to_account(sd->bl_id); + std::vector<Packet_Repeat<0x3004>> repeat_04(sd->status.account_reg_num); + for (size_t j = 0; j < sd->status.account_reg_num; j++) { - WFIFO_STRING(char_session, p, sd->status.account_reg[j].str, 32); - WFIFOL(char_session, p + 32) = sd->status.account_reg[j].value; + repeat_04[j].name = sd->status.account_reg[j].str; + repeat_04[j].value = sd->status.account_reg[j].value; } - WFIFOW(char_session, 2) = p; - WFIFOSET(char_session, p); + send_vpacket<0x3004, 8, 36>(char_session, head_04, repeat_04); } // アカウント変数要求 @@ -142,28 +136,36 @@ void intif_request_accountreg(dumb_ptr<map_session_data> sd) { nullpo_retv(sd); - WFIFOW(char_session, 0) = 0x3005; - WFIFOL(char_session, 2) = sd->bl_id; - WFIFOSET(char_session, 6); + if (!char_session) + return; + + Packet_Fixed<0x3005> fixed_05; + fixed_05.account_id = block_to_account(sd->bl_id); + send_fpacket<0x3005, 6>(char_session, fixed_05); } // 倉庫データ要求 -void intif_request_storage(int account_id) +void intif_request_storage(AccountId account_id) { - WFIFOW(char_session, 0) = 0x3010; - WFIFOL(char_session, 2) = account_id; - WFIFOSET(char_session, 6); + if (!char_session) + return; + + Packet_Fixed<0x3010> fixed_10; + fixed_10.account_id = account_id; + send_fpacket<0x3010, 6>(char_session, fixed_10); } // 倉庫データ送信 -void intif_send_storage(struct storage *stor) +void intif_send_storage(Storage *stor) { nullpo_retv(stor); - WFIFOW(char_session, 0) = 0x3011; - WFIFOW(char_session, 2) = sizeof(struct storage) + 8; - WFIFOL(char_session, 4) = stor->account_id; - WFIFO_STRUCT(char_session, 8, *stor); - WFIFOSET(char_session, WFIFOW(char_session, 2)); + if (!char_session) + return; + + Packet_Payload<0x3011> payload_11; + payload_11.account_id = stor->account_id; + payload_11.storage = *stor; + send_ppacket<0x3011>(char_session, payload_11); } // パーティ作成要求 @@ -171,95 +173,116 @@ void intif_create_party(dumb_ptr<map_session_data> sd, PartyName name) { nullpo_retv(sd); - WFIFOW(char_session, 0) = 0x3020; - WFIFOL(char_session, 2) = sd->status_key.account_id; - WFIFO_STRING(char_session, 6, name, 24); - WFIFO_STRING(char_session, 30, sd->status_key.name.to__actual(), 24); - WFIFO_STRING(char_session, 54, sd->bl_m->name_, 16); - WFIFOW(char_session, 70) = sd->status.base_level; - WFIFOSET(char_session, 72); + if (!char_session) + return; + + Packet_Fixed<0x3020> fixed_20; + fixed_20.account_id = sd->status_key.account_id; + fixed_20.party_name = name; + fixed_20.char_name = sd->status_key.name; + fixed_20.map_name = sd->bl_m->name_; + fixed_20.level = sd->status.base_level; + send_fpacket<0x3020, 72>(char_session, fixed_20); } // パーティ情報要求 -void intif_request_partyinfo(int party_id) +void intif_request_partyinfo(PartyId party_id) { - WFIFOW(char_session, 0) = 0x3021; - WFIFOL(char_session, 2) = party_id; - WFIFOSET(char_session, 6); + if (!char_session) + return; + + Packet_Fixed<0x3021> fixed_21; + fixed_21.party_id = party_id; + send_fpacket<0x3021, 6>(char_session, fixed_21); } // パーティ追加要求 -void intif_party_addmember(int party_id, int account_id) +void intif_party_addmember(PartyId party_id, AccountId account_id) { + if (!char_session) + return; + dumb_ptr<map_session_data> sd; - sd = map_id2sd(account_id); - if (sd != NULL) + sd = map_id2sd(account_to_block(account_id)); + if (sd != nullptr) { - WFIFOW(char_session, 0) = 0x3022; - WFIFOL(char_session, 2) = party_id; - WFIFOL(char_session, 6) = account_id; - WFIFO_STRING(char_session, 10, sd->status_key.name.to__actual(), 24); - WFIFO_STRING(char_session, 34, sd->bl_m->name_, 16); - WFIFOW(char_session, 50) = sd->status.base_level; - WFIFOSET(char_session, 52); + Packet_Fixed<0x3022> fixed_22; + fixed_22.party_id = party_id; + fixed_22.account_id = account_id; + fixed_22.char_name = sd->status_key.name; + fixed_22.map_name = sd->bl_m->name_; + fixed_22.level = sd->status.base_level; + send_fpacket<0x3022, 52>(char_session, fixed_22); } } // パーティ設定変更 -void intif_party_changeoption(int party_id, int account_id, int exp, int item) -{ - WFIFOW(char_session, 0) = 0x3023; - WFIFOL(char_session, 2) = party_id; - WFIFOL(char_session, 6) = account_id; - WFIFOW(char_session, 10) = exp; - WFIFOW(char_session, 12) = item; - WFIFOSET(char_session, 14); +void intif_party_changeoption(PartyId party_id, AccountId account_id, int exp, int item) +{ + if (!char_session) + return; + + Packet_Fixed<0x3023> fixed_23; + fixed_23.party_id = party_id; + fixed_23.account_id = account_id; + fixed_23.exp = exp; + fixed_23.item = item; + send_fpacket<0x3023, 14>(char_session, fixed_23); } // パーティ脱退要求 -void intif_party_leave(int party_id, int account_id) +void intif_party_leave(PartyId party_id, AccountId account_id) { - WFIFOW(char_session, 0) = 0x3024; - WFIFOL(char_session, 2) = party_id; - WFIFOL(char_session, 6) = account_id; - WFIFOSET(char_session, 10); + if (!char_session) + return; + + Packet_Fixed<0x3024> fixed_24; + fixed_24.party_id = party_id; + fixed_24.account_id = account_id; + send_fpacket<0x3024, 10>(char_session, fixed_24); } // パーティ移動要求 void intif_party_changemap(dumb_ptr<map_session_data> sd, int online) { - if (sd != NULL) + if (!char_session) + return; + + if (sd != nullptr) { - WFIFOW(char_session, 0) = 0x3025; - WFIFOL(char_session, 2) = sd->status.party_id; - WFIFOL(char_session, 6) = sd->status_key.account_id; - WFIFO_STRING(char_session, 10, sd->bl_m->name_, 16); - WFIFOB(char_session, 26) = online; - WFIFOW(char_session, 27) = sd->status.base_level; - WFIFOSET(char_session, 29); + Packet_Fixed<0x3025> fixed_25; + fixed_25.party_id = sd->status.party_id; + fixed_25.account_id = sd->status_key.account_id; + fixed_25.map_name = sd->bl_m->name_; + fixed_25.online = online; + fixed_25.level = sd->status.base_level; + send_fpacket<0x3025, 29>(char_session, fixed_25); } } // パーティ会話送信 -void intif_party_message(int party_id, int account_id, XString mes) -{ - size_t len = mes.size() + 1; - WFIFOW(char_session, 0) = 0x3027; - WFIFOW(char_session, 2) = len + 12; - WFIFOL(char_session, 4) = party_id; - WFIFOL(char_session, 8) = account_id; - WFIFO_STRING(char_session, 12, mes, len); - WFIFOSET(char_session, len + 12); +void intif_party_message(PartyId party_id, AccountId account_id, XString mes) +{ + if (!char_session) + return; + + Packet_Head<0x3027> head_27; + head_27.party_id = party_id; + head_27.account_id = account_id; + send_vpacket<0x3027, 12, 1>(char_session, head_27, mes); } // パーティ競合チェック要求 -void intif_party_checkconflict(int party_id, int account_id, CharName nick) +void intif_party_checkconflict(PartyId party_id, AccountId account_id, CharName nick) { - WFIFOW(char_session, 0) = 0x3028; - WFIFOL(char_session, 2) = party_id; - WFIFOL(char_session, 6) = account_id; - WFIFO_STRING(char_session, 10, nick.to__actual(), 24); - WFIFOSET(char_session, 34); + if (!char_session) + return; + + Packet_Fixed<0x3028> fixed_28; + fixed_28.party_id = party_id; + fixed_28.account_id = account_id; + fixed_28.char_name = nick; + send_fpacket<0x3028, 34>(char_session, fixed_28); } //----------------------------------------------------------------- @@ -267,55 +290,52 @@ void intif_party_checkconflict(int party_id, int account_id, CharName nick) // Wisp/Page reception static -int intif_parse_WisMessage(Session *s) +int intif_parse_WisMessage(Session *, const Packet_Head<0x3801>& head, AString& buf) { // rewritten by [Yor] dumb_ptr<map_session_data> sd; - CharName from = stringish<CharName>(RFIFO_STRING<24>(s, 8)); - CharName to = stringish<CharName>(RFIFO_STRING<24>(s, 32)); - - size_t len = RFIFOW(s, 2) - 56; - AString buf = RFIFO_STRING(s, 56, len); + CharName from = head.src_char_name; + CharName to = head.dst_char_name; if (battle_config.etc_log) { - PRINTF("intif_parse_wismessage: id: %d, from: %s, to: %s\n", - RFIFOL(s, 4), - from, - to); + PRINTF("intif_parse_wismessage: id: %d, from: %s, to: %s\n"_fmt, + head.whisper_id, + from, + to); } sd = map_nick2sd(to); // Searching destination player - if (sd != NULL && sd->status_key.name == to) + if (sd != nullptr && sd->status_key.name == to) { // exactly same name (inter-server have checked the name before) { // if source player not found in ignore list { clif_wis_message(sd->sess, from, buf); - intif_wis_replay(RFIFOL(s, 4), 0); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + intif_wis_replay(head.whisper_id, 0); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target } } } else - intif_wis_replay(RFIFOL(s, 4), 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target + intif_wis_replay(head.whisper_id, 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target return 0; } // Wisp/page transmission result reception static -int intif_parse_WisEnd(Session *s) +int intif_parse_WisEnd(Session *, const Packet_Fixed<0x3802>& fixed) { dumb_ptr<map_session_data> sd; - CharName name = stringish<CharName>(RFIFO_STRING<24>(s, 2)); - uint8_t flag = RFIFOB(s, 26); + CharName name = fixed.sender_char_name; + uint8_t flag = fixed.flag; if (battle_config.etc_log) // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target - PRINTF("intif_parse_wisend: player: %s, flag: %d\n", + PRINTF("intif_parse_wisend: player: %s, flag: %d\n"_fmt, name, flag); sd = map_nick2sd(name); - if (sd != NULL) + if (sd != nullptr) clif_wis_end(sd->sess, flag); return 0; @@ -323,19 +343,11 @@ int intif_parse_WisEnd(Session *s) // Received wisp message from map-server via char-server for ALL gm static -void mapif_parse_WisToGM(Session *s) +void mapif_parse_WisToGM(Session *, const Packet_Head<0x3803>& head, AString& message) { // 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B - int min_gm_level, len; - - if (RFIFOW(s, 2) - 30 <= 0) - return; - - len = RFIFOW(s, 2) - 30; - - min_gm_level = RFIFOW(s, 28); - CharName Wisp_name = stringish<CharName>(RFIFO_STRING<24>(s, 4)); - AString message = RFIFO_STRING(s, 30, len); + GmLevel min_gm_level = head.min_gm_level; + CharName Wisp_name = head.char_name; // information is sended to all online GM for (io::FD i : iter_fds()) { @@ -345,7 +357,7 @@ void mapif_parse_WisToGM(Session *s) dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get())); if (pl_sd && pl_sd->state.auth) { - if (pc_isGM(pl_sd) >= min_gm_level) + if (pc_isGM(pl_sd).satisfies(min_gm_level)) clif_wis_message(s2, Wisp_name, message); } } @@ -353,65 +365,57 @@ void mapif_parse_WisToGM(Session *s) // アカウント変数通知 static -int intif_parse_AccountReg(Session *s) +int intif_parse_AccountReg(Session *, const Packet_Head<0x3804>& head, const std::vector<Packet_Repeat<0x3804>>& repeat) { - int j, p; - dumb_ptr<map_session_data> sd = map_id2sd(RFIFOL(s, 4)); - if (sd == NULL) + dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(head.account_id)); + if (sd == nullptr) return 1; - for (p = 8, j = 0; p < RFIFOW(s, 2) && j < ACCOUNT_REG_NUM; - p += 36, j++) + + size_t jlim = std::min(ACCOUNT_REG_NUM, repeat.size()); + for (size_t j = 0; j < jlim; j++) { - sd->status.account_reg[j].str = stringish<VarName>(RFIFO_STRING<32>(s, p)); - sd->status.account_reg[j].value = RFIFOL(s, p + 32); + sd->status.account_reg[j].str = repeat[j].name; + sd->status.account_reg[j].value = repeat[j].value; } - sd->status.account_reg_num = j; -// PRINTF("intif: accountreg\n"); + sd->status.account_reg_num = jlim; return 0; } // 倉庫データ受信 static -int intif_parse_LoadStorage(Session *s) +int intif_parse_LoadStorage(Session *, const Packet_Payload<0x3810>& payload) { - struct storage *stor; + Storage *stor; dumb_ptr<map_session_data> sd; - sd = map_id2sd(RFIFOL(s, 4)); - if (sd == NULL) + sd = map_id2sd(account_to_block(payload.account_id)); + if (sd == nullptr) { if (battle_config.error_log) - PRINTF("intif_parse_LoadStorage: user not found %d\n", - RFIFOL(s, 4)); + PRINTF("intif_parse_LoadStorage: user not found %d\n"_fmt, + payload.account_id); return 1; } - stor = account2storage(RFIFOL(s, 4)); + stor = account2storage(payload.account_id); if (stor->storage_status == 1) { // Already open.. lets ignore this update if (battle_config.error_log) - PRINTF("intif_parse_LoadStorage: storage received for a client already open (User %d:%d)\n", - sd->status_key.account_id, sd->status_key.char_id); + PRINTF("intif_parse_LoadStorage: storage received for a client already open (User %d:%d)\n"_fmt, + sd->status_key.account_id, sd->status_key.char_id); return 1; } if (stor->dirty) { // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex] if (battle_config.error_log) - PRINTF("intif_parse_LoadStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", - sd->status_key.account_id, sd->status_key.char_id); + PRINTF("intif_parse_LoadStorage: received storage for an already modified non-saved storage! (User %d:%d)\n"_fmt, + sd->status_key.account_id, sd->status_key.char_id); return 1; } - if (RFIFOW(s, 2) - 8 != sizeof(struct storage)) - { - if (battle_config.error_log) - PRINTF("intif_parse_LoadStorage: data size error %d %zu\n", - RFIFOW(s, 2) - 8, sizeof(struct storage)); - return 1; - } if (battle_config.save_log) - PRINTF("intif_openstorage: %d\n", RFIFOL(s, 4)); - RFIFO_STRUCT(s, 8, *stor); + PRINTF("intif_openstorage: %d\n"_fmt, payload.account_id); + *stor = payload.storage; stor->dirty = 0; stor->storage_status = 1; sd->state.storage_open = 1; @@ -424,199 +428,273 @@ int intif_parse_LoadStorage(Session *s) // 倉庫データ送信成功 static -void intif_parse_SaveStorage(Session *s) +void intif_parse_SaveStorage(Session *, const Packet_Fixed<0x3811>& fixed) { if (battle_config.save_log) - PRINTF("intif_savestorage: done %d %d\n", RFIFOL(s, 2), - RFIFOB(s, 6)); - storage_storage_saved(RFIFOL(s, 2)); + PRINTF("intif_savestorage: done %d %d\n"_fmt, fixed.account_id, + fixed.unknown); + storage_storage_saved(fixed.account_id); } // パーティ作成可否 static -void intif_parse_PartyCreated(Session *s) +void intif_parse_PartyCreated(Session *, const Packet_Fixed<0x3820>& fixed) { if (battle_config.etc_log) - PRINTF("intif: party created\n"); - int account_id = RFIFOL(s, 2); - int fail = RFIFOB(s, 6); - int party_id = RFIFOL(s, 7); - PartyName name = stringish<PartyName>(RFIFO_STRING<24>(s, 11)); + PRINTF("intif: party created\n"_fmt); + AccountId account_id = fixed.account_id; + int fail = fixed.error; + PartyId party_id = fixed.party_id; + PartyName name = fixed.party_name; party_created(account_id, fail, party_id, name); } // パーティ情報 static -void intif_parse_PartyInfo(Session *s) +void intif_parse_PartyInfo(Session *, const Packet_Head<0x3821>& head, bool has_opt, const Packet_Option<0x3821>& option) { - if (RFIFOW(s, 2) == 8) + if (!has_opt) { if (battle_config.error_log) - PRINTF("intif: party noinfo %d\n", RFIFOL(s, 4)); - party_recv_noinfo(RFIFOL(s, 4)); + PRINTF("intif: party noinfo %d\n"_fmt, head.party_id); + party_recv_noinfo(head.party_id); return; } -// PRINTF("intif: party info %d\n",RFIFOL(fd,4)); - if (RFIFOW(s, 2) != sizeof(struct party) + 4) - { - if (battle_config.error_log) - PRINTF("intif: party info : data size error %d %d %zu\n", - RFIFOL(s, 4), RFIFOW(s, 2), - sizeof(struct party) + 4); - } - party p {}; - RFIFO_STRUCT(s, 4, p); - party_recv_info(&p); + PartyId pi = head.party_id; + PartyMost pm = option.party_most; + PartyPair pp; + pp.party_id = pi; + pp.party_most = ± + party_recv_info(pp); } // パーティ追加通知 static -void intif_parse_PartyMemberAdded(Session *s) +void intif_parse_PartyMemberAdded(Session *, const Packet_Fixed<0x3822>& fixed) { if (battle_config.etc_log) - PRINTF("intif: party member added %d %d %d\n", RFIFOL(s, 2), - RFIFOL(s, 6), RFIFOB(s, 10)); - party_member_added(RFIFOL(s, 2), RFIFOL(s, 6), RFIFOB(s, 10)); + PRINTF("intif: party member added %d %d %d\n"_fmt, fixed.party_id, + fixed.account_id, fixed.flag); + party_member_added(fixed.party_id, fixed.account_id, fixed.flag); } // パーティ設定変更通知 static -void intif_parse_PartyOptionChanged(Session *s) +void intif_parse_PartyOptionChanged(Session *, const Packet_Fixed<0x3823>& fixed) { - party_optionchanged(RFIFOL(s, 2), RFIFOL(s, 6), RFIFOW(s, 10), - RFIFOW(s, 12), RFIFOB(s, 14)); + party_optionchanged(fixed.party_id, fixed.account_id, fixed.exp, + fixed.item, fixed.flag); } // パーティ脱退通知 static -void intif_parse_PartyMemberLeaved(Session *s) +void intif_parse_PartyMemberLeaved(Session *, const Packet_Fixed<0x3824>& fixed) { - int party_id = RFIFOL(s, 2); - int account_id = RFIFOL(s, 6); - CharName name = stringish<CharName>(RFIFO_STRING<24>(s, 10)); + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + CharName name = fixed.char_name; if (battle_config.etc_log) - PRINTF("intif: party member leaved %d %d %s\n", + PRINTF("intif: party member leaved %d %d %s\n"_fmt, party_id, account_id, name); party_member_leaved(party_id, account_id, name); } // パーティ解散通知 static -void intif_parse_PartyBroken(Session *s) +void intif_parse_PartyBroken(Session *, const Packet_Fixed<0x3826>& fixed) { - party_broken(RFIFOL(s, 2)); + party_broken(fixed.party_id); } // パーティ移動通知 static -void intif_parse_PartyMove(Session *s) +void intif_parse_PartyMove(Session *, const Packet_Fixed<0x3825>& fixed) { - int party_id = RFIFOL(s, 2); - int account_id = RFIFOL(s, 6); - MapName map = stringish<MapName>(RFIFO_STRING<16>(s, 10)); - uint8_t online = RFIFOB(s, 26); - uint16_t lv = RFIFOW(s, 27); + PartyId party_id = fixed.party_id; + AccountId account_id = fixed.account_id; + MapName map = fixed.map_name; + uint8_t online = fixed.online; + uint16_t lv = fixed.level; party_recv_movemap(party_id, account_id, map, online, lv); } // パーティメッセージ static -void intif_parse_PartyMessage(Session *s) +void intif_parse_PartyMessage(Session *, const Packet_Head<0x3827>& head, AString& buf) { - size_t len = RFIFOW(s, 2) - 12; - AString buf = RFIFO_STRING(s, 12, len); - party_recv_message(RFIFOL(s, 4), RFIFOL(s, 8), buf); + party_recv_message(head.party_id, head.account_id, buf); } //----------------------------------------------------------------- // inter serverからの通信 // エラーがあれば0(false)を返すこと // パケットが処理できれば1,パケット長が足りなければ2を返すこと -int intif_parse(Session *s) -{ - int packet_len; - int cmd = RFIFOW(s, 0); - // パケットのID確認 - if (cmd < 0x3800 - || cmd >= - 0x3800 + (sizeof(packet_len_table) / sizeof(packet_len_table[0])) - || packet_len_table[cmd - 0x3800] == 0) - { - return 0; - } - // パケットの長さ確認 - packet_len = packet_len_table[cmd - 0x3800]; - if (packet_len == -1) - { - if (RFIFOREST(s) < 4) - return 2; - packet_len = RFIFOW(s, 2); - } -// if(battle_config.etc_log) -// PRINTF("intif_parse %d %x %d %d\n",fd,cmd,packet_len,RFIFOREST(fd)); - if (RFIFOREST(s) < packet_len) - { - return 2; - } - // 処理分岐 - switch (cmd) +RecvResult intif_parse(Session *s, uint16_t packet_id) +{ + RecvResult rv; + + switch (packet_id) { case 0x3800: { - AString mes = RFIFO_STRING(s, 4, packet_len - 4); - clif_GMmessage(NULL, mes, 0); - } + AString mes; + rv = recv_packet_repeatonly<0x3800, 4, 1>(s, mes); + if (rv != RecvResult::Complete) + return rv; + + clif_GMmessage(nullptr, mes, 0); break; + } case 0x3801: - intif_parse_WisMessage(s); + { + Packet_Head<0x3801> head; + AString repeat; + rv = recv_vpacket<0x3801, 56, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_WisMessage(s, head, repeat); break; + } case 0x3802: - intif_parse_WisEnd(s); + { + Packet_Fixed<0x3802> fixed; + rv = recv_fpacket<0x3802, 27>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_WisEnd(s, fixed); break; + } case 0x3803: - mapif_parse_WisToGM(s); + { + Packet_Head<0x3803> head; + AString repeat; + rv = recv_vpacket<0x3803, 30, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + mapif_parse_WisToGM(s, head, repeat); break; + } case 0x3804: - intif_parse_AccountReg(s); + { + Packet_Head<0x3804> head; + std::vector<Packet_Repeat<0x3804>> repeat; + rv = recv_vpacket<0x3804, 8, 36>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_AccountReg(s, head, repeat); break; + } case 0x3810: - intif_parse_LoadStorage(s); + { + Packet_Payload<0x3810> payload; + rv = recv_ppacket<0x3810>(s, payload); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_LoadStorage(s, payload); break; + } case 0x3811: - intif_parse_SaveStorage(s); + { + Packet_Fixed<0x3811> fixed; + rv = recv_fpacket<0x3811, 7>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_SaveStorage(s, fixed); break; + } case 0x3820: - intif_parse_PartyCreated(s); + { + Packet_Fixed<0x3820> fixed; + rv = recv_fpacket<0x3820, 35>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyCreated(s, fixed); break; + } case 0x3821: - intif_parse_PartyInfo(s); + { + Packet_Head<0x3821> head; + bool has_opt; + Packet_Option<0x3821> option; + rv = recv_opacket<0x3821, 8, sizeof(NetPacket_Option<0x3821>)>(s, head, &has_opt, option); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyInfo(s, head, has_opt, option); break; + } case 0x3822: - intif_parse_PartyMemberAdded(s); + { + Packet_Fixed<0x3822> fixed; + rv = recv_fpacket<0x3822, 11>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyMemberAdded(s, fixed); break; + } case 0x3823: - intif_parse_PartyOptionChanged(s); + { + Packet_Fixed<0x3823> fixed; + rv = recv_fpacket<0x3823, 15>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyOptionChanged(s, fixed); break; + } case 0x3824: - intif_parse_PartyMemberLeaved(s); + { + Packet_Fixed<0x3824> fixed; + rv = recv_fpacket<0x3824, 34>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyMemberLeaved(s, fixed); break; + } case 0x3825: - intif_parse_PartyMove(s); + { + Packet_Fixed<0x3825> fixed; + rv = recv_fpacket<0x3825, 29>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyMove(s, fixed); break; + } case 0x3826: - intif_parse_PartyBroken(s); + { + Packet_Fixed<0x3826> fixed; + rv = recv_fpacket<0x3826, 7>(s, fixed); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyBroken(s, fixed); break; + } case 0x3827: - intif_parse_PartyMessage(s); + { + Packet_Head<0x3827> head; + AString repeat; + rv = recv_vpacket<0x3827, 12, 1>(s, head, repeat); + if (rv != RecvResult::Complete) + return rv; + + intif_parse_PartyMessage(s, head, repeat); break; + } default: - if (battle_config.error_log) - PRINTF("intif_parse : unknown packet %d %x\n", s, - RFIFOW(s, 0)); - return 0; + return RecvResult::Error; } - // パケット読み飛ばし - RFIFOSKIP(s, packet_len); - return 1; + return rv; } +} // namespace tmwa diff --git a/src/map/intif.hpp b/src/map/intif.hpp index 80de797..5be61a9 100644 --- a/src/map/intif.hpp +++ b/src/map/intif.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_INTIF_HPP -#define TMWA_MAP_INTIF_HPP +#pragma once // intif.hpp - Network interface to the internal server. // // Copyright © ????-2004 Athena Dev Teams @@ -21,33 +20,39 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "map.hpp" +#include "../generic/fwd.hpp" -int intif_parse(Session *); +#include "../net/fwd.hpp" + +#include "../mmo/fwd.hpp" + + +namespace tmwa +{ +RecvResult intif_parse(Session *, uint16_t packet_id); void intif_GMmessage(XString mes); void intif_wis_message(dumb_ptr<map_session_data> sd, CharName nick, ZString mes); -void intif_wis_message_to_gm(CharName Wisp_name, int min_gm_level, ZString mes); +void intif_wis_message_to_gm(CharName Wisp_name, GmLevel min_gm_level, ZString mes); void intif_saveaccountreg(dumb_ptr<map_session_data> sd); void intif_request_accountreg(dumb_ptr<map_session_data> sd); -void intif_request_storage(int account_id); -void intif_send_storage(struct storage *stor); +void intif_request_storage(AccountId account_id); +void intif_send_storage(Storage *stor); void intif_create_party(dumb_ptr<map_session_data> sd, PartyName name); -void intif_request_partyinfo(int party_id); -void intif_party_addmember(int party_id, int account_id); -void intif_party_changeoption(int party_id, int account_id, int exp, +void intif_request_partyinfo(PartyId party_id); +void intif_party_addmember(PartyId party_id, AccountId account_id); +void intif_party_changeoption(PartyId party_id, AccountId account_id, int exp, int item); -void intif_party_leave(int party_id, int accound_id); +void intif_party_leave(PartyId party_id, AccountId accound_id); void intif_party_changemap(dumb_ptr<map_session_data> sd, int online); -void intif_party_message(int party_id, int account_id, XString mes); -void intif_party_checkconflict(int party_id, int account_id, CharName nick); - -#endif // TMWA_MAP_INTIF_HPP +void intif_party_message(PartyId party_id, AccountId account_id, XString mes); +void intif_party_checkconflict(PartyId party_id, AccountId account_id, CharName nick); +} // namespace tmwa diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index 4ebb52c..edc9982 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -20,29 +20,27 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <cstdlib> -#include <cstring> - -#include "../compat/nullpo.hpp" +#include <algorithm> #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" #include "../generic/db.hpp" -#include "../generic/random.hpp" #include "../io/cxxstdio.hpp" #include "../io/read.hpp" #include "../mmo/config_parse.hpp" #include "../mmo/extract.hpp" -#include "../mmo/socket.hpp" #include "../poison.hpp" + +namespace tmwa +{ static -Map<int, struct item_data> item_db; +Map<ItemNameId, struct item_data> item_db; // Function declarations @@ -67,7 +65,7 @@ struct item_data *itemdb_searchname(XString str_) ItemName str = stringish<ItemName>(str_); if (XString(str) != str_) return nullptr; - struct item_data *item = NULL; + struct item_data *item = nullptr; for (auto& pair : item_db) itemdb_searchname_sub(&pair.second, str, &item); return item; @@ -77,7 +75,7 @@ struct item_data *itemdb_searchname(XString str_) * DBの存在確認 *------------------------------------------ */ -struct item_data *itemdb_exists(int nameid) +struct item_data *itemdb_exists(ItemNameId nameid) { return item_db.search(nameid); } @@ -86,7 +84,7 @@ struct item_data *itemdb_exists(int nameid) * DBの検索 *------------------------------------------ */ -struct item_data *itemdb_search(int nameid) +struct item_data *itemdb_search(ItemNameId nameid) { struct item_data *id = item_db.search(nameid); if (id) @@ -101,22 +99,7 @@ struct item_data *itemdb_search(int nameid) id->sex = SEX::NEUTRAL; id->elv = 0; - if (nameid > 500 && nameid < 600) - id->type = ItemType::USE; - else if (nameid > 600 && nameid < 700) - id->type = ItemType::_2; - else if ((nameid > 700 && nameid < 1100) || - (nameid > 7000 && nameid < 8000)) - id->type = ItemType::JUNK; - else if (nameid >= 1750 && nameid < 1771) - id->type = ItemType::ARROW; - else if (nameid > 1100 && nameid < 2000) - id->type = ItemType::WEAPON; - else if ((nameid > 2100 && nameid < 3000) || - (nameid > 5000 && nameid < 6000)) - id->type = ItemType::ARMOR; - else if (nameid > 4000 && nameid < 5000) - id->type = ItemType::_6; + id->type = ItemType::JUNK; return id; } @@ -125,7 +108,7 @@ struct item_data *itemdb_search(int nameid) * *------------------------------------------ */ -int itemdb_isequip(int nameid) +int itemdb_isequip(ItemNameId nameid) { ItemType type = itemdb_type(nameid); return !(type == ItemType::USE @@ -155,7 +138,7 @@ int itemdb_isequip2(struct item_data *data) * *------------------------------------------ */ -int itemdb_isequip3(int nameid) +int itemdb_isequip3(ItemNameId nameid) { ItemType type = itemdb_type(nameid); return (type == ItemType::WEAPON @@ -174,7 +157,7 @@ bool itemdb_readdb(ZString filename) if (!in.is_open()) { - PRINTF("can't read %s\n", filename); + PRINTF("can't read %s\n"_fmt, filename); return false; } @@ -220,7 +203,7 @@ bool itemdb_readdb(ZString filename) ) ) { - PRINTF("%s:%d: error: bad item line: %s\n", + PRINTF("%s:%d: error: bad item line: %s\n"_fmt, filename, lines, line); rv = false; continue; @@ -242,8 +225,8 @@ bool itemdb_readdb(ZString filename) id->value_sell = id->value_buy / 2; } - id->use_script = NULL; - id->equip_script = NULL; + id->use_script = nullptr; + id->equip_script = nullptr; if (!tail_part) continue; @@ -254,7 +237,7 @@ bool itemdb_readdb(ZString filename) continue; id->equip_script = parse_script(tail_part, lines, true); } - PRINTF("read %s done (count=%d)\n", filename, ln); + PRINTF("read %s done (count=%d)\n"_fmt, filename, ln); } return rv; @@ -281,3 +264,4 @@ void do_final_itemdb(void) itemdb_final(&pair.second); item_db.clear(); } +} // namespace tmwa diff --git a/src/map/itemdb.hpp b/src/map/itemdb.hpp index 16802da..25b4dad 100644 --- a/src/map/itemdb.hpp +++ b/src/map/itemdb.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_ITEMDB_HPP -#define TMWA_MAP_ITEMDB_HPP +#pragma once // itemdb.hpp - Item definitions. // // Copyright © ????-2004 Athena Dev Teams @@ -21,16 +20,20 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../mmo/mmo.hpp" +#include "../mmo/ids.hpp" +#include "../mmo/mmo.hpp" -# include "map.t.hpp" -# include "script.hpp" +#include "map.t.hpp" +#include "script.hpp" + +namespace tmwa +{ struct item_data { - int nameid; + ItemNameId nameid; ItemName name, jname; int value_buy; int value_sell; @@ -58,47 +61,47 @@ struct random_item_data inline struct item_data *itemdb_searchname(ItemName) = delete; struct item_data *itemdb_searchname(XString name); -struct item_data *itemdb_search(int nameid); -struct item_data *itemdb_exists(int nameid); +// TODO this function should die +struct item_data *itemdb_search(ItemNameId nameid); +struct item_data *itemdb_exists(ItemNameId nameid); inline -ItemType itemdb_type(int n) +ItemType itemdb_type(ItemNameId n) { return itemdb_search(n)->type; } inline -ItemLook itemdb_look(int n) +ItemLook itemdb_look(ItemNameId n) { return itemdb_search(n)->look; } inline -int itemdb_weight(int n) +int itemdb_weight(ItemNameId n) { return itemdb_search(n)->weight; } inline -const ScriptBuffer *itemdb_equipscript(int n) +const ScriptBuffer *itemdb_equipscript(ItemNameId n) { return itemdb_search(n)->equip_script.get(); } inline -int itemdb_wlv(int n) +int itemdb_wlv(ItemNameId n) { return itemdb_search(n)->wlv; } inline -int itemdb_value_sell(int n) +int itemdb_value_sell(ItemNameId n) { return itemdb_search(n)->value_sell; } -int itemdb_isequip(int); +int itemdb_isequip(ItemNameId); int itemdb_isequip2(struct item_data *); -int itemdb_isequip3(int); +int itemdb_isequip3(ItemNameId); void itemdb_reload(void); void do_final_itemdb(void); bool itemdb_readdb(ZString filename); - -#endif // TMWA_MAP_ITEMDB_HPP +} // namespace tmwa diff --git a/src/map/magic-expr-eval.cpp b/src/map/magic-expr-eval.cpp index 36b69f5..0283b8d 100644 --- a/src/map/magic-expr-eval.cpp +++ b/src/map/magic-expr-eval.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/map/magic-expr-eval.hpp b/src/map/magic-expr-eval.hpp index 9b9f5f8..a291fcd 100644 --- a/src/map/magic-expr-eval.hpp +++ b/src/map/magic-expr-eval.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_MAGIC_EXPR_EVAL_HPP -#define TMWA_MAP_MAGIC_EXPR_EVAL_HPP +#pragma once // magic-expr-eval.hpp - Utilities for evaluating magic. // // Copyright © 2004-2011 The Mana World Development Team @@ -20,47 +19,40 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../range/slice.hpp" +#include "../strings/zstring.hpp" -# include "../strings/zstring.hpp" +#include "magic-interpreter.t.hpp" -# include "magic-interpreter.hpp" -/* Helper definitions for dealing with functions and operations */ +namespace tmwa +{ +// TODO kill this like I killed VAR +#define ARGINT(x) args[x].v.v_int +#define ARGDIR(x) args[x].v.v_dir +#define ARGSTR(x) ZString(args[x].v.v_string) +#define ARGENTITY(x) args[x].v.v_entity +#define ARGLOCATION(x) args[x].v.v_location +#define ARGAREA(x) args[x].v.v_area +#define ARGSPELL(x) args[x].v.v_spell +#define ARGINVOCATION(x) args[x].v.v_invocation -int magic_signature_check(ZString opname, ZString funname, ZString signature, - Slice<val_t> args, int line, int column); +#define RESULTINT result->v.v_int +#define RESULTDIR result->v.v_dir +#define RESULTSTR result->v.v_string +#define RESULTENTITY result->v.v_entity +#define RESULTLOCATION result->v.v_location +#define RESULTAREA result->v.v_area +#define RESULTSPELL result->v.v_spell +#define RESULTINVOCATION result->v.v_invocation -void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height, - area_t& area); +#define ARG_TYPE(x) args[x].ty +#define ENTITY_TYPE(x) ARGENTITY(x)->bl_type -# define ARGINT(x) args[x].v.v_int -# define ARGDIR(x) args[x].v.v_dir -# define ARGSTR(x) ZString(args[x].v.v_string) -# define ARGENTITY(x) args[x].v.v_entity -# define ARGLOCATION(x) args[x].v.v_location -# define ARGAREA(x) args[x].v.v_area -# define ARGSPELL(x) args[x].v.v_spell -# define ARGINVOCATION(x) args[x].v.v_invocation +#define ARGPC(x) (ARGENTITY(x)->is_player()) +#define ARGNPC(x) (ARGENTITY(x)->is_npc()) +#define ARGMOB(x) (ARGENTITY(x)->is_mob()) -# define RESULTINT result->v.v_int -# define RESULTDIR result->v.v_dir -# define RESULTSTR result->v.v_string -# define RESULTENTITY result->v.v_entity -# define RESULTLOCATION result->v.v_location -# define RESULTAREA result->v.v_area -# define RESULTSPELL result->v.v_spell -# define RESULTINVOCATION result->v.v_invocation - -# define ARG_TYPE(x) args[x].ty -# define ENTITY_TYPE(x) ARGENTITY(x)->bl_type - -# define ARGPC(x) (ARGENTITY(x)->is_player()) -# define ARGNPC(x) (ARGENTITY(x)->is_npc()) -# define ARGMOB(x) (ARGENTITY(x)->is_mob()) - -# define ARG_MAY_BE_AREA(x) (ARG_TYPE(x) == TYPE::AREA || ARG_TYPE(x) == TYPE::LOCATION) - -#endif // TMWA_MAP_MAGIC_EXPR_EVAL_HPP +#define ARG_MAY_BE_AREA(x) (ARG_TYPE(x) == TYPE::AREA || ARG_TYPE(x) == TYPE::LOCATION) +} // namespace tmwa diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp index 42ff3a7..dfb65c5 100644 --- a/src/map/magic-expr.cpp +++ b/src/map/magic-expr.cpp @@ -1,6 +1,4 @@ -#include "magic-expr-eval.hpp" #include "magic-expr.hpp" -#include "magic-interpreter-aux.hpp" // magic-expr.cpp - Pure functions for the old magic backend. // // Copyright © 2004-2011 The Mana World Development Team @@ -22,26 +20,39 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include <cassert> -#include <cmath> -#include "../compat/alg.hpp" +#include <algorithm> #include "../strings/mstring.hpp" #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/vstring.hpp" +#include "../strings/literal.hpp" +#include "../generic/dumb_ptr.hpp" #include "../generic/random.hpp" #include "../io/cxxstdio.hpp" #include "battle.hpp" +#include "itemdb.hpp" +#include "magic-expr-eval.hpp" +#include "magic-interpreter.hpp" +#include "magic-interpreter-base.hpp" #include "npc.hpp" #include "pc.hpp" -#include "itemdb.hpp" #include "../poison.hpp" + +namespace tmwa +{ +template<class T> +bool CHECK_TYPE(T *v, TYPE t) +{ + return v->ty == t; +} + static void free_area(dumb_ptr<area_t> area) { @@ -125,38 +136,38 @@ AString show_entity(dumb_ptr<block_list> entity) case BL::MOB: return entity->is_mob()->name; case BL::ITEM: - assert (0 && "There is no way this code did what it was supposed to do!"); + assert (0 && "There is no way this code did what it was supposed to do!"_s); /* Sorry about this one... */ - // WTF? item_data is a struct item, not a struct item_data + // WTF? item_data is a Item, not a struct item_data // return ((struct item_data *) (&entity->is_item()->item_data))->name; abort(); case BL::SPELL: - return {"%invocation(ERROR:this-should-not-be-an-entity)"}; + return "%invocation(ERROR:this-should-not-be-an-entity)"_s; default: - return {"%unknown-entity"}; + return "%unknown-entity"_s; } } static void stringify(val_t *v, int within_op) { - static earray<ZString, DIR, DIR::COUNT> dirs //= + static earray<LString, DIR, DIR::COUNT> dirs //= {{ - {"south"}, {"south-west"}, - {"west"}, {"north-west"}, - {"north"}, {"north-east"}, - {"east"}, {"south-east"}, + "south"_s, "south-west"_s, + "west"_s, "north-west"_s, + "north"_s, "north-east"_s, + "east"_s, "south-east"_s, }}; AString buf; switch (v->ty) { case TYPE::UNDEF: - buf = "UNDEF"; + buf = "UNDEF"_s; break; case TYPE::INT: - buf = STRPRINTF("%i", v->v.v_int); + buf = STRPRINTF("%i"_fmt, v->v.v_int); break; case TYPE::STRING: @@ -171,14 +182,14 @@ void stringify(val_t *v, int within_op) break; case TYPE::LOCATION: - buf = STRPRINTF("<\"%s\", %d, %d>", + buf = STRPRINTF("<\"%s\", %d, %d>"_fmt, v->v.v_location.m->name_, v->v.v_location.x, v->v.v_location.y); break; case TYPE::AREA: - buf = "%area"; + buf = "%area"_s; free_area(v->v.v_area); break; @@ -190,13 +201,13 @@ void stringify(val_t *v, int within_op) { dumb_ptr<invocation> invocation_ = within_op ? v->v.v_invocation - : map_id2bl(v->v.v_int)->is_spell(); + : map_id2bl(wrap<BlockId>(static_cast<uint32_t>(v->v.v_int)))->is_spell(); buf = invocation_->spell->name; } break; default: - FPRINTF(stderr, "[magic] INTERNAL ERROR: Cannot stringify %d\n", + FPRINTF(stderr, "[magic] INTERNAL ERROR: Cannot stringify %d\n"_fmt, v->ty); return; } @@ -294,8 +305,8 @@ int fun_add(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) make_area(&args[0]); make_area(&args[1]); RESULTAREA = area_union(ARGAREA(0), ARGAREA(1)); - ARGAREA(0) = NULL; - ARGAREA(1) = NULL; + ARGAREA(0) = nullptr; + ARGAREA(1) = nullptr; result->ty = TYPE::AREA; } else @@ -504,14 +515,14 @@ int fun_bitshr(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) static int fun_max(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { - RESULTINT = max(ARGINT(0), ARGINT(1)); + RESULTINT = std::max(ARGINT(0), ARGINT(1)); return 0; } static int fun_min(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { - RESULTINT = min(ARGINT(0), ARGINT(1)); + RESULTINT = std::min(ARGINT(0), ARGINT(1)); return 0; } @@ -590,7 +601,7 @@ void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height, default: FPRINTF(stderr, - "Error: Trying to compute area of NE/SE/NW/SW-facing bar"); + "Error: Trying to compute area of NE/SE/NW/SW-facing bar"_fmt); *x = tx; *y = ty; *width = *height = 1; @@ -619,7 +630,7 @@ int magic_location_in_area(map_local *m, int x, int y, dumb_ptr<area_t> area) && (x < ax + awidth) && (y < ay + aheight)); } default: - FPRINTF(stderr, "INTERNAL ERROR: Invalid area\n"); + FPRINTF(stderr, "INTERNAL ERROR: Invalid area\n"_fmt); return 0; } } @@ -639,7 +650,7 @@ int fun_skill(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) if (ENTITY_TYPE(0) != BL::PC // don't convert to enum until after the range check || ARGINT(1) < 0 - || ARGINT(1) >= uint16_t(MAX_SKILL)) + || ARGINT(1) >= static_cast<uint16_t>(MAX_SKILL)) { RESULTINT = 0; } @@ -725,7 +736,7 @@ int fun_mob_id(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { if (ENTITY_TYPE(0) != BL::MOB) return 1; - RESULTINT = ARGMOB(0)->mob_class; + RESULTINT = unwrap<Species>(ARGMOB(0)->mob_class); return 0; } @@ -783,18 +794,18 @@ int fun_random_dir(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) static int fun_hash_entity(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { - RESULTINT = ARGENTITY(0)->bl_id; + RESULTINT = unwrap<BlockId>(ARGENTITY(0)->bl_id); return 0; } -int // ret -1: not a string, ret 1: no such item, ret 0: OK -magic_find_item(Slice<val_t> args, int index, struct item *item_, int *stackable) +// ret -1: not a string, ret 1: no such item, ret 0: OK +int magic_find_item(Slice<val_t> args, int index, Item *item_, int *stackable) { struct item_data *item_data; int must_add_sequentially; if (ARG_TYPE(index) == TYPE::INT) - item_data = itemdb_exists(ARGINT(index)); + item_data = itemdb_exists(wrap<ItemNameId>(static_cast<uint16_t>(ARGINT(index)))); else if (ARG_TYPE(index) == TYPE::STRING) item_data = itemdb_searchname(ARGSTR(index)); else @@ -813,7 +824,7 @@ magic_find_item(Slice<val_t> args, int index, struct item *item_, int *stackable if (stackable) *stackable = !must_add_sequentially; - *item_ = item(); + *item_ = Item(); item_->nameid = item_data->nameid; return 0; @@ -822,9 +833,9 @@ magic_find_item(Slice<val_t> args, int index, struct item *item_, int *stackable static int fun_count_item(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { - dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; + dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr; int stackable; - struct item item; + Item item; GET_ARG_ITEM(1, item, stackable); @@ -838,9 +849,9 @@ int fun_count_item(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) static int fun_is_equipped(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { - dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; + dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr; int stackable; - struct item item; + Item item; bool retval = false; GET_ARG_ITEM(1, item, stackable); @@ -850,8 +861,8 @@ int fun_is_equipped(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) for (EQUIP i : EQUIPs) { - int idx = chr->equip_index_maybe[i]; - if (idx >= 0 && chr->status.inventory[idx].nameid == item.nameid) + IOff0 idx = chr->equip_index_maybe[i]; + if (idx.ok() && chr->status.inventory[idx].nameid == item.nameid) { retval = true; break; @@ -927,7 +938,7 @@ int fun_npc(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { NpcName name = stringish<NpcName>(ARGSTR(0)); RESULTENTITY = npc_name2id(name); - return RESULTENTITY == NULL; + return RESULTENTITY == nullptr; } static @@ -935,7 +946,7 @@ int fun_pc(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { CharName name = stringish<CharName>(ARGSTR(0)); RESULTENTITY = map_nick2sd(name); - return RESULTENTITY == NULL; + return RESULTENTITY == nullptr; } static @@ -944,7 +955,7 @@ int fun_distance(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) if (ARGLOCATION(0).m != ARGLOCATION(1).m) RESULTINT = 0x7fffffff; else - RESULTINT = max(abs(ARGLOCATION(0).x - ARGLOCATION(1).x), + RESULTINT = std::max(abs(ARGLOCATION(0).x - ARGLOCATION(1).x), abs(ARGLOCATION(0).y - ARGLOCATION(1).y)); return 0; } @@ -1034,7 +1045,7 @@ void magic_random_location(location_t *dest, dumb_ptr<area_t> area) } default: - FPRINTF(stderr, "Unknown area type %d\n", + FPRINTF(stderr, "Unknown area type %d\n"_fmt, area->ty); } } @@ -1133,7 +1144,7 @@ int fun_is_exterior(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) static int fun_contains_string(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { - RESULTINT = NULL != strstr(ARGSTR(0).c_str(), ARGSTR(1).c_str()); + RESULTINT = nullptr != strstr(ARGSTR(0).c_str(), ARGSTR(1).c_str()); return 0; } @@ -1142,7 +1153,7 @@ int fun_strstr(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { const char *offset = strstr(ARGSTR(0).c_str(), ARGSTR(1).c_str()); RESULTINT = offset - ARGSTR(0).c_str(); - return offset == NULL; + return offset == nullptr; } static @@ -1273,7 +1284,7 @@ int fun_dir_towards(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) static int fun_extract_healer_xp(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { - dumb_ptr<map_session_data> sd = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; + dumb_ptr<map_session_data> sd = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr; if (!sd) RESULTINT = 0; @@ -1282,89 +1293,89 @@ int fun_extract_healer_xp(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) return 0; } -#define MAGIC_FUNCTION(name, args, ret, impl) {{name}, {{name}, {args}, ret, impl}} -#define MAGIC_FUNCTION1(name, args, ret) MAGIC_FUNCTION(#name, args, ret, fun_##name) -static +#define MAGIC_FUNCTION(name, args, ret, impl) {name, {name, args, ret, impl}} +#define MAGIC_FUNCTION1(name, args, ret) MAGIC_FUNCTION(#name##_s, args, ret, fun_##name) +static // should be LString, but no heterogenous lookup yet std::map<ZString, fun_t> functions = { - MAGIC_FUNCTION("+", "..", '.', fun_add), - MAGIC_FUNCTION("-", "ii", 'i', fun_sub), - MAGIC_FUNCTION("*", "ii", 'i', fun_mul), - MAGIC_FUNCTION("/", "ii", 'i', fun_div), - MAGIC_FUNCTION("%", "ii", 'i', fun_mod), - MAGIC_FUNCTION("||", "ii", 'i', fun_or), - MAGIC_FUNCTION("&&", "ii", 'i', fun_and), - MAGIC_FUNCTION("<", "..", 'i', fun_lt), - MAGIC_FUNCTION(">", "..", 'i', fun_gt), - MAGIC_FUNCTION("<=", "..", 'i', fun_lte), - MAGIC_FUNCTION(">=", "..", 'i', fun_gte), - MAGIC_FUNCTION("==", "..", 'i', fun_eq), - MAGIC_FUNCTION("!=", "..", 'i', fun_ne), - MAGIC_FUNCTION("|", "..", 'i', fun_bitor), - MAGIC_FUNCTION("&", "ii", 'i', fun_bitand), - MAGIC_FUNCTION("^", "ii", 'i', fun_bitxor), - MAGIC_FUNCTION("<<", "ii", 'i', fun_bitshl), - MAGIC_FUNCTION(">>", "ii", 'i', fun_bitshr), - MAGIC_FUNCTION1(not, "i", 'i'), - MAGIC_FUNCTION1(neg, "i", 'i'), - MAGIC_FUNCTION1(max, "ii", 'i'), - MAGIC_FUNCTION1(min, "ii", 'i'), - MAGIC_FUNCTION1(is_in, "la", 'i'), - MAGIC_FUNCTION1(if_then_else, "i__", '_'), - MAGIC_FUNCTION1(skill, "ei", 'i'), - MAGIC_FUNCTION("str", "e", 'i', fun_get_str), - MAGIC_FUNCTION("agi", "e", 'i', fun_get_agi), - MAGIC_FUNCTION("vit", "e", 'i', fun_get_vit), - MAGIC_FUNCTION("dex", "e", 'i', fun_get_dex), - MAGIC_FUNCTION("luk", "e", 'i', fun_get_luk), - MAGIC_FUNCTION("int", "e", 'i', fun_get_int), - MAGIC_FUNCTION("level", "e", 'i', fun_get_lv), - MAGIC_FUNCTION("mdef", "e", 'i', fun_get_mdef), - MAGIC_FUNCTION("def", "e", 'i', fun_get_def), - MAGIC_FUNCTION("hp", "e", 'i', fun_get_hp), - MAGIC_FUNCTION("max_hp", "e", 'i', fun_get_max_hp), - MAGIC_FUNCTION("sp", "e", 'i', fun_get_sp), - MAGIC_FUNCTION("max_sp", "e", 'i', fun_get_max_sp), - MAGIC_FUNCTION("dir", "e", 'd', fun_get_dir), - MAGIC_FUNCTION1(name_of, ".", 's'), - MAGIC_FUNCTION1(mob_id, "e", 'i'), - MAGIC_FUNCTION1(location, "e", 'l'), - MAGIC_FUNCTION1(random, "i", 'i'), - MAGIC_FUNCTION1(random_dir, "i", 'd'), - MAGIC_FUNCTION1(hash_entity, "e", 'i'), - MAGIC_FUNCTION1(is_married, "e", 'i'), - MAGIC_FUNCTION1(partner, "e", 'e'), - MAGIC_FUNCTION1(awayfrom, "ldi", 'l'), - MAGIC_FUNCTION1(failed, "_", 'i'), - MAGIC_FUNCTION1(pc, "s", 'e'), - MAGIC_FUNCTION1(npc, "s", 'e'), - MAGIC_FUNCTION1(distance, "ll", 'i'), - MAGIC_FUNCTION1(rdistance, "ll", 'i'), - MAGIC_FUNCTION1(anchor, "s", 'a'), - MAGIC_FUNCTION("random_location", "a", 'l', fun_pick_location), - MAGIC_FUNCTION("script_int", "es", 'i', fun_read_script_int), - MAGIC_FUNCTION("script_str", "es", 's', fun_read_script_str), - MAGIC_FUNCTION1(rbox, "li", 'a'), - MAGIC_FUNCTION1(count_item, "e.", 'i'), - MAGIC_FUNCTION1(line_of_sight, "ll", 'i'), - MAGIC_FUNCTION1(running_status_update, "ei", 'i'), - MAGIC_FUNCTION1(status_option, "ei", 'i'), - MAGIC_FUNCTION1(element, "e", 'i'), - MAGIC_FUNCTION1(element_level, "e", 'i'), - MAGIC_FUNCTION1(his_shroud, "e", 'i'), - MAGIC_FUNCTION1(is_equipped, "e.", 'i'), - MAGIC_FUNCTION1(is_exterior, "l", 'i'), - MAGIC_FUNCTION1(contains_string, "ss", 'i'), - MAGIC_FUNCTION1(strstr, "ss", 'i'), - MAGIC_FUNCTION1(strlen, "s", 'i'), - MAGIC_FUNCTION1(substr, "sii", 's'), - MAGIC_FUNCTION1(sqrt, "i", 'i'), - MAGIC_FUNCTION1(map_level, "l", 'i'), - MAGIC_FUNCTION1(map_nr, "l", 'i'), - MAGIC_FUNCTION1(dir_towards, "lli", 'd'), - MAGIC_FUNCTION1(is_dead, "e", 'i'), - MAGIC_FUNCTION1(is_pc, "e", 'i'), - MAGIC_FUNCTION("extract_healer_experience", "ei", 'i', fun_extract_healer_xp), + MAGIC_FUNCTION("+"_s, ".."_s, '.', fun_add), + MAGIC_FUNCTION("-"_s, "ii"_s, 'i', fun_sub), + MAGIC_FUNCTION("*"_s, "ii"_s, 'i', fun_mul), + MAGIC_FUNCTION("/"_s, "ii"_s, 'i', fun_div), + MAGIC_FUNCTION("%"_s, "ii"_s, 'i', fun_mod), + MAGIC_FUNCTION("||"_s, "ii"_s, 'i', fun_or), + MAGIC_FUNCTION("&&"_s, "ii"_s, 'i', fun_and), + MAGIC_FUNCTION("<"_s, ".."_s, 'i', fun_lt), + MAGIC_FUNCTION(">"_s, ".."_s, 'i', fun_gt), + MAGIC_FUNCTION("<="_s, ".."_s, 'i', fun_lte), + MAGIC_FUNCTION(">="_s, ".."_s, 'i', fun_gte), + MAGIC_FUNCTION("=="_s, ".."_s, 'i', fun_eq), + MAGIC_FUNCTION("!="_s, ".."_s, 'i', fun_ne), + MAGIC_FUNCTION("|"_s, ".."_s, 'i', fun_bitor), + MAGIC_FUNCTION("&"_s, "ii"_s, 'i', fun_bitand), + MAGIC_FUNCTION("^"_s, "ii"_s, 'i', fun_bitxor), + MAGIC_FUNCTION("<<"_s, "ii"_s, 'i', fun_bitshl), + MAGIC_FUNCTION(">>"_s, "ii"_s, 'i', fun_bitshr), + MAGIC_FUNCTION1(not, "i"_s, 'i'), + MAGIC_FUNCTION1(neg, "i"_s, 'i'), + MAGIC_FUNCTION1(max, "ii"_s, 'i'), + MAGIC_FUNCTION1(min, "ii"_s, 'i'), + MAGIC_FUNCTION1(is_in, "la"_s, 'i'), + MAGIC_FUNCTION1(if_then_else, "i__"_s, '_'), + MAGIC_FUNCTION1(skill, "ei"_s, 'i'), + MAGIC_FUNCTION("str"_s, "e"_s, 'i', fun_get_str), + MAGIC_FUNCTION("agi"_s, "e"_s, 'i', fun_get_agi), + MAGIC_FUNCTION("vit"_s, "e"_s, 'i', fun_get_vit), + MAGIC_FUNCTION("dex"_s, "e"_s, 'i', fun_get_dex), + MAGIC_FUNCTION("luk"_s, "e"_s, 'i', fun_get_luk), + MAGIC_FUNCTION("int"_s, "e"_s, 'i', fun_get_int), + MAGIC_FUNCTION("level"_s, "e"_s, 'i', fun_get_lv), + MAGIC_FUNCTION("mdef"_s, "e"_s, 'i', fun_get_mdef), + MAGIC_FUNCTION("def"_s, "e"_s, 'i', fun_get_def), + MAGIC_FUNCTION("hp"_s, "e"_s, 'i', fun_get_hp), + MAGIC_FUNCTION("max_hp"_s, "e"_s, 'i', fun_get_max_hp), + MAGIC_FUNCTION("sp"_s, "e"_s, 'i', fun_get_sp), + MAGIC_FUNCTION("max_sp"_s, "e"_s, 'i', fun_get_max_sp), + MAGIC_FUNCTION("dir"_s, "e"_s, 'd', fun_get_dir), + MAGIC_FUNCTION1(name_of, "."_s, 's'), + MAGIC_FUNCTION1(mob_id, "e"_s, 'i'), + MAGIC_FUNCTION1(location, "e"_s, 'l'), + MAGIC_FUNCTION1(random, "i"_s, 'i'), + MAGIC_FUNCTION1(random_dir, "i"_s, 'd'), + MAGIC_FUNCTION1(hash_entity, "e"_s, 'i'), + MAGIC_FUNCTION1(is_married, "e"_s, 'i'), + MAGIC_FUNCTION1(partner, "e"_s, 'e'), + MAGIC_FUNCTION1(awayfrom, "ldi"_s, 'l'), + MAGIC_FUNCTION1(failed, "_"_s, 'i'), + MAGIC_FUNCTION1(pc, "s"_s, 'e'), + MAGIC_FUNCTION1(npc, "s"_s, 'e'), + MAGIC_FUNCTION1(distance, "ll"_s, 'i'), + MAGIC_FUNCTION1(rdistance, "ll"_s, 'i'), + MAGIC_FUNCTION1(anchor, "s"_s, 'a'), + MAGIC_FUNCTION("random_location"_s, "a"_s, 'l', fun_pick_location), + MAGIC_FUNCTION("script_int"_s, "es"_s, 'i', fun_read_script_int), + MAGIC_FUNCTION("script_str"_s, "es"_s, 's', fun_read_script_str), + MAGIC_FUNCTION1(rbox, "li"_s, 'a'), + MAGIC_FUNCTION1(count_item, "e."_s, 'i'), + MAGIC_FUNCTION1(line_of_sight, "ll"_s, 'i'), + MAGIC_FUNCTION1(running_status_update, "ei"_s, 'i'), + MAGIC_FUNCTION1(status_option, "ei"_s, 'i'), + MAGIC_FUNCTION1(element, "e"_s, 'i'), + MAGIC_FUNCTION1(element_level, "e"_s, 'i'), + MAGIC_FUNCTION1(his_shroud, "e"_s, 'i'), + MAGIC_FUNCTION1(is_equipped, "e."_s, 'i'), + MAGIC_FUNCTION1(is_exterior, "l"_s, 'i'), + MAGIC_FUNCTION1(contains_string, "ss"_s, 'i'), + MAGIC_FUNCTION1(strstr, "ss"_s, 'i'), + MAGIC_FUNCTION1(strlen, "s"_s, 'i'), + MAGIC_FUNCTION1(substr, "sii"_s, 's'), + MAGIC_FUNCTION1(sqrt, "i"_s, 'i'), + MAGIC_FUNCTION1(map_level, "l"_s, 'i'), + MAGIC_FUNCTION1(map_nr, "l"_s, 'i'), + MAGIC_FUNCTION1(dir_towards, "lli"_s, 'd'), + MAGIC_FUNCTION1(is_dead, "e"_s, 'i'), + MAGIC_FUNCTION1(is_pc, "e"_s, 'i'), + MAGIC_FUNCTION("extract_healer_experience"_s, "ei"_s, 'i', fun_extract_healer_xp), }; fun_t *magic_get_fun(ZString name) @@ -1420,7 +1431,7 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, e_area_t& expr_) if (eval_location(env, &area->a.a_loc, &expr->a.a_loc)) { area.delete_(); - return NULL; + return nullptr; } else return area; @@ -1443,7 +1454,7 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, e_area_t& expr_) free_area(area->a.a_union[i]); } area.delete_(); - return NULL; + return nullptr; } area->size = area->a.a_union[0]->size + area->a.a_union[1]->size; return area; @@ -1473,7 +1484,7 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, e_area_t& expr_) area.delete_(); magic_clear_var(&width); magic_clear_var(&height); - return NULL; + return nullptr; } } @@ -1507,15 +1518,15 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, e_area_t& expr_) magic_clear_var(&width); magic_clear_var(&depth); magic_clear_var(&dir); - return NULL; + return nullptr; } } default: - FPRINTF(stderr, "INTERNAL ERROR: Unknown area type %d\n", + FPRINTF(stderr, "INTERNAL ERROR: Unknown area type %d\n"_fmt, area->ty); area.delete_(); - return NULL; + return nullptr; } } @@ -1559,13 +1570,13 @@ int magic_signature_check(ZString opname, ZString funname, ZString signature, if (ty == TYPE::ENTITY) { /* Dereference entities in preparation for calling function */ - arg->v.v_entity = map_id2bl(arg->v.v_int); + arg->v.v_entity = map_id2bl(wrap<BlockId>(static_cast<uint32_t>(arg->v.v_int))); if (!arg->v.v_entity) ty = arg->ty = TYPE::FAIL; } else if (ty == TYPE::INVOCATION) { - arg->v.v_invocation = map_id2bl(arg->v.v_int)->is_spell(); + arg->v.v_invocation = map_id2bl(wrap<BlockId>(static_cast<uint32_t>(arg->v.v_int)))->is_spell(); if (!arg->v.v_entity) ty = arg->ty = TYPE::FAIL; } @@ -1573,8 +1584,8 @@ int magic_signature_check(ZString opname, ZString funname, ZString signature, if (!ty_key) { FPRINTF(stderr, - "[magic-eval]: L%d:%d: Too many arguments (%zu) to %s `%s'\n", - line, column, args.size(), opname, funname); + "[magic-eval]: L%d:%d: Too many arguments (%zu) to %s `%s'\n"_fmt, + line, column, args.size(), opname, funname); return 1; } @@ -1587,8 +1598,8 @@ int magic_signature_check(ZString opname, ZString funname, ZString signature, if (ty == TYPE::UNDEF) { FPRINTF(stderr, - "[magic-eval]: L%d:%d: Argument #%d to %s `%s' undefined\n", - line, column, i + 1, opname, funname); + "[magic-eval]: L%d:%d: Argument #%d to %s `%s' undefined\n"_fmt, + line, column, i + 1, opname, funname); return 1; } @@ -1619,9 +1630,9 @@ int magic_signature_check(ZString opname, ZString funname, ZString signature, { /* Coercion failed? */ if (ty != TYPE::FAIL) FPRINTF(stderr, - "[magic-eval]: L%d:%d: Argument #%d to %s `%s' of incorrect type (%d)\n", - line, column, i + 1, opname, funname, - ty); + "[magic-eval]: L%d:%d: Argument #%d to %s `%s' of incorrect type (%d)\n"_fmt, + line, column, i + 1, opname, funname, + ty); return 1; } } @@ -1660,7 +1671,7 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) for (i = 0; i < args_nr; ++i) magic_eval(env, &arguments[i], expr->e.e_funapp.args[i]); - if (magic_signature_check("function", f->name, f->signature, Slice<val_t>(arguments, args_nr), + if (magic_signature_check("function"_s, f->name, f->signature, Slice<val_t>(arguments, args_nr), expr->e.e_funapp.line_nr, expr->e.e_funapp.column) || f->fun(env, dest, Slice<val_t>(arguments, args_nr))) dest->ty = TYPE::FAIL; @@ -1674,7 +1685,7 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) if (dest->ty == TYPE::ENTITY) { if (dest->v.v_entity) - dest->v.v_int = dest->v.v_entity->bl_id; + dest->v.v_int = static_cast<int32_t>(unwrap<BlockId>(dest->v.v_entity->bl_id)); else dest->ty = TYPE::FAIL; } @@ -1700,7 +1711,7 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) if (v.ty == TYPE::INVOCATION) { - dumb_ptr<invocation> t = map_id2bl(v.v.v_int)->is_spell(); + dumb_ptr<invocation> t = map_id2bl(wrap<BlockId>(static_cast<uint32_t>(v.v.v_int)))->is_spell(); if (!t) dest->ty = TYPE::UNDEF; @@ -1713,8 +1724,8 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) else { FPRINTF(stderr, - "[magic] Attempt to access field %s on non-spell\n", - env->base_env->varv[id].name); + "[magic] Attempt to access field %s on non-spell\n"_fmt, + env->base_env->varv[id].name); dest->ty = TYPE::FAIL; } break; @@ -1722,8 +1733,8 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) default: FPRINTF(stderr, - "[magic] INTERNAL ERROR: Unknown expression type %d\n", - expr->ty); + "[magic] INTERNAL ERROR: Unknown expression type %d\n"_fmt, + expr->ty); break; } } @@ -1747,7 +1758,7 @@ AString magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr) magic_eval(env, &result, expr); if (result.ty == TYPE::FAIL || result.ty == TYPE::UNDEF) - return {"?"}; + return "?"_s; stringify(&result, 0); @@ -1760,3 +1771,4 @@ dumb_ptr<expr_t> magic_new_expr(EXPR ty) expr->ty = ty; return expr; } +} // namespace tmwa diff --git a/src/map/magic-expr.hpp b/src/map/magic-expr.hpp index 58f6596..e582a66 100644 --- a/src/map/magic-expr.hpp +++ b/src/map/magic-expr.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_MAGIC_EXPR_HPP -#define TMWA_MAP_MAGIC_EXPR_HPP +#pragma once // magic-expr.hpp - Pure functions for the old magic backend. // // Copyright © 2004-2011 The Mana World Development Team @@ -20,15 +19,22 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "magic-interpreter.hpp" +#include "../generic/fwd.hpp" -# include "../range/slice.hpp" +#include "../range/fwd.hpp" -# include "../strings/fwd.hpp" -# include "../strings/zstring.hpp" +#include "../strings/zstring.hpp" +#include "../strings/literal.hpp" +#include "../mmo/fwd.hpp" + +#include "magic-interpreter.t.hpp" + + +namespace tmwa +{ /* * Argument types: * i : int @@ -44,34 +50,20 @@ */ struct fun_t { - ZString name; - ZString signature; + LString name; + LString signature; char ret_ty; int (*fun)(dumb_ptr<env_t> env, val_t *result, Slice<val_t> arga); }; -struct op_t -{ - ZString name; - ZString signature; - int (*op)(dumb_ptr<env_t> env, Slice<val_t> arga); -}; - /** * Retrieves a function by name * @param name The name to look up - * @return A function of that name, or NULL. + * @return A function of that name, or nullptr. */ fun_t *magic_get_fun(ZString name); /** - * Retrieves an operation by name - * @param name The name to look up - * @return An operation of that name, or NULL, and a function index - */ -op_t *magic_get_op(ZString name); - -/** * Evaluates an expression and stores the result in `dest' */ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr); @@ -95,9 +87,9 @@ void magic_copy_var(val_t *dest, val_t *src); void magic_random_location(location_t *dest, dumb_ptr<area_t> area); // ret -1: not a string, ret 1: no such item, ret 0: OK -int magic_find_item(Slice<val_t> args, int index, struct item *item, int *stackable); +int magic_find_item(Slice<val_t> args, int index, Item *item, int *stackable); -# define GET_ARG_ITEM(index, dest, stackable) \ +#define GET_ARG_ITEM(index, dest, stackable) \ switch (magic_find_item(args, index, &dest, &stackable)) \ { \ case -1: return 1; \ @@ -107,4 +99,11 @@ int magic_find_item(Slice<val_t> args, int index, struct item *item, int *stacka int magic_location_in_area(map_local *m, int x, int y, dumb_ptr<area_t> area); -#endif // TMWA_MAP_MAGIC_EXPR_HPP +/* Helper definitions for dealing with functions and operations */ + +int magic_signature_check(ZString opname, ZString funname, ZString signature, + Slice<val_t> args, int line, int column); + +void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height, + area_t& area); +} // namespace tmwa diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp index d86f595..768a7df 100644 --- a/src/map/magic-interpreter-base.cpp +++ b/src/map/magic-interpreter-base.cpp @@ -19,22 +19,25 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include "magic-interpreter-aux.hpp" -#include "magic-interpreter.hpp" +#include <algorithm> #include "../strings/astring.hpp" #include "../strings/xstring.hpp" #include "../io/cxxstdio.hpp" -#include "../mmo/timer.hpp" +#include "../net/timer.hpp" +#include "magic.hpp" #include "magic-expr.hpp" - +#include "magic-interpreter.hpp" #include "pc.hpp" #include "../poison.hpp" + +namespace tmwa +{ static void set_int_p(val_t *v, int i, TYPE t) { @@ -43,8 +46,8 @@ void set_int_p(val_t *v, int i, TYPE t) } #warning "This code should die" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-macros" +DIAG_PUSH(); +DIAG_I(unused_macros); #define set_int(v, i) set_int_p(v, i, TYPE::INT) #define set_dir(v, i) set_int_p(v, i, TYPE::DIR) @@ -58,14 +61,14 @@ static void set_entity(val_t *v, dumb_ptr<block_list> e) { v->ty = TYPE::ENTITY; - v->v.v_int = e->bl_id; + v->v.v_int = static_cast<int32_t>(unwrap<BlockId>(e->bl_id)); } static void set_invocation(val_t *v, dumb_ptr<invocation> i) { v->ty = TYPE::INVOCATION; - v->v.v_int = i->bl_id; + v->v.v_int = static_cast<int32_t>(unwrap<BlockId>(i->bl_id)); } static @@ -82,10 +85,10 @@ void set_spell SETTER(dumb_ptr<spell_t>, TYPE::SPELL, v_spell) #define set_env_invocation(v, x) setenv(set_invocation, v, x) #define set_env_spell(v, x) setenv(set_spell, v, x) -#pragma GCC diagnostic pop +DIAG_POP(); magic_conf_t magic_conf; /* Global magic conf */ -env_t magic_default_env = { &magic_conf, NULL }; +env_t magic_default_env = { &magic_conf, nullptr }; AString magic_find_invocation(XString spellname) { @@ -102,7 +105,7 @@ dumb_ptr<spell_t> magic_find_spell(XString invocation) if (it != magic_conf.spells_by_invocation.end()) return it->second; - return NULL; + return nullptr; } /* -------------------------------------------------------------------------------- */ @@ -125,7 +128,7 @@ dumb_ptr<teleport_anchor_t> magic_find_anchor(XString name) if (it != magic_conf.anchors_by_invocation.end()) return it->second; - return NULL; + return nullptr; } /* -------------------------------------------------------------------------------- */ @@ -187,8 +190,8 @@ dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell, break; default: - FPRINTF(stderr, "Unexpected spellarg type %d\n", - spell->spellarg_ty); + FPRINTF(stderr, "Unexpected spellarg type %d\n"_fmt, + spell->spellarg_ty); } set_env_entity(VAR_CASTER, caster); @@ -201,22 +204,22 @@ dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell, static void free_components(dumb_ptr<component_t> *component_holder) { - if (*component_holder == NULL) + if (*component_holder == nullptr) return; free_components(&(*component_holder)->next); (*component_holder).delete_(); - *component_holder = NULL; + *component_holder = nullptr; } -void magic_add_component(dumb_ptr<component_t> *component_holder, int id, int count) +void magic_add_component(dumb_ptr<component_t> *component_holder, ItemNameId id, int count) { if (count <= 0) return; - if (*component_holder == NULL) + if (*component_holder == nullptr) { auto component = dumb_ptr<component_t>::make(); - component->next = NULL; + component->next = nullptr; component->item_id = id; component->count = count; *component_holder = component; @@ -238,7 +241,7 @@ void magic_add_component(dumb_ptr<component_t> *component_holder, int id, int co static void copy_components(dumb_ptr<component_t> *component_holder, dumb_ptr<component_t> component) { - if (component == NULL) + if (component == nullptr) return; magic_add_component(component_holder, component->item_id, component->count); @@ -296,7 +299,7 @@ int spellguard_can_satisfy(spellguard_check_t *check, dumb_ptr<map_session_data> interval_t casttime = check->casttime; if (env->VAR(VAR_MIN_CASTTIME).ty == TYPE::INT) - casttime = max(casttime, static_cast<interval_t>(env->VAR(VAR_MIN_CASTTIME).v.v_int)); + casttime = std::max(casttime, static_cast<interval_t>(env->VAR(VAR_MIN_CASTTIME).v.v_int)); caster->cast_tick = tick + casttime; /* Make sure not to cast too frequently */ @@ -314,14 +317,14 @@ effect_set_t *spellguard_check_sub(spellguard_check_t *check, dumb_ptr<env_t> env, int *near_miss) { - if (guard == NULL) - return NULL; + if (guard == nullptr) + return nullptr; switch (guard->ty) { case SPELLGUARD::CONDITION: if (!magic_eval_int(env, guard->s.s_condition)) - return NULL; + return nullptr; break; case SPELLGUARD::COMPONENTS: @@ -337,8 +340,8 @@ effect_set_t *spellguard_check_sub(spellguard_check_t *check, spellguard_check_t altcheck = *check; effect_set_t *retval; - altcheck.components = NULL; - altcheck.catalysts = NULL; + altcheck.components = nullptr; + altcheck.catalysts = nullptr; copy_components(&altcheck.catalysts, check->catalysts); copy_components(&altcheck.components, check->components); @@ -367,12 +370,12 @@ effect_set_t *spellguard_check_sub(spellguard_check_t *check, if (spellguard_can_satisfy(check, caster, env, near_miss)) return &guard->s.s_effect; else - return NULL; + return nullptr; default: - FPRINTF(stderr, "Unexpected spellguard type %d\n", + FPRINTF(stderr, "Unexpected spellguard type %d\n"_fmt, guard->ty); - return NULL; + return nullptr; } return spellguard_check_sub(check, guard->next, caster, env, near_miss); @@ -385,8 +388,8 @@ effect_set_t *check_spellguard(dumb_ptr<spellguard_t> guard, { spellguard_check_t check; effect_set_t *retval; - check.catalysts = NULL; - check.components = NULL; + check.catalysts = nullptr; + check.components = nullptr; check.mana = 0; check.casttime = interval_t::zero(); @@ -449,7 +452,7 @@ dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, dumb_ptr<env_t> retval->env = env; - retval->caster = env->VAR(VAR_CASTER).v.v_int; + retval->caster = wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_CASTER).v.v_int)); retval->spell = env->VAR(VAR_SPELL).v.v_spell; retval->stack_size = 0; retval->current_effect = effect_set->effect; @@ -478,12 +481,12 @@ dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> base) // since this is the only call site, it is expanded here //*retval = *base; - retval->next_invocation = NULL; + retval->next_invocation = nullptr; retval->flags = INVOCATION_FLAG::ZERO; dumb_ptr<env_t> env = retval->env = clone_env(base->env); retval->spell = base->spell; retval->caster = base->caster; - retval->subject = 0; + retval->subject = BlockId(); // retval->timer = 0; retval->stack_size = 0; // retval->stack = undef; @@ -491,12 +494,12 @@ dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> base) // huh? retval->current_effect = base->trigger_effect; retval->trigger_effect = base->trigger_effect; - retval->end_effect = NULL; - // retval->status_change_refs = NULL; + retval->end_effect = nullptr; + // retval->status_change_refs = nullptr; - retval->bl_id = 0; - retval->bl_prev = NULL; - retval->bl_next = NULL; + retval->bl_id = BlockId(); + retval->bl_prev = nullptr; + retval->bl_next = nullptr; retval->bl_m = base->bl_m; retval->bl_x = base->bl_x; retval->bl_y = base->bl_y; @@ -517,10 +520,10 @@ void spell_bind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocat if (bool(invocation->flags & INVOCATION_FLAG::BOUND) || invocation->subject || invocation->next_invocation) { - int *i = NULL; + int *i = nullptr; FPRINTF(stderr, - "[magic] INTERNAL ERROR: Attempt to re-bind spell invocation `%s'\n", - invocation->spell->name); + "[magic] INTERNAL ERROR: Attempt to re-bind spell invocation `%s'\n"_fmt, + invocation->spell->name); *i = 1; return; } @@ -545,8 +548,8 @@ int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invoca *seeker = invocation_->next_invocation; invocation_->flags &= ~INVOCATION_FLAG::BOUND; - invocation_->next_invocation = NULL; - invocation_->subject = 0; + invocation_->next_invocation = nullptr; + invocation_->subject = BlockId(); return 0; } @@ -555,3 +558,4 @@ int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invoca return 1; } +} // namespace tmwa diff --git a/src/map/magic-interpreter-base.hpp b/src/map/magic-interpreter-base.hpp index 9b1e08a..57dde85 100644 --- a/src/map/magic-interpreter-base.hpp +++ b/src/map/magic-interpreter-base.hpp @@ -1,8 +1,8 @@ -#ifndef TMWA_MAP_MAGIC_INTERPRETER_BASE_HPP -#define TMWA_MAP_MAGIC_INTERPRETER_BASE_HPP -// magic-interpreter-base.hpp - dummy header to make Make dependencies work. +#pragma once +// magic-interpreter-base.hpp - Core of the old magic system. // -// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> +// Copyright © 2004-2011 The Mana World Development Team +// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> // // This file is part of The Mana World (Athena server) // @@ -19,6 +19,69 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -#endif // TMWA_MAP_MAGIC_INTERPRETER_BASE_HPP +#include "../strings/fwd.hpp" + +#include "../generic/fwd.hpp" + +#include "../mmo/fwd.hpp" + + +namespace tmwa +{ +extern magic_conf_t magic_conf; /* Global magic conf */ +extern env_t magic_default_env; /* Fake default environment */ + +/** + * Adds a component selection to a component holder (which may initially be nullptr) + */ +void magic_add_component(dumb_ptr<component_t> *component_holder, ItemNameId id, int count); + +/** + * Identifies the invocation used to trigger a spell + * + * Returns empty string if not found + */ +AString magic_find_invocation(XString spellname); + +/** + * Identifies the invocation used to denote a teleport location + * + * Returns empty string if not found + */ +AString magic_find_anchor_invocation(XString teleport_location); + +dumb_ptr<teleport_anchor_t> magic_find_anchor(XString name); + +dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell, + dumb_ptr<map_session_data> caster, int spellpower, XString param); + +void magic_free_env(dumb_ptr<env_t> env); + +/** + * near_miss is set to nonzero iff the spell only failed due to ephemereal issues (spell delay in effect, out of mana, out of components) + */ +effect_set_t *spell_trigger(dumb_ptr<spell_t> spell, + dumb_ptr<map_session_data> caster, + dumb_ptr<env_t> env, int *near_miss); + +dumb_ptr<invocation> spell_instantiate(effect_set_t *effect, dumb_ptr<env_t> env); + +/** + * Bind a spell to a subject (this is a no-op for `local' spells). + */ +void spell_bind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocation); + +// 1 on failure +int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocation); + +/** + * Clones a spell to run the at_effect field + */ +dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> source); + +dumb_ptr<spell_t> magic_find_spell(XString invocation); + +void spell_update_location(dumb_ptr<invocation> invocation); +} // namespace tmwa diff --git a/src/map/magic-interpreter.cpp b/src/map/magic-interpreter.cpp index 4680971..87ac23e 100644 --- a/src/map/magic-interpreter.cpp +++ b/src/map/magic-interpreter.cpp @@ -1,5 +1,5 @@ #include "magic-interpreter.hpp" -// magic-interpreter.hpp - Old magic. +// magic-interpreter.cpp - Old magic. // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> // @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/map/magic-interpreter.hpp b/src/map/magic-interpreter.hpp index 7d529ee..c9b6c97 100644 --- a/src/map/magic-interpreter.hpp +++ b/src/map/magic-interpreter.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_MAGIC_INTERPRETER_HPP -#define TMWA_MAP_MAGIC_INTERPRETER_HPP +#pragma once // magic-interpreter.hpp - Old magic. // // Copyright © 2004-2011 The Mana World Development Team @@ -20,29 +19,31 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "magic-interpreter.t.hpp" +#include "magic-interpreter.t.hpp" -# include <cassert> +#include <cassert> -# include "../strings/fwd.hpp" -# include "../strings/rstring.hpp" +#include <memory> -# include "magic.hpp" -# include "map.hpp" -# include "script.hpp" -# include "skill.t.hpp" +#include "../strings/fwd.hpp" +#include "../strings/rstring.hpp" -struct fun_t; -struct op_t; -struct expr_t; -struct val_t; -struct location_t; -struct area_t; -struct spell_t; -struct invocation; +#include "../generic/fwd.hpp" +#include "../net/timer.t.hpp" + +#include "../mmo/ids.hpp" +#include "../mmo/utils.hpp" + +#include "map.hpp" +#include "script.hpp" +#include "skill.t.hpp" + + +namespace tmwa +{ struct location_t { map_local *m; @@ -103,7 +104,7 @@ struct val_t /* Expressions */ /* ----------- */ -# define MAX_ARGS 7 /* Max. # of args used in builtin primitive functions */ +#define MAX_ARGS 7 /* Max. # of args used in builtin primitive functions */ struct e_location_t { @@ -223,7 +224,7 @@ struct effect_t struct component_t { dumb_ptr<component_t> next; - int item_id; + ItemNameId item_id; int count; }; @@ -309,17 +310,15 @@ struct magic_conf_t /* Execution environment */ // these are not an enum they're a nasty intern hack -# define VAR_MIN_CASTTIME 0 -# define VAR_OBSCURE_CHANCE 1 -# define VAR_CASTER 2 -# define VAR_SPELLPOWER 3 -# define VAR_SPELL 4 -# define VAR_INVOCATION 5 -# define VAR_TARGET 6 -# define VAR_SCRIPTTARGET 7 -# define VAR_LOCATION 8 - -struct magic_config; +#define VAR_MIN_CASTTIME 0 +#define VAR_OBSCURE_CHANCE 1 +#define VAR_CASTER 2 +#define VAR_SPELLPOWER 3 +#define VAR_SPELL 4 +#define VAR_INVOCATION 5 +#define VAR_TARGET 6 +#define VAR_SCRIPTTARGET 7 +#define VAR_LOCATION 8 struct env_t { @@ -337,7 +336,7 @@ struct env_t }; -# define MAX_STACK_SIZE 32 +#define MAX_STACK_SIZE 32 struct cont_activation_record_t { @@ -349,7 +348,7 @@ struct cont_activation_record_t int id; TYPE ty; dumb_ptr<effect_t> body; - dumb_ptr<std::vector<int>> entities_vp; + dumb_ptr<std::vector<BlockId>> entities_vp; int index; } c_foreach; struct @@ -377,7 +376,7 @@ struct cont_activation_record_t struct status_change_ref_t { StatusChange sc_type; - int bl_id; + BlockId bl_id; }; struct invocation : block_list @@ -387,8 +386,8 @@ struct invocation : block_list dumb_ptr<env_t> env; dumb_ptr<spell_t> spell; - int caster; /* this is the person who originally invoked the spell */ - int subject; /* when this person dies, the spell dies with it */ + BlockId caster; /* this is the person who originally invoked the spell */ + BlockId subject; /* when this person dies, the spell dies with it */ Timer timer; /* spell timer, if any */ @@ -397,56 +396,18 @@ struct invocation : block_list int script_pos; /* Script position; if nonzero, resume the script we were running. */ dumb_ptr<effect_t> current_effect; - dumb_ptr<effect_t> trigger_effect; /* If non-NULL, this is used to spawn a cloned effect based on the same environment */ - dumb_ptr<effect_t> end_effect; /* If non-NULL, this is executed when the spell terminates naturally, e.g. when all status changes have run out or all delays are over. */ + dumb_ptr<effect_t> trigger_effect; /* If non-nullptr, this is used to spawn a cloned effect based on the same environment */ + dumb_ptr<effect_t> end_effect; /* If non-nullptr, this is executed when the spell terminates naturally, e.g. when all status changes have run out or all delays are over. */ /* Status change references: for status change updates, keep track of whom we updated where */ std::vector<status_change_ref_t> status_change_refv; }; +// inlines for map.hpp inline dumb_ptr<invocation> block_list::as_spell() { return dumb_ptr<invocation>(static_cast<invocation *>(this)); } inline dumb_ptr<invocation> block_list::is_spell() { return bl_type == BL::SPELL ? as_spell() : nullptr; } -extern magic_conf_t magic_conf; /* Global magic conf */ -extern env_t magic_default_env; /* Fake default environment */ - -/** - * Adds a component selection to a component holder (which may initially be NULL) - */ -void magic_add_component(dumb_ptr<component_t> *component_holder, int id, int count); - -dumb_ptr<teleport_anchor_t> magic_find_anchor(XString name); - -dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell, - dumb_ptr<map_session_data> caster, int spellpower, XString param); - -void magic_free_env(dumb_ptr<env_t> env); - -/** - * near_miss is set to nonzero iff the spell only failed due to ephemereal issues (spell delay in effect, out of mana, out of components) - */ -effect_set_t *spell_trigger(dumb_ptr<spell_t> spell, - dumb_ptr<map_session_data> caster, - dumb_ptr<env_t> env, int *near_miss); - -dumb_ptr<invocation> spell_instantiate(effect_set_t *effect, dumb_ptr<env_t> env); - -/** - * Bind a spell to a subject (this is a no-op for `local' spells). - */ -void spell_bind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocation); - -// 1 on failure -int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocation); - -/** - * Clones a spell to run the at_effect field - */ -dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> source); - -dumb_ptr<spell_t> magic_find_spell(XString invocation); - /* The following is used only by the parser: */ struct args_rec_t { @@ -465,7 +426,4 @@ struct proc_t , body() {} }; - -void spell_update_location(dumb_ptr<invocation> invocation); - -#endif // TMWA_MAP_MAGIC_INTERPRETER_HPP +} // namespace tmwa diff --git a/src/map/magic-interpreter.py b/src/map/magic-interpreter.py index 8170f27..f6fa4c9 100644 --- a/src/map/magic-interpreter.py +++ b/src/map/magic-interpreter.py @@ -2,7 +2,7 @@ class area_t(object): ''' print an area_t ''' __slots__ = ('_value') - name = 'area_t' + name = 'tmwa::area_t' enabled = True def __init__(self, value): @@ -31,7 +31,7 @@ class val_t(object): ''' print a val_t ''' __slots__ = ('_value') - name = 'val_t' + name = 'tmwa::val_t' enabled = True def __init__(self, value): @@ -69,7 +69,7 @@ class e_area_t(object): ''' print an e_area_t ''' __slots__ = ('_value') - name = 'e_area_t' + name = 'tmwa::e_area_t' enabled = True def __init__(self, value): @@ -97,7 +97,7 @@ class expr_t(object): ''' print an expr_t ''' __slots__ = ('_value') - name = 'expr_t' + name = 'tmwa::expr_t' enabled = True def __init__(self, value): @@ -129,7 +129,7 @@ class effect_t(object): ''' print an effect_t ''' __slots__ = ('_value') - name = 'effect_t' + name = 'tmwa::effect_t' enabled = True def __init__(self, value): @@ -166,7 +166,7 @@ class spellguard_t(object): ''' print a spellguard_t ''' __slots__ = ('_value') - name = 'spellguard_t' + name = 'tmwa::spellguard_t' enabled = True def __init__(self, value): @@ -201,7 +201,7 @@ class cont_activation_record_t(object): ''' print a cont_activation_record_t ''' __slots__ = ('_value') - name = 'cont_activation_record_t' + name = 'tmwa::cont_activation_record_t' enabled = True def __init__(self, value): diff --git a/src/map/magic-interpreter.t.hpp b/src/map/magic-interpreter.t.hpp index 9310a7b..6c7ff81 100644 --- a/src/map/magic-interpreter.t.hpp +++ b/src/map/magic-interpreter.t.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_MAGIC_INTERPRETER_T_HPP -#define TMWA_MAP_MAGIC_INTERPRETER_T_HPP +#pragma once // magic-interpreter.t.hpp - Old magic. // // Copyright © 2004-2011 The Mana World Development Team @@ -20,10 +19,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../generic/enum.hpp" +#include "../generic/enum.hpp" + +namespace tmwa +{ enum class SPELLARG : uint8_t { NONE, @@ -47,38 +49,6 @@ enum class TYPE : uint8_t NEGATIVE_1 = 255, }; -// Note: there is also a typedef by this name in <dirent.h> -// but we should be fine since we never include it. -// (in the long term we should still rename this though) -enum class DIR : uint8_t -{ - S = 0, - SW = 1, - W = 2, - NW = 3, - N = 4, - NE = 5, - E = 6, - SE = 7, - - COUNT, -}; - -constexpr -earray<int, DIR, DIR::COUNT> dirx //= -{{ - 0, -1, -1, -1, 0, 1, 1, 1, -}}, diry //= -{{ - 1, 1, 0, -1, -1, -1, 0, 1, -}}; - -constexpr -bool dir_is_diagonal(DIR d) -{ - return static_cast<uint8_t>(d) & 1; -} - enum class AREA : uint8_t { LOCATION, @@ -176,5 +146,4 @@ enum class INVOCATION_FLAG : uint8_t ENUM_BITWISE_OPERATORS(INVOCATION_FLAG) } using e::INVOCATION_FLAG; - -#endif // TMWA_MAP_MAGIC_INTERPRETER_T_HPP +} // namespace tmwa diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp index ba99409..9aca511 100644 --- a/src/map/magic-stmt.cpp +++ b/src/map/magic-stmt.cpp @@ -30,15 +30,15 @@ #include "../io/cxxstdio.hpp" -#include "../mmo/timer.hpp" +#include "../net/timer.hpp" +#include "battle.hpp" +#include "clif.hpp" +#include "magic.hpp" #include "magic-expr.hpp" #include "magic-expr-eval.hpp" #include "magic-interpreter.hpp" -#include "magic-interpreter-aux.hpp" - -#include "battle.hpp" -#include "clif.hpp" +#include "magic-interpreter-base.hpp" #include "mob.hpp" #include "npc.hpp" #include "pc.hpp" @@ -46,8 +46,11 @@ #include "../poison.hpp" + +namespace tmwa +{ /* used for local spell effects */ -constexpr int INVISIBLE_NPC = 127; +constexpr Species INVISIBLE_NPC = wrap<Species>(127); //#define DEBUG @@ -58,19 +61,19 @@ void print_val(val_t *v) switch (v->ty) { case TYPE::UNDEF: - FPRINTF(stderr, "UNDEF"); + FPRINTF(stderr, "UNDEF"_fmt); break; case TYPE::INT: - FPRINTF(stderr, "%d", v->v.v_int); + FPRINTF(stderr, "%d"_fmt, v->v.v_int); break; case TYPE::DIR: - FPRINTF(stderr, "dir%d", v->v.v_int); + FPRINTF(stderr, "dir%d"_fmt, v->v.v_int); break; case TYPE::STRING: - FPRINTF(stderr, "`%s'", v->v.v_string); + FPRINTF(stderr, "`%s'"_fmt, v->v.v_string); break; default: - FPRINTF(stderr, "ty%d", v->ty); + FPRINTF(stderr, "ty%d"_fmt, v->ty); break; } } @@ -84,11 +87,11 @@ void dump_env(env_t *env) val_t *v = &env->vars[i]; val_t *bv = &env->base_env->vars[i]; - FPRINTF(stderr, "%02x %30s ", i, env->base_env->var_name[i]); + FPRINTF(stderr, "%02x %30s "_fmt, i, env->base_env->var_name[i]); print_val(v); - FPRINTF(stderr, "\t("); + FPRINTF(stderr, "\t("_fmt); print_val(bv); - FPRINTF(stderr, ")\n"); + FPRINTF(stderr, ")\n"_fmt); } } #endif @@ -108,7 +111,7 @@ void clear_activation_record(cont_activation_record_t *ar) } static -void invocation_timer_callback(TimerData *, tick_t, int id) +void invocation_timer_callback(TimerData *, tick_t, BlockId id) { dumb_ptr<invocation> invocation = map_id_is_spell(id); @@ -153,7 +156,7 @@ void spell_free_invocation(dumb_ptr<invocation> invocation_) static void char_set_weapon_icon(dumb_ptr<map_session_data> subject, int count, - StatusChange icon, int look) + StatusChange icon, ItemNameId look) { const StatusChange old_icon = subject->attack_spell_icon_override; @@ -166,7 +169,7 @@ void char_set_weapon_icon(dumb_ptr<map_session_data> subject, int count, clif_fixpcpos(subject); if (count) { - clif_changelook(subject, LOOK::WEAPON, look); + clif_changelook(subject, LOOK::WEAPON, unwrap<ItemNameId>(look)); if (icon != StatusChange::ZERO) clif_status_change(subject, icon, 1); } @@ -202,7 +205,7 @@ void magic_stop_completely(dumb_ptr<map_session_data> c) { // Zap all status change references to spells for (StatusChange i : erange(StatusChange(), StatusChange::MAX_STATUSCHANGE)) - c->sc_data[i].spell_invocation = 0; + c->sc_data[i].spell_invocation = BlockId(); while (c->active_spells) spell_free_invocation(c->active_spells); @@ -212,8 +215,8 @@ void magic_stop_completely(dumb_ptr<map_session_data> c) dumb_ptr<invocation> attack_spell = map_id_is_spell(c->attack_spell_override); if (attack_spell) spell_free_invocation(attack_spell); - c->attack_spell_override = 0; - char_set_weapon_icon(c, 0, StatusChange::ZERO, 0); + c->attack_spell_override = BlockId(); + char_set_weapon_icon(c, 0, StatusChange::ZERO, ItemNameId()); char_set_attack_info(c, interval_t::zero(), 0); } } @@ -228,7 +231,7 @@ void try_to_finish_invocation(dumb_ptr<invocation> invocation) { clear_stack(invocation); invocation->current_effect = invocation->end_effect; - invocation->end_effect = NULL; + invocation->end_effect = nullptr; spell_execute(invocation); } else @@ -237,19 +240,19 @@ void try_to_finish_invocation(dumb_ptr<invocation> invocation) } static -int trigger_spell(int subject, int spell) +BlockId trigger_spell(BlockId subject, BlockId spell) { dumb_ptr<invocation> invocation_ = map_id_is_spell(spell); if (!invocation_) - return 0; + return BlockId(); invocation_ = spell_clone_effect(invocation_); spell_bind(map_id_is_player(subject), invocation_); magic_clear_var(&invocation_->env->varu[VAR_CASTER]); invocation_->env->varu[VAR_CASTER].ty = TYPE::ENTITY; - invocation_->env->varu[VAR_CASTER].v.v_int = subject; + invocation_->env->varu[VAR_CASTER].v.v_int = static_cast<int32_t>(unwrap<BlockId>(subject)); return invocation_->bl_id; } @@ -265,7 +268,7 @@ void char_update(dumb_ptr<map_session_data> character) } static -void timer_callback_effect(TimerData *, tick_t, int id, int data) +void timer_callback_effect(TimerData *, tick_t, BlockId id, int data) { dumb_ptr<block_list> target = map_id2bl(id); if (target) @@ -286,12 +289,12 @@ void magic_unshroud(dumb_ptr<map_session_data> other_char) other_char->state.shroud_active = 0; // Now warp the caster out of and back into here to refresh everyone's display char_update(other_char); - clif_displaymessage(other_char->sess, "Your shroud has been dispelled!"); + clif_displaymessage(other_char->sess, "Your shroud has been dispelled!"_s); // entity_effect(other_char, MAGIC_EFFECT_REVEAL); } static -void timer_callback_effect_npc_delete(TimerData *, tick_t, int npc_id) +void timer_callback_effect_npc_delete(TimerData *, tick_t, BlockId npc_id) { dumb_ptr<npc_data> effect_npc = map_id_is_npc(npc_id); npc_free(effect_npc); @@ -302,10 +305,10 @@ dumb_ptr<npc_data> local_spell_effect(map_local *m, int x, int y, int effect, interval_t tdelay) { /* 1 minute should be enough for all interesting spell effects, I hope */ - std::chrono::seconds delay = std::chrono::seconds(30); + std::chrono::seconds delay = 30_s; dumb_ptr<npc_data> effect_npc = npc_spawn_text(m, x, y, - INVISIBLE_NPC, NpcName(), "?"); - int effect_npc_id = effect_npc->bl_id; + INVISIBLE_NPC, NpcName(), "?"_s); + BlockId effect_npc_id = effect_npc->bl_id; entity_effect(effect_npc, effect, tdelay); Timer(gettick() + delay, @@ -341,7 +344,7 @@ static int op_instaheal(dumb_ptr<env_t> env, Slice<val_t> args) { dumb_ptr<block_list> caster = (env->VAR(VAR_CASTER).ty == TYPE::ENTITY) - ? map_id2bl(env->VAR(VAR_CASTER).v.v_int) : NULL; + ? map_id2bl(wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_CASTER).v.v_int))) : nullptr; dumb_ptr<block_list> subject = ARGENTITY(0); if (!caster) caster = subject; @@ -350,8 +353,8 @@ int op_instaheal(dumb_ptr<env_t> env, Slice<val_t> args) { dumb_ptr<map_session_data> caster_pc = caster->is_player(); dumb_ptr<map_session_data> subject_pc = subject->is_player(); - MAP_LOG_PC(caster_pc, "SPELLHEAL-INSTA PC%d FOR %d", - subject_pc->status_key.char_id, ARGINT(1)); + MAP_LOG_PC(caster_pc, "SPELLHEAL-INSTA PC%d FOR %d"_fmt, + subject_pc->status_key.char_id, ARGINT(1)); } battle_heal(caster, subject, ARGINT(1), ARGINT(2), 0); @@ -430,7 +433,7 @@ int op_message(dumb_ptr<env_t>, Slice<val_t> args) } static -void timer_callback_kill_npc(TimerData *, tick_t, int npc_id) +void timer_callback_kill_npc(TimerData *, tick_t, BlockId npc_id) { dumb_ptr<npc_data> npc = map_id_is_npc(npc_id); if (npc) @@ -445,7 +448,7 @@ int op_messenger_npc(dumb_ptr<env_t>, Slice<val_t> args) NpcName npcname = stringish<NpcName>(ARGSTR(2)); npc = npc_spawn_text(loc->m, loc->x, loc->y, - ARGINT(1), npcname, ARGSTR(3)); + wrap<Species>(static_cast<uint16_t>(ARGINT(1))), npcname, ARGSTR(3)); Timer(gettick() + static_cast<interval_t>(ARGINT(4)), std::bind(timer_callback_kill_npc, ph::_1, ph::_2, @@ -537,7 +540,7 @@ int op_banish(dumb_ptr<env_t>, Slice<val_t> args) } static -void record_status_change(dumb_ptr<invocation> invocation_, int bl_id, +void record_status_change(dumb_ptr<invocation> invocation_, BlockId bl_id, StatusChange sc_id) { status_change_ref_t cr {}; @@ -551,8 +554,8 @@ static int op_status_change(dumb_ptr<env_t> env, Slice<val_t> args) { dumb_ptr<block_list> subject = ARGENTITY(0); - int invocation_id = env->VAR(VAR_INVOCATION).ty == TYPE::INVOCATION - ? env->VAR(VAR_INVOCATION).v.v_int : 0; + BlockId invocation_id = env->VAR(VAR_INVOCATION).ty == TYPE::INVOCATION + ? wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_INVOCATION).v.v_int)) : BlockId(); dumb_ptr<invocation> invocation_ = map_id_is_spell(invocation_id); assert (!ARGINT(3)); @@ -563,7 +566,7 @@ int op_status_change(dumb_ptr<env_t> env, Slice<val_t> args) static_cast<interval_t>(ARGINT(6)), invocation_id); if (invocation_ && subject->bl_type == BL::PC) - record_status_change(invocation_, subject->bl_id, StatusChange(ARGINT(1))); + record_status_change(invocation_, subject->bl_id, static_cast<StatusChange>(ARGINT(1))); return 0; } @@ -587,7 +590,7 @@ int op_override_attack(dumb_ptr<env_t> env, Slice<val_t> args) interval_t attack_delay = static_cast<interval_t>(ARGINT(2)); int attack_range = ARGINT(3); StatusChange icon = StatusChange(ARGINT(4)); - int look = ARGINT(5); + ItemNameId look = wrap<ItemNameId>(static_cast<uint16_t>(ARGINT(5))); int stopattack = ARGINT(6); dumb_ptr<map_session_data> subject; @@ -604,7 +607,7 @@ int op_override_attack(dumb_ptr<env_t> env, Slice<val_t> args) } subject->attack_spell_override = - trigger_spell(subject->bl_id, env->VAR(VAR_INVOCATION).v.v_int); + trigger_spell(subject->bl_id, wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_INVOCATION).v.v_int))); subject->attack_spell_charges = charges; if (subject->attack_spell_override) @@ -623,7 +626,7 @@ int op_override_attack(dumb_ptr<env_t> env, Slice<val_t> args) static int op_create_item(dumb_ptr<env_t>, Slice<val_t> args) { - struct item item; + Item item; dumb_ptr<block_list> entity = ARGENTITY(0); dumb_ptr<map_session_data> subject; int stackable; @@ -698,13 +701,13 @@ int op_spawn(dumb_ptr<env_t>, Slice<val_t> args) { dumb_ptr<area_t> area = ARGAREA(0); dumb_ptr<block_list> owner_e = ARGENTITY(1); - int monster_id = ARGINT(2); + Species monster_id = wrap<Species>(ARGINT(2)); MonsterAttitude monster_attitude = static_cast<MonsterAttitude>(ARGINT(3)); int monster_count = ARGINT(4); interval_t monster_lifetime = static_cast<interval_t>(ARGINT(5)); int i; - dumb_ptr<map_session_data> owner = NULL; + dumb_ptr<map_session_data> owner = nullptr; if (monster_attitude == MonsterAttitude::SERVANT && owner_e->bl_type == BL::PC) owner = owner_e->is_player(); @@ -714,7 +717,7 @@ int op_spawn(dumb_ptr<env_t>, Slice<val_t> args) location_t loc; magic_random_location(&loc, area); - int mob_id; + BlockId mob_id; dumb_ptr<mob_data> mob; mob_id = mob_once_spawn(owner, loc.m->name_, loc.x, loc.y, JAPANESE_NAME, // Is that needed? @@ -724,7 +727,7 @@ int op_spawn(dumb_ptr<env_t>, Slice<val_t> args) if (mob) { - mob->mode = mob_db[monster_id].mode; + mob->mode = get_mob_db(monster_id).mode; switch (monster_attitude) { @@ -770,18 +773,18 @@ int op_spawn(dumb_ptr<env_t>, Slice<val_t> args) } static -const char *get_invocation_name(dumb_ptr<env_t> env) +ZString get_invocation_name(dumb_ptr<env_t> env) { dumb_ptr<invocation> invocation_; if (env->VAR(VAR_INVOCATION).ty != TYPE::INVOCATION) - return "?"; - invocation_ = map_id_is_spell(env->VAR(VAR_INVOCATION).v.v_int); + return "?"_s; + invocation_ = map_id_is_spell(wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_INVOCATION).v.v_int))); if (invocation_) - return invocation_->spell->name.c_str(); + return invocation_->spell->name; else - return "??"; + return "??"_s; } static @@ -824,9 +827,9 @@ int op_injure(dumb_ptr<env_t> env, Slice<val_t> args) { dumb_ptr<mob_data> mob = target->is_mob(); - MAP_LOG_PC(caster_pc, "SPELLDMG MOB%d %d FOR %d BY %s", - mob->bl_id, mob->mob_class, damage_caused, - get_invocation_name(env)); + MAP_LOG_PC(caster_pc, "SPELLDMG MOB%d %d FOR %d BY %s"_fmt, + mob->bl_id, mob->mob_class, damage_caused, + get_invocation_name(env)); } } battle_damage(caster, target, damage_caused, mp_damage); @@ -847,7 +850,7 @@ int op_emote(dumb_ptr<env_t>, Slice<val_t> args) static int op_set_script_variable(dumb_ptr<env_t>, Slice<val_t> args) { - dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; + dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr; VarName varname = stringish<VarName>(ARGSTR(1)); int array_index = 0; @@ -862,7 +865,7 @@ int op_set_script_variable(dumb_ptr<env_t>, Slice<val_t> args) static int op_set_script_str(dumb_ptr<env_t>, Slice<val_t> args) { - dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; + dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr; VarName varname = stringish<VarName>(ARGSTR(1)); int array_index = 0; @@ -877,7 +880,7 @@ int op_set_script_str(dumb_ptr<env_t>, Slice<val_t> args) static int op_set_hair_colour(dumb_ptr<env_t>, Slice<val_t> args) { - dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; + dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr; if (!c) return 1; @@ -890,7 +893,7 @@ int op_set_hair_colour(dumb_ptr<env_t>, Slice<val_t> args) static int op_set_hair_style(dumb_ptr<env_t>, Slice<val_t> args) { - dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; + dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr; if (!c) return 1; @@ -903,25 +906,29 @@ int op_set_hair_style(dumb_ptr<env_t>, Slice<val_t> args) static int op_drop_item_for (dumb_ptr<env_t>, Slice<val_t> args) { - struct item item; + Item item; int stackable; location_t *loc = &ARGLOCATION(0); int count = ARGINT(2); interval_t interval = static_cast<interval_t>(ARGINT(3)); - dumb_ptr<map_session_data> c = ((args.size() > 4) && (ENTITY_TYPE(4) == BL::PC)) ? ARGPC(4) : NULL; + dumb_ptr<map_session_data> c = ((args.size() > 4) && (ENTITY_TYPE(4) == BL::PC)) ? ARGPC(4) : nullptr; interval_t delay = (args.size() > 5) ? static_cast<interval_t>(ARGINT(5)) : interval_t::zero(); interval_t delaytime[3] = { delay, delay, delay }; - dumb_ptr<map_session_data> owners[3] = { c, NULL, NULL }; + dumb_ptr<map_session_data> owners[3] = { c, nullptr, nullptr }; GET_ARG_ITEM(1, item, stackable); if (stackable) + { map_addflooritem_any(&item, count, loc->m, loc->x, loc->y, owners, delaytime, interval, 0); + } else + { while (count-- > 0) map_addflooritem_any(&item, 1, loc->m, loc->x, loc->y, owners, delaytime, interval, 0); + } return 0; } @@ -929,7 +936,7 @@ int op_drop_item_for (dumb_ptr<env_t>, Slice<val_t> args) static int op_gain_exp(dumb_ptr<env_t>, Slice<val_t> args) { - dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; + dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr; if (!c) return 1; @@ -940,35 +947,35 @@ int op_gain_exp(dumb_ptr<env_t>, Slice<val_t> args) } #define MAGIC_OPERATION(name, args, impl) {{name}, {{name}, {args}, impl}} -#define MAGIC_OPERATION1(name, args) MAGIC_OPERATION(#name, args, op_##name) +#define MAGIC_OPERATION1(name, args) MAGIC_OPERATION(#name##_s, args, op_##name) static std::map<ZString, op_t> operations = { - MAGIC_OPERATION1(sfx, ".ii"), - MAGIC_OPERATION1(instaheal, "eii"), - MAGIC_OPERATION1(itemheal, "eii"), - MAGIC_OPERATION1(shroud, "ei"), - MAGIC_OPERATION("unshroud", "e", op_reveal), - MAGIC_OPERATION1(message, "es"), - MAGIC_OPERATION1(messenger_npc, "lissi"), - MAGIC_OPERATION1(move, "ed"), - MAGIC_OPERATION1(warp, "el"), - MAGIC_OPERATION1(banish, "e"), - MAGIC_OPERATION1(status_change, "eiiiiii"), - MAGIC_OPERATION1(stop_status_change, "ei"), - MAGIC_OPERATION1(override_attack, "eiiiiii"), - MAGIC_OPERATION1(create_item, "e.i"), - MAGIC_OPERATION1(aggravate, "eie"), - MAGIC_OPERATION1(spawn, "aeiiii"), - MAGIC_OPERATION1(injure, "eeii"), - MAGIC_OPERATION1(emote, "ei"), - MAGIC_OPERATION1(set_script_variable, "esi"), - MAGIC_OPERATION1(set_script_str, "ess"), - MAGIC_OPERATION1(set_hair_colour, "ei"), - MAGIC_OPERATION1(set_hair_style, "ei"), - MAGIC_OPERATION("drop_item", "l.ii", op_drop_item_for), - MAGIC_OPERATION1(drop_item_for, "l.iiei"), - MAGIC_OPERATION("gain_experience", "eiii", op_gain_exp), + MAGIC_OPERATION1(sfx, ".ii"_s), + MAGIC_OPERATION1(instaheal, "eii"_s), + MAGIC_OPERATION1(itemheal, "eii"_s), + MAGIC_OPERATION1(shroud, "ei"_s), + MAGIC_OPERATION("unshroud"_s, "e"_s, op_reveal), + MAGIC_OPERATION1(message, "es"_s), + MAGIC_OPERATION1(messenger_npc, "lissi"_s), + MAGIC_OPERATION1(move, "ed"_s), + MAGIC_OPERATION1(warp, "el"_s), + MAGIC_OPERATION1(banish, "e"_s), + MAGIC_OPERATION1(status_change, "eiiiiii"_s), + MAGIC_OPERATION1(stop_status_change, "ei"_s), + MAGIC_OPERATION1(override_attack, "eiiiiii"_s), + MAGIC_OPERATION1(create_item, "e.i"_s), + MAGIC_OPERATION1(aggravate, "eie"_s), + MAGIC_OPERATION1(spawn, "aeiiii"_s), + MAGIC_OPERATION1(injure, "eeii"_s), + MAGIC_OPERATION1(emote, "ei"_s), + MAGIC_OPERATION1(set_script_variable, "esi"_s), + MAGIC_OPERATION1(set_script_str, "ess"_s), + MAGIC_OPERATION1(set_hair_colour, "ei"_s), + MAGIC_OPERATION1(set_hair_style, "ei"_s), + MAGIC_OPERATION("drop_item"_s, "l.ii"_s, op_drop_item_for), + MAGIC_OPERATION1(drop_item_for, "l.iiei"_s), + MAGIC_OPERATION("gain_experience"_s, "eiii"_s, op_gain_exp), }; op_t *magic_get_op(ZString name) @@ -979,7 +986,7 @@ op_t *magic_get_op(ZString name) return &it->second; } -void spell_effect_report_termination(int invocation_id, int bl_id, +void spell_effect_report_termination(BlockId invocation_id, BlockId bl_id, StatusChange sc_id, int) { dumb_ptr<invocation> invocation_ = map_id_is_spell(invocation_id); @@ -1004,8 +1011,8 @@ void spell_effect_report_termination(int invocation_id, int bl_id, dumb_ptr<block_list> entity = map_id2bl(bl_id); if (entity->bl_type == BL::PC) FPRINTF(stderr, - "[magic] INTERNAL ERROR: spell-effect-report-termination: tried to terminate on unexpected bl %d, sc %d\n", - bl_id, sc_id); + "[magic] INTERNAL ERROR: spell-effect-report-termination: tried to terminate on unexpected bl %d, sc %d\n"_fmt, + bl_id, sc_id); return; } @@ -1015,7 +1022,7 @@ static dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_) { if (!invocation_->stack_size) - return NULL; + return nullptr; else { cont_activation_record_t *ar = @@ -1042,7 +1049,7 @@ dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_) case CONT_STACK::FOREACH: { - int entity_id; + BlockId entity_id; val_t *var = &invocation_->env->varu[ar->c.c_foreach.id]; do @@ -1065,7 +1072,7 @@ dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_) magic_clear_var(var); var->ty = ar->c.c_foreach.ty; - var->v.v_int = entity_id; + var->v.v_int = static_cast<int32_t>(unwrap<BlockId>(entity_id)); return ar->c.c_foreach.body; } @@ -1089,9 +1096,9 @@ dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_) default: FPRINTF(stderr, - "[magic] INTERNAL ERROR: While executing spell `%s': stack corruption\n", - invocation_->spell->name); - return NULL; + "[magic] INTERNAL ERROR: While executing spell `%s': stack corruption\n"_fmt, + invocation_->spell->name); + return nullptr; } } } @@ -1105,10 +1112,10 @@ cont_activation_record_t *add_stack_entry(dumb_ptr<invocation> invocation_, if (invocation_->stack_size >= MAX_STACK_SIZE) { FPRINTF(stderr, - "[magic] Execution stack size exceeded in spell `%s'; truncating effect\n", - invocation_->spell->name); + "[magic] Execution stack size exceeded in spell `%s'; truncating effect\n"_fmt, + invocation_->spell->name); invocation_->stack_size--; - return NULL; + return nullptr; } ar->ty = ty; @@ -1118,7 +1125,7 @@ cont_activation_record_t *add_stack_entry(dumb_ptr<invocation> invocation_, static void find_entities_in_area_c(dumb_ptr<block_list> target, - std::vector<int> *entities_vp, + std::vector<BlockId> *entities_vp, FOREACH_FILTER filter) { switch (target->bl_type) @@ -1180,7 +1187,7 @@ void find_entities_in_area_c(dumb_ptr<block_list> target, static void find_entities_in_area(area_t& area_, - std::vector<int> *entities_vp, + std::vector<BlockId> *entities_vp, FOREACH_FILTER filter) { area_t *area = &area_; // temporary hack to "keep diff small". Heh. @@ -1221,8 +1228,8 @@ dumb_ptr<effect_t> run_foreach(dumb_ptr<invocation> invocation, { magic_clear_var(&area); FPRINTF(stderr, - "[magic] Error in spell `%s': FOREACH loop over non-area\n", - invocation->spell->name.c_str()); + "[magic] Error in spell `%s': FOREACH loop over non-area\n"_fmt, + invocation->spell->name); return return_location; } else @@ -1233,7 +1240,7 @@ dumb_ptr<effect_t> run_foreach(dumb_ptr<invocation> invocation, if (!ar) return return_location; - std::vector<int> entities_v; + std::vector<BlockId> entities_v; find_entities_in_area(*area.v.v_area, &entities_v, filter); entities_v.shrink_to_fit(); @@ -1271,8 +1278,8 @@ dumb_ptr<effect_t> run_for (dumb_ptr<invocation> invocation, magic_clear_var(&start); magic_clear_var(&stop); FPRINTF(stderr, - "[magic] Error in spell `%s': FOR loop start or stop point is not an integer\n", - invocation->spell->name); + "[magic] Error in spell `%s': FOR loop start or stop point is not an integer\n"_fmt, + invocation->spell->name); return return_location; } @@ -1319,9 +1326,9 @@ void print_cfg(int i, effect_t *e) { int j; for (j = 0; j < i; j++) - PRINTF(" "); + PRINTF(" "_fmt); - PRINTF("%p: ", e); + PRINTF("%p: "_fmt, e); if (!e) { @@ -1354,11 +1361,11 @@ void print_cfg(int i, effect_t *e) case EFFECT::IF: puts("IF"); for (j = 0; j < i; j++) - PRINTF(" "); + PRINTF(" "_fmt); puts("THEN"); print_cfg(i + 1, e->e.e_if.true_branch); for (j = 0; j < i; j++) - PRINTF(" "); + PRINTF(" "_fmt); puts("ELSE"); print_cfg(i + 1, e->e.e_if.false_branch); break; @@ -1391,12 +1398,12 @@ void print_cfg(int i, effect_t *e) static interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) { - const int invocation_id = invocation_->bl_id; + const BlockId invocation_id = invocation_->bl_id; #define REFRESH_INVOCATION invocation_ = map_id_is_spell(invocation_id); if (!invocation_) return interval_t::zero(); #ifdef DEBUG - FPRINTF(stderr, "Resuming execution: invocation of `%s'\n", - invocation_->spell->name); + FPRINTF(stderr, "Resuming execution: invocation of `%s'\n"_fmt, + invocation_->spell->name); print_cfg(1, invocation_->current_effect); #endif while (invocation_->current_effect) @@ -1406,7 +1413,7 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) int i; #ifdef DEBUG - FPRINTF(stderr, "Next step of type %d\n", e->ty); + FPRINTF(stderr, "Next step of type %d\n"_fmt, e->ty); dump_env(invocation_->env); #endif @@ -1417,11 +1424,11 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) case EFFECT::ABORT: invocation_->flags |= INVOCATION_FLAG::ABORTED; - invocation_->end_effect = NULL; + invocation_->end_effect = nullptr; FALLTHROUGH; case EFFECT::END: clear_stack(invocation_); - next = NULL; + next = nullptr; break; case EFFECT::ASSIGN: @@ -1464,14 +1471,14 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) ZString caster_name = (caster ? caster->status_key.name : CharName()).to__actual(); argrec_t arg[3] = { - {"@target", env->VAR(VAR_TARGET).ty == TYPE::ENTITY ? 0 : env->VAR(VAR_TARGET).v.v_int}, - {"@caster", invocation_->caster}, - {"@caster_name$", caster_name}, + {"@target"_s, env->VAR(VAR_TARGET).ty == TYPE::ENTITY ? 0 : env->VAR(VAR_TARGET).v.v_int}, + {"@caster"_s, static_cast<int32_t>(unwrap<BlockId>(invocation_->caster))}, + {"@caster_name$"_s, caster_name}, }; - int message_recipient = - env->VAR(VAR_SCRIPTTARGET).ty == - TYPE::ENTITY ? env->VAR(VAR_SCRIPTTARGET). - v.v_int : invocation_->caster; + BlockId message_recipient = + env->VAR(VAR_SCRIPTTARGET).ty == TYPE::ENTITY + ? wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_SCRIPTTARGET).v.v_int)) + : invocation_->caster; dumb_ptr<map_session_data> recipient = map_id_is_player(message_recipient); if (recipient->npc_id @@ -1516,7 +1523,7 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) for (i = 0; i < e->e.e_op.args_nr; i++) magic_eval(invocation_->env, &args[i], e->e.e_op.args[i]); - if (!magic_signature_check("effect", op->name, op->signature, + if (!magic_signature_check("effect"_s, op->name, op->signature, Slice<val_t>(args, e->e.e_op.args_nr), e->e.e_op.line_nr, e->e.e_op.column)) @@ -1535,8 +1542,8 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete) default: FPRINTF(stderr, - "[magic] INTERNAL ERROR: Unknown effect %d\n", - e->ty); + "[magic] INTERNAL ERROR: Unknown effect %d\n"_fmt, + e->ty); } if (!next) @@ -1583,7 +1590,7 @@ void spell_execute_script(dumb_ptr<invocation> invocation) * running the same spell twice! */ } -int spell_attack(int caster_id, int target_id) +int spell_attack(BlockId caster_id, BlockId target_id) { dumb_ptr<map_session_data> caster = map_id_is_player(caster_id); dumb_ptr<invocation> invocation_; @@ -1601,7 +1608,7 @@ int spell_attack(int caster_id, int target_id) { magic_clear_var(&invocation_->env->varu[VAR_TARGET]); invocation_->env->varu[VAR_TARGET].ty = TYPE::ENTITY; - invocation_->env->varu[VAR_TARGET].v.v_int = target_id; + invocation_->env->varu[VAR_TARGET].v.v_int = static_cast<int32_t>(unwrap<BlockId>(target_id)); invocation_->current_effect = invocation_->trigger_effect; invocation_->flags &= ~INVOCATION_FLAG::ABORTED; @@ -1622,8 +1629,8 @@ int spell_attack(int caster_id, int target_id) } else if (!invocation_ || caster->attack_spell_charges <= 0) { - caster->attack_spell_override = 0; - char_set_weapon_icon(caster, 0, StatusChange::ZERO, 0); + caster->attack_spell_override = BlockId(); + char_set_weapon_icon(caster, 0, StatusChange::ZERO, ItemNameId()); char_set_attack_info(caster, interval_t::zero(), 0); if (stop_attack) @@ -1635,3 +1642,4 @@ int spell_attack(int caster_id, int target_id) return 1; } +} // namespace tmwa diff --git a/src/map/magic-stmt.hpp b/src/map/magic-stmt.hpp index 838854f..729562e 100644 --- a/src/map/magic-stmt.hpp +++ b/src/map/magic-stmt.hpp @@ -1,8 +1,8 @@ -#ifndef TMWA_MAP_MAGIC_STMT_HPP -#define TMWA_MAP_MAGIC_STMT_HPP -// magic-stmt.hpp - dummy header to make Make dependencies work. +#pragma once +// magic-stmt.hpp - Imperative commands for the magic backend. // -// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> +// Copyright © 2004-2011 The Mana World Development Team +// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> // // This file is part of The Mana World (Athena server) // @@ -19,6 +19,73 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -#endif // TMWA_MAP_MAGIC_STMT_HPP +#include "../range/fwd.hpp" + +#include "../strings/zstring.hpp" + +#include "../generic/fwd.hpp" + +#include "skill.t.hpp" + + +namespace tmwa +{ +struct op_t +{ + ZString name; + ZString signature; + int (*op)(dumb_ptr<env_t> env, Slice<val_t> arga); +}; + +/** + * Retrieves an operation by name + * @param name The name to look up + * @return An operation of that name, or nullptr, and a function index + */ +op_t *magic_get_op(ZString name); + +/** + * Removes the shroud from a character + * + * \param character The character to remove the shroud from + */ +void magic_unshroud(dumb_ptr<map_session_data> character); + +/** + * Notifies a running spell that a status_change timer triggered by the spell has expired + * + * \param invocation The invocation to notify + * \param bl_id ID of the PC for whom this happened + * \param sc_id ID of the status change entry that finished + * \param supplanted Whether the status_change finished normally (0) or was supplanted by a new status_change (1) + */ +void spell_effect_report_termination(BlockId invocation, BlockId bl_id, + StatusChange sc_id, int supplanted); + +/** + * Execute a spell invocation and sets up timers to finish + */ +void spell_execute(dumb_ptr<invocation> invocation); + +/** + * Continue an NPC script embedded in a spell + */ +void spell_execute_script(dumb_ptr<invocation> invocation); + +/** + * Stops all magic bound to the specified character + * + */ +void magic_stop_completely(dumb_ptr<map_session_data> c); + +/** + * Attacks with a magical spell charged to the character + * + * Returns 0 if there is no charged spell or the spell is depleted. + */ +int spell_attack(BlockId caster, BlockId target); + +void spell_free_invocation(dumb_ptr<invocation> invocation); +} // namespace tmwa diff --git a/src/map/magic-v2.cpp b/src/map/magic-v2.cpp index 41d29cd..a671dea 100644 --- a/src/map/magic-v2.cpp +++ b/src/map/magic-v2.cpp @@ -18,17 +18,33 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include <cstddef> + +#include <algorithm> +#include <map> #include <set> -#include "../sexpr/parser.hpp" +#include "../strings/rstring.hpp" +#include "../strings/literal.hpp" + +#include "../generic/dumb_ptr.hpp" + +#include "../io/cxxstdio.hpp" +#include "../io/line.hpp" -#include "../mmo/dumb_ptr.hpp" +#include "../sexpr/parser.hpp" #include "itemdb.hpp" #include "magic-expr.hpp" +#include "magic-interpreter.hpp" +#include "magic-interpreter-base.hpp" +#include "magic-stmt.hpp" #include "../poison.hpp" + +namespace tmwa +{ namespace magic_v2 { static @@ -61,8 +77,8 @@ namespace magic_v2 if (zid != id) { FPRINTF(stderr, - "[magic-conf] INTERNAL ERROR: Builtin special var %s interned to %d, not %d as it should be!\n", - name, zid, id); + "[magic-conf] INTERNAL ERROR: Builtin special var %s interned to %d, not %d as it should be!\n"_fmt, + name, zid, id); } return zid == id; } @@ -72,15 +88,15 @@ namespace magic_v2 { bool ok = true; - ok &= INTERN_ASSERT("min_casttime", VAR_MIN_CASTTIME); - ok &= INTERN_ASSERT("obscure_chance", VAR_OBSCURE_CHANCE); - ok &= INTERN_ASSERT("caster", VAR_CASTER); - ok &= INTERN_ASSERT("spellpower", VAR_SPELLPOWER); - ok &= INTERN_ASSERT("self_spell", VAR_SPELL); - ok &= INTERN_ASSERT("self_invocation", VAR_INVOCATION); - ok &= INTERN_ASSERT("target", VAR_TARGET); - ok &= INTERN_ASSERT("script_target", VAR_SCRIPTTARGET); - ok &= INTERN_ASSERT("location", VAR_LOCATION); + ok &= INTERN_ASSERT("min_casttime"_s, VAR_MIN_CASTTIME); + ok &= INTERN_ASSERT("obscure_chance"_s, VAR_OBSCURE_CHANCE); + ok &= INTERN_ASSERT("caster"_s, VAR_CASTER); + ok &= INTERN_ASSERT("spellpower"_s, VAR_SPELLPOWER); + ok &= INTERN_ASSERT("self_spell"_s, VAR_SPELL); + ok &= INTERN_ASSERT("self_invocation"_s, VAR_INVOCATION); + ok &= INTERN_ASSERT("target"_s, VAR_TARGET); + ok &= INTERN_ASSERT("script_target"_s, VAR_SCRIPTTARGET); + ok &= INTERN_ASSERT("location"_s, VAR_LOCATION); return ok; } @@ -91,7 +107,7 @@ namespace magic_v2 { if (!const_defm.insert({name, *val}).second) { - span.error(STRPRINTF("Redefinition of constant '%s'", name)); + span.error(STRPRINTF("Redefinition of constant '%s'"_fmt, name)); return false; } return true; @@ -103,7 +119,7 @@ namespace magic_v2 if (it != const_defm.end()) return &it->second; - return NULL; + return nullptr; } static dumb_ptr<effect_t> new_effect(EFFECT ty) @@ -184,14 +200,14 @@ namespace magic_v2 auto pair1 = magic_conf.spells_by_name.insert({spell->name, spell}); if (!pair1.second) { - span.error(STRPRINTF("Attempt to redefine spell '%s'", spell->name)); + span.error(STRPRINTF("Attempt to redefine spell '%s'"_fmt, spell->name)); return false; } auto pair2 = magic_conf.spells_by_invocation.insert({spell->invocation, spell}); if (!pair2.second) { - span.error(STRPRINTF("Attempt to redefine spell invocation '%s'", spell->invocation)); + span.error(STRPRINTF("Attempt to redefine spell invocation '%s'"_fmt, spell->invocation)); magic_conf.spells_by_name.erase(pair1.first); return false; } @@ -203,14 +219,14 @@ namespace magic_v2 auto pair1 = magic_conf.anchors_by_name.insert({anchor->name, anchor}); if (!pair1.second) { - span.error(STRPRINTF("Attempt to redefine teleport anchor '%s'", anchor->name)); + span.error(STRPRINTF("Attempt to redefine teleport anchor '%s'"_fmt, anchor->name)); return false; } auto pair2 = magic_conf.anchors_by_invocation.insert({anchor->name, anchor}); if (!pair2.second) { - span.error(STRPRINTF("Attempt to redefine anchor invocation '%s'", anchor->invocation)); + span.error(STRPRINTF("Attempt to redefine anchor invocation '%s'"_fmt, anchor->invocation)); magic_conf.anchors_by_name.erase(pair1.first); return false; } @@ -223,7 +239,7 @@ namespace magic_v2 RString name = proc->name; if (!procs.insert({name, std::move(*proc)}).second) { - span.error("procedure already exists"); + span.error("procedure already exists"_s); return false; } return true; @@ -234,7 +250,7 @@ namespace magic_v2 auto pi = procs.find(name); if (pi == procs.end()) { - span.error(STRPRINTF("Unknown procedure '%s'", name)); + span.error(STRPRINTF("Unknown procedure '%s'"_fmt, name)); return false; } @@ -242,7 +258,7 @@ namespace magic_v2 if (p->argv.size() != argvp->size()) { - span.error(STRPRINTF("Procedure %s/%zu invoked with %zu parameters", + span.error(STRPRINTF("Procedure %s/%zu invoked with %zu parameters"_fmt, name, p->argv.size(), argvp->size())); return false; } @@ -259,13 +275,13 @@ namespace magic_v2 op_t *op = magic_get_op(name); if (!op) { - span.error(STRPRINTF("Unknown operation '%s'", name)); + span.error(STRPRINTF("Unknown operation '%s'"_fmt, name)); return false; } if (op->signature.size() != argv.size()) { - span.error(STRPRINTF("Incorrect number of arguments to operation '%s': Expected %zu, found %zu", - name, op->signature.size(), argv.size())); + span.error(STRPRINTF("Incorrect number of arguments to operation '%s': Expected %zu, found %zu"_fmt, + name, op->signature.size(), argv.size())); return false; } @@ -295,13 +311,13 @@ namespace magic_v2 fun_t *fun = magic_get_fun(name); if (!fun) { - span.error(STRPRINTF("Unknown function '%s'", name)); + span.error(STRPRINTF("Unknown function '%s'"_fmt, name)); return false; } if (fun->signature.size() != argv.size()) { - span.error(STRPRINTF("Incorrect number of arguments to function '%s': Expected %zu, found %zu", - name, fun->signature.size(), argv.size())); + span.error(STRPRINTF("Incorrect number of arguments to function '%s': Expected %zu, found %zu"_fmt, + name, fun->signature.size(), argv.size())); return false; } expr = magic_new_expr(EXPR::FUNAPP); @@ -362,20 +378,20 @@ namespace magic_v2 return false; if (s._list[0]._type != sexpr::TOKEN) return false; - return s._list[0]._str == "DISABLED"; + return s._list[0]._str == "DISABLED"_s; } static bool parse_loc(const SExpr& s, e_location_t& loc) { if (s._type != sexpr::LIST) - return fail(s, "loc not list"); + return fail(s, "loc not list"_s); if (s._list.size() != 4) - return fail(s, "loc not 3 args"); + return fail(s, "loc not 3 args"_s); if (s._list[0]._type != sexpr::TOKEN) - return fail(s._list[0], "loc cmd not tok"); - if (s._list[0]._str != "@") - return fail(s._list[0], "loc cmd not cmd"); + return fail(s._list[0], "loc cmd not tok"_s); + if (s._list[0]._str != "@"_s) + return fail(s._list[0], "loc cmd not cmd"_s); return parse_expression(s._list[1], loc.m) && parse_expression(s._list[2], loc.x) && parse_expression(s._list[3], loc.y); @@ -392,7 +408,7 @@ namespace magic_v2 val.ty = TYPE::INT; val.v.v_int = x._int; if (val.v.v_int != x._int) - return fail(x, "integer too large"); + return fail(x, "integer too large"_s); out = magic_new_expr(EXPR::VAL); out->e.e_val = val; @@ -410,9 +426,11 @@ namespace magic_v2 } case sexpr::TOKEN: { - ZString dirs[8] = { - ZString("S"), ZString("SW"), ZString("W"), ZString("NW"), ZString("N"), ZString("NE"), ZString("E"), ZString("SE"), - }; + earray<LString, DIR, DIR::COUNT> dirs //= + {{ + "S"_s, "SW"_s, "W"_s, "NW"_s, + "N"_s, "NE"_s, "E"_s, "SE"_s, + }}; auto begin = std::begin(dirs); auto end = std::end(dirs); auto it = std::find(begin, end, x._str); @@ -444,13 +462,13 @@ namespace magic_v2 break; case sexpr::LIST: if (x._list.empty()) - return fail(x, "empty list"); + return fail(x, "empty list"_s); { if (x._list[0]._type != sexpr::TOKEN) - return fail(x._list[0], "op not token"); + return fail(x._list[0], "op not token"_s); ZString op = x._list[0]._str; // area - if (op == "@") + if (op == "@"_s) { e_location_t loc; if (!parse_loc(x, loc)) @@ -460,7 +478,7 @@ namespace magic_v2 out->e.e_area.a.a_loc = loc; return true; } - if (op == "@+") + if (op == "@+"_s) { e_location_t loc; dumb_ptr<expr_t> width; @@ -478,7 +496,7 @@ namespace magic_v2 out->e.e_area.a.a_rect.height = height; return true; } - if (op == "TOWARDS") + if (op == "TOWARDS"_s) { e_location_t loc; dumb_ptr<expr_t> dir; @@ -500,33 +518,33 @@ namespace magic_v2 out->e.e_area.a.a_bar.depth = depth; return true; } - if (op == ".") + if (op == "."_s) { if (x._list.size() != 3) - return fail(x, ". not 2"); + return fail(x, ". not 2"_s); dumb_ptr<expr_t> expr; if (!parse_expression(x._list[1], expr)) return false; if (x._list[2]._type != sexpr::TOKEN) - return fail(x._list[2], ".elem not name"); + return fail(x._list[2], ".elem not name"_s); ZString elem = x._list[2]._str; out = dot_expr(expr, intern_id(elem)); return true; } - static + static // TODO LString std::set<ZString> ops = { - "<", ">", "<=", ">=", "==", "!=", - "+", "-", "*", "%", "/", - "&", "^", "|", "<<", ">>", - "&&", "||", + "<"_s, ">"_s, "<="_s, ">="_s, "=="_s, "!="_s, + "+"_s, "-"_s, "*"_s, "%"_s, "/"_s, + "&"_s, "^"_s, "|"_s, "<<"_s, ">>"_s, + "&&"_s, "||"_s, }; // TODO implement unary operators if (ops.count(op)) { // operators are n-ary and left-associative if (x._list.size() < 3) - return fail(x, "operator not at least 2 args"); + return fail(x, "operator not at least 2 args"_s); auto begin = x._list.begin() + 1; auto end = x._list.end(); if (!parse_expression(*begin, out)) @@ -557,7 +575,7 @@ namespace magic_v2 } static - bool parse_item(const SExpr& s, int& id, int& count) + bool parse_item(const SExpr& s, ItemNameId& id, int& count) { if (s._type == sexpr::STRING) { @@ -565,23 +583,23 @@ namespace magic_v2 item_data *item = itemdb_searchname(s._str); if (!item) - return fail(s, "no such item"); + return fail(s, "no such item"_s); id = item->nameid; return true; } if (s._type != sexpr::LIST) - return fail(s, "item not string or list"); + return fail(s, "item not string or list"_s); if (s._list.size() != 2) - return fail(s, "item list is not pair"); + return fail(s, "item list is not pair"_s); if (s._list[0]._type != sexpr::INT) - return fail(s._list[0], "item pair first not int"); + return fail(s._list[0], "item pair first not int"_s); count = s._list[0]._int; if (s._list[1]._type != sexpr::STRING) - return fail(s._list[1], "item pair second not name"); + return fail(s._list[1], "item pair second not name"_s); item_data *item = itemdb_searchname(s._list[1]._str); if (!item) - return fail(s, "no such item"); + return fail(s, "no such item"_s); id = item->nameid; return true; } @@ -590,18 +608,18 @@ namespace magic_v2 bool parse_spellguard(const SExpr& s, dumb_ptr<spellguard_t>& out) { if (s._type != sexpr::LIST) - return fail(s, "not list"); + return fail(s, "not list"_s); if (s._list.empty()) - return fail(s, "empty list"); + return fail(s, "empty list"_s); if (s._list[0]._type != sexpr::TOKEN) - return fail(s._list[0], "not token"); + return fail(s._list[0], "not token"_s); ZString cmd = s._list[0]._str; - if (cmd == "OR") + if (cmd == "OR"_s) { auto begin = s._list.begin() + 1; auto end = s._list.end(); if (begin == end) - return fail(s, "missing arguments"); + return fail(s, "missing arguments"_s); if (!parse_spellguard(*begin, out)) return false; ++begin; @@ -617,14 +635,14 @@ namespace magic_v2 } return true; } - if (cmd == "GUARD") + if (cmd == "GUARD"_s) { auto begin = s._list.begin() + 1; auto end = s._list.end(); while (is_comment(end[-1])) --end; if (begin == end) - return fail(s, "missing arguments"); + return fail(s, "missing arguments"_s); if (!parse_spellguard(end[-1], out)) return false; --end; @@ -639,10 +657,10 @@ namespace magic_v2 } return true; } - if (cmd == "REQUIRE") + if (cmd == "REQUIRE"_s) { if (s._list.size() != 2) - return fail(s, "not one argument"); + return fail(s, "not one argument"_s); dumb_ptr<expr_t> condition; if (!parse_expression(s._list[1], condition)) return false; @@ -650,10 +668,10 @@ namespace magic_v2 out->s.s_condition = condition; return true; } - if (cmd == "MANA") + if (cmd == "MANA"_s) { if (s._list.size() != 2) - return fail(s, "not one argument"); + return fail(s, "not one argument"_s); dumb_ptr<expr_t> mana; if (!parse_expression(s._list[1], mana)) return false; @@ -661,10 +679,10 @@ namespace magic_v2 out->s.s_mana = mana; return true; } - if (cmd == "CASTTIME") + if (cmd == "CASTTIME"_s) { if (s._list.size() != 2) - return fail(s, "not one argument"); + return fail(s, "not one argument"_s); dumb_ptr<expr_t> casttime; if (!parse_expression(s._list[1], casttime)) return false; @@ -672,12 +690,13 @@ namespace magic_v2 out->s.s_casttime = casttime; return true; } - if (cmd == "CATALYSTS") + if (cmd == "CATALYSTS"_s) { dumb_ptr<component_t> items = nullptr; for (auto it = s._list.begin() + 1, end = s._list.end(); it != end; ++it) { - int id, count; + ItemNameId id; + int count; if (!parse_item(*it, id, count)) return false; magic_add_component(&items, id, count); @@ -686,12 +705,13 @@ namespace magic_v2 out->s.s_catalysts = items; return true; } - if (cmd == "COMPONENTS") + if (cmd == "COMPONENTS"_s) { dumb_ptr<component_t> items = nullptr; for (auto it = s._list.begin() + 1, end = s._list.end(); it != end; ++it) { - int id, count; + ItemNameId id; + int count; if (!parse_item(*it, id, count)) return false; magic_add_component(&items, id, count); @@ -700,7 +720,7 @@ namespace magic_v2 out->s.s_components = items; return true; } - return fail(s._list[0], "unknown guard"); + return fail(s._list[0], "unknown guard"_s); } static @@ -727,25 +747,25 @@ namespace magic_v2 bool parse_effect(const SExpr& s, dumb_ptr<effect_t>& out) { if (s._type != sexpr::LIST) - return fail(s, "not list"); + return fail(s, "not list"_s); if (s._list.empty()) - return fail(s, "empty list"); + return fail(s, "empty list"_s); if (s._list[0]._type != sexpr::TOKEN) - return fail(s._list[0], "not token"); + return fail(s._list[0], "not token"_s); ZString cmd = s._list[0]._str; - if (cmd == "BLOCK") + if (cmd == "BLOCK"_s) { return build_effect_list(s._list.begin() + 1, s._list.end(), out); } - if (cmd == "SET") + if (cmd == "SET"_s) { if (s._list.size() != 3) - return fail(s, "not 2 args"); + return fail(s, "not 2 args"_s); if (s._list[1]._type != sexpr::TOKEN) - return fail(s._list[1], "not token"); + return fail(s._list[1], "not token"_s); ZString name = s._list[1]._str; if (find_constant(name)) - return fail(s._list[1], "assigning to constant"); + return fail(s._list[1], "assigning to constant"_s); dumb_ptr<expr_t> expr; if (!parse_expression(s._list[2], expr)) return false; @@ -755,72 +775,72 @@ namespace magic_v2 out->e.e_assign.expr = expr; return true; } - if (cmd == "SCRIPT") + if (cmd == "SCRIPT"_s) { if (s._list.size() != 2) - return fail(s, "not 1 arg"); + return fail(s, "not 1 arg"_s); if (s._list[1]._type != sexpr::STRING) - return fail(s._list[1], "not string"); + return fail(s._list[1], "not string"_s); ZString body = s._list[1]._str; std::unique_ptr<const ScriptBuffer> script = parse_script(body, s._list[1]._span.begin.line, true); if (!script) - return fail(s._list[1], "script does not compile"); + return fail(s._list[1], "script does not compile"_s); out = new_effect(EFFECT::SCRIPT); out->e.e_script = dumb_ptr<const ScriptBuffer>(script.release()); return true; } - if (cmd == "SKIP") + if (cmd == "SKIP"_s) { if (s._list.size() != 1) - return fail(s, "not 0 arg"); + return fail(s, "not 0 arg"_s); out = new_effect(EFFECT::SKIP); return true; } - if (cmd == "ABORT") + if (cmd == "ABORT"_s) { if (s._list.size() != 1) - return fail(s, "not 0 arg"); + return fail(s, "not 0 arg"_s); out = new_effect(EFFECT::ABORT); return true; } - if (cmd == "END") + if (cmd == "END"_s) { if (s._list.size() != 1) - return fail(s, "not 0 arg"); + return fail(s, "not 0 arg"_s); out = new_effect(EFFECT::END); return true; } - if (cmd == "BREAK") + if (cmd == "BREAK"_s) { if (s._list.size() != 1) - return fail(s, "not 0 arg"); + return fail(s, "not 0 arg"_s); out = new_effect(EFFECT::BREAK); return true; } - if (cmd == "FOREACH") + if (cmd == "FOREACH"_s) { if (s._list.size() != 5) - return fail(s, "not 4 arg"); + return fail(s, "not 4 arg"_s); if (s._list[1]._type != sexpr::TOKEN) - return fail(s._list[1], "foreach type not token"); + return fail(s._list[1], "foreach type not token"_s); ZString type = s._list[1]._str; FOREACH_FILTER filter; - if (type == "PC") + if (type == "PC"_s) filter = FOREACH_FILTER::PC; - else if (type == "MOB") + else if (type == "MOB"_s) filter = FOREACH_FILTER::MOB; - else if (type == "ENTITY") + else if (type == "ENTITY"_s) filter = FOREACH_FILTER::ENTITY; - else if (type == "SPELL") + else if (type == "SPELL"_s) filter = FOREACH_FILTER::SPELL; - else if (type == "TARGET") + else if (type == "TARGET"_s) filter = FOREACH_FILTER::TARGET; - else if (type == "NPC") + else if (type == "NPC"_s) filter = FOREACH_FILTER::NPC; else - return fail(s._list[1], "unknown foreach filter"); + return fail(s._list[1], "unknown foreach filter"_s); if (s._list[2]._type != sexpr::TOKEN) - return fail(s._list[2], "foreach var not token"); + return fail(s._list[2], "foreach var not token"_s); ZString var = s._list[2]._str; dumb_ptr<expr_t> area; dumb_ptr<effect_t> effect; @@ -835,12 +855,12 @@ namespace magic_v2 out->e.e_foreach.filter = filter; return true; } - if (cmd == "FOR") + if (cmd == "FOR"_s) { if (s._list.size() != 5) - return fail(s, "not 4 arg"); + return fail(s, "not 4 arg"_s); if (s._list[1]._type != sexpr::TOKEN) - return fail(s._list[1], "for var not token"); + return fail(s._list[1], "for var not token"_s); ZString var = s._list[1]._str; dumb_ptr<expr_t> low; dumb_ptr<expr_t> high; @@ -858,10 +878,10 @@ namespace magic_v2 out->e.e_for.body = effect; return true; } - if (cmd == "IF") + if (cmd == "IF"_s) { if (s._list.size() != 3 && s._list.size() != 4) - return fail(s, "not 2 or 3 args"); + return fail(s, "not 2 or 3 args"_s); dumb_ptr<expr_t> cond; dumb_ptr<effect_t> if_true; dumb_ptr<effect_t> if_false; @@ -882,10 +902,10 @@ namespace magic_v2 out->e.e_if.false_branch = if_false; return true; } - if (cmd == "WAIT") + if (cmd == "WAIT"_s) { if (s._list.size() != 2) - return fail(s, "not 1 arg"); + return fail(s, "not 1 arg"_s); dumb_ptr<expr_t> expr; if (!parse_expression(s._list[1], expr)) return false; @@ -893,12 +913,12 @@ namespace magic_v2 out->e.e_sleep = expr; return true; } - if (cmd == "CALL") + if (cmd == "CALL"_s) { if (s._list.size() < 2) - return fail(s, "call what?"); + return fail(s, "call what?"_s); if (s._list[1]._type != sexpr::TOKEN) - return fail(s._list[1], "call token please"); + return fail(s._list[1], "call token please"_s); ZString func = s._list[1]._str; auto argvp = dumb_ptr<std::vector<dumb_ptr<expr_t>>>::make(); for (auto it = s._list.begin() + 2, end = s._list.end(); it != end; ++it) @@ -925,16 +945,16 @@ namespace magic_v2 bool parse_spellbody(const SExpr& s, dumb_ptr<spellguard_t>& out) { if (s._type != sexpr::LIST) - return fail(s, "not list"); + return fail(s, "not list"_s); if (s._list.empty()) - return fail(s, "empty list"); + return fail(s, "empty list"_s); if (s._list[0]._type != sexpr::TOKEN) - return fail(s._list[0], "not token"); + return fail(s._list[0], "not token"_s); ZString cmd = s._list[0]._str; - if (cmd == "=>") + if (cmd == "=>"_s) { if (s._list.size() != 3) - return fail(s, "list does not have exactly 2 arguments"); + return fail(s, "list does not have exactly 2 arguments"_s); dumb_ptr<spellguard_t> guard; if (!parse_spellguard(s._list[1], guard)) return false; @@ -944,10 +964,10 @@ namespace magic_v2 out = spellguard_implication(guard, body); return true; } - if (cmd == "|") + if (cmd == "|"_s) { if (s._list.size() == 1) - return fail(s, "spellbody choice empty"); + return fail(s, "spellbody choice empty"_s); auto begin = s._list.begin() + 1; auto end = s._list.end(); if (!parse_spellbody(*begin, out)) @@ -965,7 +985,7 @@ namespace magic_v2 } return true; } - if (cmd == "EFFECT") + if (cmd == "EFFECT"_s) { auto begin = s._list.begin() + 1; auto end = s._list.end(); @@ -978,7 +998,7 @@ namespace magic_v2 --end; if (end[-1]._type == sexpr::LIST && !end[-1]._list.empty() && end[-1]._list[0]._type == sexpr::TOKEN - && end[-1]._list[0]._str == "ATEND") + && end[-1]._list[0]._str == "ATEND"_s) { auto atb = end[-1]._list.begin() + 1; auto ate = end[-1]._list.end(); @@ -995,7 +1015,7 @@ namespace magic_v2 } if (end[-1]._type == sexpr::LIST && !end[-1]._list.empty() && end[-1]._list[0]._type == sexpr::TOKEN - && end[-1]._list[0]._str == "ATTRIGGER") + && end[-1]._list[0]._str == "ATTRIGGER"_s) { auto atb = end[-1]._list.begin() + 1; auto ate = end[-1]._list.end(); @@ -1015,20 +1035,20 @@ namespace magic_v2 out->s.s_effect.at_end = atend; return true; } - return fail(s._list[0], "unknown spellbody"); + return fail(s._list[0], "unknown spellbody"_s); } static bool parse_top_set(const std::vector<SExpr>& in) { if (in.size() != 3) - return fail(in[0], "not 2 arguments"); + return fail(in[0], "not 2 arguments"_s); ZString name = in[1]._str; dumb_ptr<expr_t> expr; if (!parse_expression(in[2], expr)) return false; if (find_constant(name)) - return fail(in[1], "assign constant"); + return fail(in[1], "assign constant"_s); size_t var_id = intern_id(name); magic_eval(dumb_ptr<env_t>(&magic_default_env), &magic_conf.varv[var_id].val, expr); return true; @@ -1037,9 +1057,9 @@ namespace magic_v2 bool parse_const(io::LineSpan span, const std::vector<SExpr>& in) { if (in.size() != 3) - return fail(in[0], "not 2 arguments"); + return fail(in[0], "not 2 arguments"_s); if (in[1]._type != sexpr::TOKEN) - return fail(in[1], "not token"); + return fail(in[1], "not token"_s); ZString name = in[1]._str; dumb_ptr<expr_t> expr; if (!parse_expression(in[2], expr)) @@ -1052,13 +1072,13 @@ namespace magic_v2 bool parse_anchor(io::LineSpan span, const std::vector<SExpr>& in) { if (in.size() != 4) - return fail(in[0], "not 3 arguments"); + return fail(in[0], "not 3 arguments"_s); auto anchor = dumb_ptr<teleport_anchor_t>::make(); if (in[1]._type != sexpr::TOKEN) - return fail(in[1], "not token"); + return fail(in[1], "not token"_s); anchor->name = in[1]._str; if (in[2]._type != sexpr::STRING) - return fail(in[2], "not string"); + return fail(in[2], "not string"_s); anchor->invocation = in[2]._str; dumb_ptr<expr_t> expr; if (!parse_expression(in[3], expr)) @@ -1070,17 +1090,17 @@ namespace magic_v2 bool parse_proc(io::LineSpan span, const std::vector<SExpr>& in) { if (in.size() < 4) - return fail(in[0], "not at least 3 arguments"); + return fail(in[0], "not at least 3 arguments"_s); auto proc = dumb_ptr<proc_t>::make(); if (in[1]._type != sexpr::TOKEN) - return fail(in[1], "name not token"); + return fail(in[1], "name not token"_s); proc->name = in[1]._str; if (in[2]._type != sexpr::LIST) - return fail(in[2], "args not list"); + return fail(in[2], "args not list"_s); for (const SExpr& arg : in[2]._list) { if (arg._type != sexpr::TOKEN) - return fail(arg, "arg not token"); + return fail(arg, "arg not token"_s); proc->argv.push_back(intern_id(arg._str)); } if (!build_effect_list(in.begin() + 3, in.end(), proc->body)) @@ -1091,37 +1111,37 @@ namespace magic_v2 bool parse_spell(io::LineSpan span, const std::vector<SExpr>& in) { if (in.size() < 6) - return fail(in[0], "not at least 5 arguments"); + return fail(in[0], "not at least 5 arguments"_s); if (in[1]._type != sexpr::LIST) - return fail(in[1], "flags not list"); + return fail(in[1], "flags not list"_s); auto spell = dumb_ptr<spell_t>::make(); for (const SExpr& s : in[1]._list) { if (s._type != sexpr::TOKEN) - return fail(s, "flag not token"); + return fail(s, "flag not token"_s); SPELL_FLAG flag = SPELL_FLAG::ZERO; - if (s._str == "LOCAL") + if (s._str == "LOCAL"_s) flag = SPELL_FLAG::LOCAL; - else if (s._str == "NONMAGIC") + else if (s._str == "NONMAGIC"_s) flag = SPELL_FLAG::NONMAGIC; - else if (s._str == "SILENT") + else if (s._str == "SILENT"_s) flag = SPELL_FLAG::SILENT; else - return fail(s, "unknown flag"); + return fail(s, "unknown flag"_s); if (bool(spell->flags & flag)) - return fail(s, "duplicate flag"); + return fail(s, "duplicate flag"_s); spell->flags |= flag; } if (in[2]._type != sexpr::TOKEN) - return fail(in[2], "name not token"); + return fail(in[2], "name not token"_s); spell->name = in[2]._str; if (in[3]._type != sexpr::STRING) - return fail(in[3], "invoc not string"); + return fail(in[3], "invoc not string"_s); spell->invocation = in[3]._str; if (in[4]._type != sexpr::LIST) - return fail(in[4], "spellarg not list"); + return fail(in[4], "spellarg not list"_s); if (in[4]._list.size() == 0) { spell->spellarg_ty = SPELLARG::NONE; @@ -1129,18 +1149,18 @@ namespace magic_v2 else { if (in[4]._list.size() != 2) - return fail(in[4], "spellarg not empty list or pair"); + return fail(in[4], "spellarg not empty list or pair"_s); if (in[4]._list[0]._type != sexpr::TOKEN) - return fail(in[4]._list[0], "spellarg type not token"); + return fail(in[4]._list[0], "spellarg type not token"_s); if (in[4]._list[1]._type != sexpr::TOKEN) - return fail(in[4]._list[1], "spellarg name not token"); + return fail(in[4]._list[1], "spellarg name not token"_s); ZString ty = in[4]._list[0]._str; - if (ty == "PC") + if (ty == "PC"_s) spell->spellarg_ty = SPELLARG::PC; - else if (ty == "STRING") + else if (ty == "STRING"_s) spell->spellarg_ty = SPELLARG::STRING; else - return fail(in[4]._list[0], "unknown spellarg type"); + return fail(in[4]._list[0], "unknown spellarg type"_s); ZString an = in[4]._list[1]._str; spell->arg = intern_id(an); } @@ -1148,19 +1168,19 @@ namespace magic_v2 for (;; ++it) { if (it == in.end()) - return fail(it[-1], "end of list scanning LET defs"); + return fail(it[-1], "end of list scanning LET defs"_s); if (is_comment(*it)) continue; if (it->_type != sexpr::LIST || it->_list.empty()) break; - if (it->_list[0]._type != sexpr::TOKEN || it->_list[0]._str != "LET") + if (it->_list[0]._type != sexpr::TOKEN || it->_list[0]._str != "LET"_s) break; if (it->_list[1]._type != sexpr::TOKEN) - return fail(it->_list[1], "let name not token"); + return fail(it->_list[1], "let name not token"_s); ZString name = it->_list[1]._str; if (find_constant(name)) - return fail(it->_list[1], "constant exists"); + return fail(it->_list[1], "constant exists"_s); dumb_ptr<expr_t> expr; if (!parse_expression(it->_list[2], expr)) return false; @@ -1170,7 +1190,7 @@ namespace magic_v2 spell->letdefv.push_back(let); } if (it + 1 != in.end()) - return fail(*it, "expected only one body entry besides LET"); + return fail(*it, "expected only one body entry besides LET"_s); // formally, 'guard' only refers to the first argument of '=>' // but internally, spellbodies use the same thing @@ -1186,23 +1206,23 @@ namespace magic_v2 { if (vs.empty()) { - span.error("Empty list at top"); + span.error("Empty list at top"_s); return false; } if (vs[0]._type != sexpr::TOKEN) - return fail(vs[0], "top not token"); + return fail(vs[0], "top not token"_s); ZString cmd = vs[0]._str; - if (cmd == "CONST") + if (cmd == "CONST"_s) return parse_const(span, vs); - if (cmd == "PROCEDURE") + if (cmd == "PROCEDURE"_s) return parse_proc(span, vs); - if (cmd == "SET") + if (cmd == "SET"_s) return parse_top_set(vs); - if (cmd == "SPELL") + if (cmd == "SPELL"_s) return parse_spell(span, vs); - if (cmd == "TELEPORT-ANCHOR") + if (cmd == "TELEPORT-ANCHOR"_s) return parse_anchor(span, vs); - return fail(vs[0], "Unknown top-level command"); + return fail(vs[0], "Unknown top-level command"_s); } static @@ -1214,14 +1234,14 @@ namespace magic_v2 if (is_comment(s)) continue; if (s._type != sexpr::LIST) - return fail(s, "top-level entity not a list or comment"); + return fail(s, "top-level entity not a list or comment"_s); if (!parse_top(s._span, s._list)) return false; } // handle low-level errors if (in.peek() != sexpr::TOK_EOF) { - in.span().error("parser gave up before end of file"); + in.span().error("parser gave up before end of file"_s); return false; } return true; @@ -1239,7 +1259,8 @@ bool load_magic_file_v2(ZString filename) bool rv = magic_v2::loop(in); if (!rv) { - in.span().error(STRPRINTF("next token: %s '%s'", sexpr::token_name(in.peek()), in.val_string())); + in.span().error(STRPRINTF("next token: %s '%s'"_fmt, sexpr::token_name(in.peek()), in.val_string())); } return rv; } +} // namespace tmwa diff --git a/src/map/magic-v2.hpp b/src/map/magic-v2.hpp index 888e183..07d467e 100644 --- a/src/map/magic-v2.hpp +++ b/src/map/magic-v2.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_MAGIC_V2_HPP -#define TMWA_MAP_MAGIC_V2_HPP +#pragma once // magic-v2.hpp - second generation magic parser // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,12 +18,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/zstring.hpp" +#include "../strings/zstring.hpp" + +namespace tmwa +{ bool magic_init0(); // must be called after itemdb initialization bool load_magic_file_v2(ZString filename); - -#endif // TMWA_MAP_MAGIC_V2_HPP +} // namespace tmwa diff --git a/src/map/magic.cpp b/src/map/magic.cpp index 9896b26..b899a5e 100644 --- a/src/map/magic.cpp +++ b/src/map/magic.cpp @@ -1,3 +1,4 @@ +#include "magic.hpp" // magic.cpp - Entry to the magic system. // // Copyright © 2004-2011 The Mana World Development Team @@ -18,23 +19,27 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <cstring> +#include <algorithm> +#include <utility> #include "../strings/xstring.hpp" -#include "../io/cxxstdio.hpp" - -#include "magic-interpreter.hpp" +#include "../generic/dumb_ptr.hpp" -#include "pc.hpp" +#include "../io/cxxstdio.hpp" #include "magic-expr.hpp" +#include "magic-interpreter.hpp" #include "magic-interpreter-base.hpp" #include "magic-stmt.hpp" -#include "magic.hpp" +#include "map.hpp" +#include "pc.hpp" #include "../poison.hpp" + +namespace tmwa +{ #undef DEBUG /// Return a pair of strings, {spellname, parameter} @@ -95,15 +100,15 @@ int magic_message(dumb_ptr<map_session_data> caster, XString source_invocation) if (bool(spell->flags & SPELL_FLAG::NONMAGIC) || (power >= 1)) effects = spell_trigger(spell, caster, env, &near_miss); else - effects = NULL; + effects = nullptr; #ifdef DEBUG - FPRINTF(stderr, "Found spell `%s', triggered = %d\n", spell_, - effects != NULL); + FPRINTF(stderr, "Found spell `%s', triggered = %d\n"_fmt, spell_, + effects != nullptr); #endif - MAP_LOG_PC(caster, "CAST %s %s", - spell->name, effects ? "SUCCESS" : "FAILURE"); + MAP_LOG_PC(caster, "CAST %s %s"_fmt, + spell->name, effects ? "SUCCESS"_s : "FAILURE"_s); if (effects) { @@ -122,3 +127,4 @@ int magic_message(dumb_ptr<map_session_data> caster, XString source_invocation) return 0; /* Not a spell */ } +} // namespace tmwa diff --git a/src/map/magic.hpp b/src/map/magic.hpp index a5a966c..e06e913 100644 --- a/src/map/magic.hpp +++ b/src/map/magic.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_MAGIC_HPP -#define TMWA_MAP_MAGIC_HPP +#pragma once // magic.hpp - Entry to the magic system. // // Copyright © 2004-2011 The Mana World Development Team @@ -20,17 +19,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "../mmo/dumb_ptr.hpp" +#include "../generic/fwd.hpp" -# include "map.hpp" -# include "skill.t.hpp" +#include "map.t.hpp" +#include "skill.t.hpp" -struct invocation; /* Spell invocation */ +namespace tmwa +{ /** * Try to cast magic. * @@ -43,62 +43,4 @@ struct invocation; /* Spell invocation */ * message should not be repeated. */ int magic_message(dumb_ptr<map_session_data> caster, XString source_invocation); - -/** - * Removes the shroud from a character - * - * \param character The character to remove the shroud from - */ -void magic_unshroud(dumb_ptr<map_session_data> character); - -/** - * Notifies a running spell that a status_change timer triggered by the spell has expired - * - * \param invocation The invocation to notify - * \param bl_id ID of the PC for whom this happened - * \param sc_id ID of the status change entry that finished - * \param supplanted Whether the status_change finished normally (0) or was supplanted by a new status_change (1) - */ -void spell_effect_report_termination(int invocation, int bl_id, - StatusChange sc_id, int supplanted); - -/** - * Identifies the invocation used to trigger a spell - * - * Returns empty string if not found - */ -AString magic_find_invocation(XString spellname); - -/** - * Identifies the invocation used to denote a teleport location - * - * Returns empty string if not found - */ -AString magic_find_anchor_invocation(XString teleport_location); - -/** - * Execute a spell invocation and sets up timers to finish - */ -void spell_execute(dumb_ptr<invocation> invocation); - -/** - * Continue an NPC script embedded in a spell - */ -void spell_execute_script(dumb_ptr<invocation> invocation); - -/** - * Stops all magic bound to the specified character - * - */ -void magic_stop_completely(dumb_ptr<map_session_data> c); - -/** - * Attacks with a magical spell charged to the character - * - * Returns 0 if there is no charged spell or the spell is depleted. - */ -int spell_attack(int caster, int target); - -void spell_free_invocation(dumb_ptr<invocation> invocation); - -#endif // TMWA_MAP_MAGIC_HPP +} // namespace tmwa diff --git a/src/map/main.cpp b/src/map/main.cpp index 2db1408..8e8e9d5 100644 --- a/src/map/main.cpp +++ b/src/map/main.cpp @@ -1,4 +1,3 @@ -#include "map.hpp" // map/main.cpp - dummy file to make Make dependencies work // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -18,4 +17,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include "map.hpp" + #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/map/map.cpp b/src/map/map.cpp index b49b225..033f299 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -29,15 +29,17 @@ #include <cassert> #include <cstdlib> -#include <cstring> #include "../compat/nullpo.hpp" #include "../compat/fun.hpp" +#include "../ints/udl.hpp" + #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" #include "../strings/vstring.hpp" +#include "../strings/literal.hpp" #include "../generic/db.hpp" #include "../generic/random2.hpp" @@ -47,11 +49,13 @@ #include "../io/tty.hpp" #include "../io/write.hpp" +#include "../net/socket.hpp" +#include "../net/timer.hpp" + #include "../mmo/config_parse.hpp" #include "../mmo/core.hpp" #include "../mmo/extract.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" +#include "../mmo/utils.hpp" #include "../mmo/version.hpp" #include "atcommand.hpp" @@ -60,8 +64,8 @@ #include "clif.hpp" #include "grfio.hpp" #include "itemdb.hpp" -#include "magic.hpp" -#include "magic-interpreter.hpp" +#include "magic-interpreter.hpp" // for is_spell inline body +#include "magic-stmt.hpp" #include "magic-v2.hpp" #include "mob.hpp" #include "npc.hpp" @@ -74,7 +78,10 @@ #include "../poison.hpp" -DMap<int, dumb_ptr<block_list>> id_db; + +namespace tmwa +{ +DMap<BlockId, dumb_ptr<block_list>> id_db; UPMap<MapName, map_abstract> maps_db; @@ -88,21 +95,21 @@ struct charid2nick }; static -Map<int, struct charid2nick> charid_db; +Map<CharId, struct charid2nick> charid_db; static int users = 0; static -Array<dumb_ptr<block_list>, MAX_FLOORITEM> object; +Array<dumb_ptr<block_list>, unwrap<BlockId>(MAX_FLOORITEM)> object; static -int first_free_object_id = 0, last_object_id = 0; +BlockId first_free_object_id = BlockId(); interval_t autosave_time = DEFAULT_AUTOSAVE_INTERVAL; int save_settings = 0xFFFF; -AString motd_txt = "conf/motd.txt"; +AString motd_txt = "conf/motd.txt"_s; -CharName wisp_server_name = stringish<CharName>("Server"); // can be modified in char-server configuration file +CharName wisp_server_name = stringish<CharName>("Server"_s); // can be modified in char-server configuration file static void map_delmap(MapName mapname); @@ -112,6 +119,10 @@ void SessionDeleter::operator()(SessionData *sd) really_delete1 static_cast<map_session_data *>(sd); } +VString<49> convert_for_printf(NpcEvent ev) +{ + return STRNPRINTF(50, "%s::%s"_fmt, ev.npc, ev.label); +} bool extract(XString str, NpcEvent *ev) { XString mid; @@ -181,12 +192,12 @@ struct block_list bl_head; */ int map_addblock(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_prev) { if (battle_config.error_log) - PRINTF("map_addblock error : bl->bl_prev!=NULL\n"); + PRINTF("map_addblock error : bl->bl_prev!=nullptr\n"_fmt); return 0; } @@ -226,7 +237,7 @@ int map_addblock(dumb_ptr<block_list> bl) */ int map_delblock(dumb_ptr<block_list> bl) { - nullpo_ret(bl); + nullpo_retz(bl); // 既にblocklistから抜けている if (!bl->bl_prev) @@ -235,7 +246,7 @@ int map_delblock(dumb_ptr<block_list> bl) { // prevがNULLでnextがNULLでないのは有ってはならない if (battle_config.error_log) - PRINTF("map_delblock error : bl->bl_next!=NULL\n"); + PRINTF("map_delblock error : bl->bl_next!=nullptr\n"_fmt); } return 0; } @@ -261,8 +272,8 @@ int map_delblock(dumb_ptr<block_list> bl) { bl->bl_prev->bl_next = bl->bl_next; } - bl->bl_next = NULL; - bl->bl_prev = NULL; + bl->bl_next = nullptr; + bl->bl_prev = nullptr; return 0; } @@ -274,7 +285,7 @@ int map_delblock(dumb_ptr<block_list> bl) int map_count_oncell(map_local *m, int x, int y) { int bx, by; - dumb_ptr<block_list> bl = NULL; + dumb_ptr<block_list> bl = nullptr; int count = 0; if (x < 0 || y < 0 || (x >= m->xs) || (y >= m->ys)) @@ -533,29 +544,27 @@ void map_foreachincell(std::function<void(dumb_ptr<block_list>)> func, * bl->bl_idもこの中で設定して問題無い? *------------------------------------------ */ -int map_addobject(dumb_ptr<block_list> bl) +BlockId map_addobject(dumb_ptr<block_list> bl) { - int i; + BlockId i; if (!bl) { - PRINTF("map_addobject nullpo?\n"); - return 0; + PRINTF("map_addobject nullpo?\n"_fmt); + return BlockId(); } - if (first_free_object_id < 2 || first_free_object_id >= MAX_FLOORITEM) - first_free_object_id = 2; - for (i = first_free_object_id; i < MAX_FLOORITEM; i++) - if (!object[i]) + if (first_free_object_id < wrap<BlockId>(2) || first_free_object_id == MAX_FLOORITEM) + first_free_object_id = wrap<BlockId>(2); + for (i = first_free_object_id; i < MAX_FLOORITEM; i = next(i)) + if (!object[i._value]) break; - if (i >= MAX_FLOORITEM) + if (i == MAX_FLOORITEM) { if (battle_config.error_log) - PRINTF("no free object id\n"); - return 0; + PRINTF("no free object id\n"_fmt); + return BlockId(); } first_free_object_id = i; - if (last_object_id < i) - last_object_id = i; - object[i] = bl; + object[i._value] = bl; id_db.put(i, bl); return i; } @@ -565,32 +574,26 @@ int map_addobject(dumb_ptr<block_list> bl) * map_delobjectのfreeしないバージョン *------------------------------------------ */ -int map_delobjectnofree(int id, BL type) +void map_delobjectnofree(BlockId id, BL type) { assert (id < MAX_FLOORITEM); - if (!object[id]) - return 0; + if (!object[id._value]) + return; - if (object[id]->bl_type != type) + if (object[id._value]->bl_type != type) { - FPRINTF(stderr, "Incorrect type: expected %d, got %d\n", + FPRINTF(stderr, "Incorrect type: expected %d, got %d\n"_fmt, type, - object[id]->bl_type); + object[id._value]->bl_type); abort(); } - map_delblock(object[id]); + map_delblock(object[id._value]); id_db.put(id, dumb_ptr<block_list>()); -// map_freeblock(object[id]); - object[id] = nullptr; + object[id._value] = nullptr; - if (first_free_object_id > id) + if (id < first_free_object_id) first_free_object_id = id; - - while (last_object_id > 2 && object[last_object_id] == NULL) - last_object_id--; - - return 0; } /*========================================== @@ -601,21 +604,19 @@ int map_delobjectnofree(int id, BL type) * addとの対称性が無いのが気になる *------------------------------------------ */ -int map_delobject(int id, BL type) +void map_delobject(BlockId id, BL type) { assert (id < MAX_FLOORITEM); - dumb_ptr<block_list> obj = object[id]; + dumb_ptr<block_list> obj = object[id._value]; - if (obj == NULL) - return 0; + if (obj == nullptr) + return; map_delobjectnofree(id, type); if (obj->bl_type == BL::PC) // [Fate] Not sure where else to put this... I'm not sure where delobject for PCs is called from pc_cleanup(obj->is_player()); MapBlockLock::freeblock(obj); - - return 0; } /*========================================== @@ -626,24 +627,28 @@ int map_delobject(int id, BL type) void map_foreachobject(std::function<void(dumb_ptr<block_list>)> func, BL type) { - assert (last_object_id < MAX_FLOORITEM); std::vector<dumb_ptr<block_list>> bl_list; - for (int i = 2; i <= last_object_id; i++) + for (BlockId i = wrap<BlockId>(2); i < MAX_FLOORITEM; i = next(i)) { - if (!object[i]) + if (!object[i._value]) continue; { - if (type != BL::NUL && object[i]->bl_type != type) + if (type != BL::NUL && object[i._value]->bl_type != type) continue; - bl_list.push_back(object[i]); + bl_list.push_back(object[i._value]); } } MapBlockLock lock; for (dumb_ptr<block_list> bl : bl_list) + { + // TODO figure out if the second branch can happen + // bl_prev is non-null for all that are on a map (see bl_head) + // bl_next is only meaningful for objects that are on a map if (bl->bl_prev || bl->bl_next) func(bl); + } } /*========================================== @@ -656,15 +661,15 @@ void map_foreachobject(std::function<void(dumb_ptr<block_list>)> func, * map.h内で#defineしてある *------------------------------------------ */ -void map_clearflooritem_timer(TimerData *tid, tick_t, int id) +void map_clearflooritem_timer(TimerData *tid, tick_t, BlockId id) { assert (id < MAX_FLOORITEM); - dumb_ptr<block_list> obj = object[id]; + dumb_ptr<block_list> obj = object[id._value]; assert (obj && obj->bl_type == BL::ITEM); dumb_ptr<flooritem_data> fitem = obj->is_item(); if (!tid) fitem->cleartimer.cancel(); - clif_clearflooritem(fitem, 0); + clif_clearflooritem(fitem, nullptr); map_delobject(fitem->bl_id, BL::ITEM); } @@ -678,7 +683,7 @@ std::pair<uint16_t, uint16_t> map_randfreecell(map_local *m, if (!bool(read_gatp(m, x + dx, y + dy) & MapCell::UNWALKABLE)) return {static_cast<uint16_t>(x + dx), static_cast<uint16_t>(y + dy)}; } - return {static_cast<uint16_t>(0), static_cast<uint16_t>(0)}; + return {0_u16, 0_u16}; } /// Return a randomly selected passable cell within a given range. @@ -695,36 +700,36 @@ std::pair<uint16_t, uint16_t> map_searchrandfreecell(map_local *m, int x, int y, * item_dataはamount以外をcopyする *------------------------------------------ */ -int map_addflooritem_any(struct item *item_data, int amount, +BlockId map_addflooritem_any(Item *item_data, int amount, map_local *m, int x, int y, dumb_ptr<map_session_data> *owners, interval_t *owner_protection, interval_t lifetime, int dispersal) { - dumb_ptr<flooritem_data> fitem = NULL; + dumb_ptr<flooritem_data> fitem = nullptr; - nullpo_ret(item_data); + nullpo_retr(BlockId(), item_data); auto xy = map_searchrandfreecell(m, x, y, dispersal); if (xy.first == 0 && xy.second == 0) - return 0; + return BlockId(); fitem.new_(); fitem->bl_type = BL::ITEM; - fitem->bl_prev = fitem->bl_next = NULL; + fitem->bl_prev = fitem->bl_next = nullptr; fitem->bl_m = m; fitem->bl_x = xy.first; fitem->bl_y = xy.second; - fitem->first_get_id = 0; + fitem->first_get_id = BlockId(); fitem->first_get_tick = tick_t(); - fitem->second_get_id = 0; + fitem->second_get_id = BlockId(); fitem->second_get_tick = tick_t(); - fitem->third_get_id = 0; + fitem->third_get_id = BlockId(); fitem->third_get_tick = tick_t(); fitem->bl_id = map_addobject(fitem); - if (fitem->bl_id == 0) + if (!fitem->bl_id) { fitem.delete_(); - return 0; + return BlockId(); } tick_t tick = gettick(); @@ -760,7 +765,7 @@ int map_addflooritem_any(struct item *item_data, int amount, return fitem->bl_id; } -int map_addflooritem(struct item *item_data, int amount, +BlockId map_addflooritem(Item *item_data, int amount, map_local *m, int x, int y, dumb_ptr<map_session_data> first_sd, dumb_ptr<map_session_data> second_sd, @@ -784,10 +789,10 @@ int map_addflooritem(struct item *item_data, int amount, * charid_dbへ追加(返信待ちがあれば返信) *------------------------------------------ */ -void map_addchariddb(int charid, CharName name) +void map_addchariddb(CharId charid, CharName name) { struct charid2nick *p = charid_db.search(charid); - if (p == NULL) + if (p == nullptr) p = charid_db.init(charid); p->nick = name; @@ -840,7 +845,7 @@ void map_quit(dumb_ptr<map_session_data> sd) if (sd->trade_partner) // 取引を中断する trade_tradecancel(sd); - if (sd->party_invite > 0) // パーティ勧誘を拒否する + if (sd->party_invite) // パーティ勧誘を拒否する party_reply_invite(sd, sd->party_invite_account, 0); party_send_logout(sd); // パーティのログアウトメッセージ送信 @@ -883,7 +888,7 @@ void map_quit(dumb_ptr<map_session_data> sd) * id番号のPCを探す。居なければNULL *------------------------------------------ */ -dumb_ptr<map_session_data> map_id2sd(int id) +dumb_ptr<map_session_data> map_id2sd(BlockId id) { // This is bogus. // However, there might be differences for de-auth'ed accounts. @@ -899,7 +904,7 @@ dumb_ptr<map_session_data> map_id2sd(int id) bl=numdb_search(id_db,id); if (bl && bl->bl_type==BL::PC) return (struct map_session_data*)bl; - return NULL; + return nullptr; */ for (io::FD i : iter_fds()) { @@ -914,18 +919,18 @@ dumb_ptr<map_session_data> map_id2sd(int id) } } - return NULL; + return nullptr; } /*========================================== * char_id番号の名前を探す *------------------------------------------ */ -CharName map_charid2nick(int id) +CharName map_charid2nick(CharId id) { struct charid2nick *p = charid_db.search(id); - if (p == NULL) + if (p == nullptr) return CharName(); if (p->req_id != 0) return CharName(); @@ -947,7 +952,7 @@ dumb_ptr<map_session_data> map_get_session(io::FD i) return dumb_ptr<map_session_data>(d); } - return NULL; + return nullptr; } static @@ -960,7 +965,7 @@ dumb_ptr<map_session_data> map_get_session_forward(int start) return d; } - return NULL; + return nullptr; } static @@ -973,7 +978,7 @@ dumb_ptr<map_session_data> map_get_session_backward(int start) return d; } - return NULL; + return nullptr; } dumb_ptr<map_session_data> map_get_first_session(void) @@ -999,7 +1004,7 @@ dumb_ptr<map_session_data> map_get_prev_session(dumb_ptr<map_session_data> d) /*========================================== * Search session data from a nick name * (without sensitive case if necessary) - * return map_session_data pointer or NULL + * return map_session_data pointer or nullptr *------------------------------------------ */ dumb_ptr<map_session_data> map_nick2sd(CharName nick) @@ -1018,7 +1023,7 @@ dumb_ptr<map_session_data> map_nick2sd(CharName nick) } } } - return NULL; + return nullptr; } /*========================================== @@ -1026,11 +1031,11 @@ dumb_ptr<map_session_data> map_nick2sd(CharName nick) * 一時objectの場合は配列を引くのみ *------------------------------------------ */ -dumb_ptr<block_list> map_id2bl(int id) +dumb_ptr<block_list> map_id2bl(BlockId id) { - dumb_ptr<block_list> bl = NULL; - if (id < sizeof(object) / sizeof(object[0])) - bl = object[id]; + dumb_ptr<block_list> bl = nullptr; + if (id < MAX_FLOORITEM) + bl = object[id._value]; else bl = id_db.get(id); @@ -1047,12 +1052,12 @@ int map_addnpc(map_local *m, dumb_ptr<npc_data> nd) if (!m) return -1; for (i = 0; i < m->npc_num && i < MAX_NPC_PER_MAP; i++) - if (m->npc[i] == NULL) + if (m->npc[i] == nullptr) break; if (i == MAX_NPC_PER_MAP) { if (battle_config.error_log) - PRINTF("too many NPCs in one map %s\n", m->name_); + PRINTF("too many NPCs in one map %s\n"_fmt, m->name_); return -1; } if (i == m->npc_num) @@ -1060,7 +1065,7 @@ int map_addnpc(map_local *m, dumb_ptr<npc_data> nd) m->npc_num++; } - nullpo_ret(nd); + nullpo_retz(nd); m->npc[i] = nd; nd->n = i; @@ -1081,7 +1086,7 @@ void map_removenpc(void) map_local *m = static_cast<map_local *>(mitp.second.get()); for (int i = 0; i < m->npc_num && i < MAX_NPC_PER_MAP; i++) { - if (m->npc[i] != NULL) + if (m->npc[i] != nullptr) { clif_clearchar(m->npc[i], BeingRemoveWhy::QUIT); map_delblock(m->npc[i]); @@ -1096,7 +1101,7 @@ void map_removenpc(void) } } } - PRINTF("%d NPCs removed.\n", n); + PRINTF("%d NPCs removed.\n"_fmt, n); } /*========================================== @@ -1106,7 +1111,7 @@ void map_removenpc(void) map_local *map_mapname2mapid(MapName name) { map_abstract *md = maps_db.get(name); - if (md == NULL || md->gat == NULL) + if (md == nullptr || md->gat == nullptr) return nullptr; return static_cast<map_local *>(md); } @@ -1118,7 +1123,7 @@ map_local *map_mapname2mapid(MapName name) int map_mapname2ipport(MapName name, IP4Address *ip, int *port) { map_abstract *md = maps_db.get(name); - if (md == NULL || md->gat) + if (md == nullptr || md->gat) return -1; map_remote *mdos = static_cast<map_remote *>(md); *ip = mdos->ip; @@ -1227,12 +1232,12 @@ void map_setcell(map_local *m, int x, int y, MapCell t) int map_setipport(MapName name, IP4Address ip, int port) { map_abstract *md = maps_db.get(name); - if (md == NULL) + if (md == nullptr) { // not exist -> add new data auto mdos = make_unique<map_remote>(); mdos->name_ = name; - mdos->gat = NULL; + mdos->gat = nullptr; mdos->ip = ip; mdos->port = port; maps_db.put(mdos->name_, std::move(mdos)); @@ -1244,7 +1249,7 @@ int map_setipport(MapName name, IP4Address ip, int port) // local -> check data if (ip != clif_getip() || port != clif_getport()) { - PRINTF("from char server : %s -> %s:%d\n", + PRINTF("from char server : %s -> %s:%d\n"_fmt, name, ip, port); return 1; } @@ -1275,7 +1280,7 @@ bool map_readmap(map_local *m, size_t num, MapName fn) int xs = m->xs = gat_v[0] | gat_v[1] << 8; int ys = m->ys = gat_v[2] | gat_v[3] << 8; - PRINTF("\rLoading Maps [%zu/%zu]: %-30s (%i, %i)", + PRINTF("\rLoading Maps [%zu/%zu]: %-30s (%i, %i)"_fmt, num, maps_db.size(), fn, xs, ys); fflush(stdout); @@ -1328,10 +1333,10 @@ bool map_readallmap(void) } } - PRINTF("\rMaps Loaded: %-65zu\n", maps_db.size()); + PRINTF("\rMaps Loaded: %-65zu\n"_fmt, maps_db.size()); if (maps_removed) { - PRINTF("Cowardly refusing to keep going after removing %d maps.\n", + PRINTF("Cowardly refusing to keep going after removing %d maps.\n"_fmt, maps_removed); return false; } @@ -1346,7 +1351,7 @@ bool map_readallmap(void) static void map_addmap(MapName mapname) { - if (mapname == "clear") + if (mapname == "clear"_s) { maps_db.clear(); return; @@ -1366,7 +1371,7 @@ void map_addmap(MapName mapname) */ void map_delmap(MapName mapname) { - if (mapname == "all") + if (mapname == "all"_s) { maps_db.clear(); return; @@ -1389,13 +1394,13 @@ void map_close_logfile(void) { if (map_logfile) { - AString filename = STRPRINTF("%s.%ld", map_logfile_name, map_logfile_index); + AString filename = STRPRINTF("%s.%ld"_fmt, map_logfile_name, map_logfile_index); const char *args[] = { "gzip", "-f", filename.c_str(), - NULL + nullptr }; char **argv = const_cast<char **>(args); @@ -1406,7 +1411,7 @@ void map_close_logfile(void) execvp("gzip", argv); _exit(1); } - wait(NULL); + wait(nullptr); } } @@ -1416,7 +1421,7 @@ void map_start_logfile(long index) map_logfile_index = index; AString filename_buf = STRPRINTF( - "%s.%ld", + "%s.%ld"_fmt, map_logfile_name, map_logfile_index); map_logfile = make_unique<io::AppendFile>(filename_buf); @@ -1433,11 +1438,11 @@ void map_set_logfile(AString filename) struct timeval tv; map_logfile_name = std::move(filename); - gettimeofday(&tv, NULL); + gettimeofday(&tv, nullptr); map_start_logfile(tv.tv_sec >> LOGFILE_SECONDS_PER_CHUNK_SHIFT); - MAP_LOG("log-start v5"); + MAP_LOG("log-start v5"_fmt); } void map_log(XString line) @@ -1464,12 +1469,12 @@ void map_log(XString line) static bool map_config_read(ZString cfgName) { - struct hostent *h = NULL; + struct hostent *h = nullptr; io::ReadFile in(cfgName); if (!in.is_open()) { - PRINTF("Map configuration file not found at: %s\n", cfgName); + PRINTF("Map configuration file not found at: %s\n"_fmt, cfgName); return false; } @@ -1483,25 +1488,25 @@ bool map_config_read(ZString cfgName) ZString w2; if (!config_split(line, &w1, &w2)) { - PRINTF("Bad config line: %s\n", line); + PRINTF("Bad config line: %s\n"_fmt, line); rv = false; continue; } - if (w1 == "userid") + if (w1 == "userid"_s) { AccountName name = stringish<AccountName>(w2); chrif_setuserid(name); } - else if (w1 == "passwd") + else if (w1 == "passwd"_s) { AccountPass pass = stringish<AccountPass>(w2); chrif_setpasswd(pass); } - else if (w1 == "char_ip") + else if (w1 == "char_ip"_s) { h = gethostbyname(w2.c_str()); IP4Address w2ip; - if (h != NULL) + if (h != nullptr) { w2ip = IP4Address({ static_cast<uint8_t>(h->h_addr[0]), @@ -1509,25 +1514,25 @@ bool map_config_read(ZString cfgName) static_cast<uint8_t>(h->h_addr[2]), static_cast<uint8_t>(h->h_addr[3]), }); - PRINTF("Character server IP address : %s -> %s\n", + PRINTF("Character server IP address : %s -> %s\n"_fmt, w2, w2ip); } else { - PRINTF("Bad IP value: %s\n", line); + PRINTF("Bad IP value: %s\n"_fmt, line); return false; } chrif_setip(w2ip); } - else if (w1 == "char_port") + else if (w1 == "char_port"_s) { chrif_setport(atoi(w2.c_str())); } - else if (w1 == "map_ip") + else if (w1 == "map_ip"_s) { h = gethostbyname(w2.c_str()); IP4Address w2ip; - if (h != NULL) + if (h != nullptr) { w2ip = IP4Address({ static_cast<uint8_t>(h->h_addr[0]), @@ -1535,61 +1540,61 @@ bool map_config_read(ZString cfgName) static_cast<uint8_t>(h->h_addr[2]), static_cast<uint8_t>(h->h_addr[3]), }); - PRINTF("Map server IP address : %s -> %s\n", + PRINTF("Map server IP address : %s -> %s\n"_fmt, w2, w2ip); } else { - PRINTF("Bad IP value: %s\n", line); + PRINTF("Bad IP value: %s\n"_fmt, line); return false; } clif_setip(w2ip); } - else if (w1 == "map_port") + else if (w1 == "map_port"_s) { clif_setport(atoi(w2.c_str())); } - else if (w1 == "map") + else if (w1 == "map"_s) { MapName name = VString<15>(w2); map_addmap(name); } - else if (w1 == "delmap") + else if (w1 == "delmap"_s) { MapName name = VString<15>(w2); map_delmap(name); } - else if (w1 == "npc") + else if (w1 == "npc"_s) { npc_addsrcfile(w2); } - else if (w1 == "delnpc") + else if (w1 == "delnpc"_s) { npc_delsrcfile(w2); } - else if (w1 == "autosave_time") + else if (w1 == "autosave_time"_s) { autosave_time = std::chrono::seconds(atoi(w2.c_str())); if (autosave_time <= interval_t::zero()) autosave_time = DEFAULT_AUTOSAVE_INTERVAL; } - else if (w1 == "motd_txt") + else if (w1 == "motd_txt"_s) { motd_txt = w2; } - else if (w1 == "mapreg_txt") + else if (w1 == "mapreg_txt"_s) { mapreg_txt = w2; } - else if (w1 == "gm_log") + else if (w1 == "gm_log"_s) { gm_log = std::move(w2); } - else if (w1 == "log_file") + else if (w1 == "log_file"_s) { map_set_logfile(w2); } - else if (w1 == "import") + else if (w1 == "import"_s) { rv &= map_config_read(w2); } @@ -1656,7 +1661,7 @@ void term_func(void) map_close_logfile(); } -int compare_item(struct item *a, struct item *b) +int compare_item(Item *a, Item *b) { return (a->nameid == b->nameid); } @@ -1664,29 +1669,29 @@ int compare_item(struct item *a, struct item *b) static bool map_confs(XString key, ZString value) { - if (key == "map_conf") + if (key == "map_conf"_s) return map_config_read(value); - if (key == "battle_conf") + if (key == "battle_conf"_s) return battle_config_read(value); - if (key == "atcommand_conf") + if (key == "atcommand_conf"_s) return atcommand_config_read(value); - if (key == "item_db") + if (key == "item_db"_s) return itemdb_readdb(value); - if (key == "mob_db") + if (key == "mob_db"_s) return mob_readdb(value); - if (key == "mob_skill_db") + if (key == "mob_skill_db"_s) return mob_readskilldb(value); - if (key == "skill_db") + if (key == "skill_db"_s) return skill_readdb(value); - if (key == "magic_conf") + if (key == "magic_conf"_s) return load_magic_file_v2(value); - if (key == "resnametable") + if (key == "resnametable"_s) return load_resnametable(value); - if (key == "const_db") + if (key == "const_db"_s) return read_constdb(value); - PRINTF("unknown map conf key: %s\n", AString(key)); + PRINTF("unknown map conf key: %s\n"_fmt, AString(key)); return false; } @@ -1705,22 +1710,22 @@ int do_init(Slice<ZString> argv) ZString argvi = argv.pop_front(); if (argvi.startswith('-')) { - if (argvi == "--help") + if (argvi == "--help"_s) { - PRINTF("Usage: %s [--help] [--version] [--write_atcommand_config outfile] [files...]\n", + PRINTF("Usage: %s [--help] [--version] [--write_atcommand_config outfile] [files...]\n"_fmt, argv0); exit(0); } - else if (argvi == "--version") + else if (argvi == "--version"_s) { - PRINTF("%s\n", CURRENT_VERSION_STRING); + PRINTF("%s\n"_fmt, CURRENT_VERSION_STRING); exit(0); } - else if (argvi == "--write-atcommand-config") + else if (argvi == "--write-atcommand-config"_s) { if (!argv) { - PRINTF("Missing argument\n"); + PRINTF("Missing argument\n"_fmt); exit(1); } ZString filename = argv.pop_front(); @@ -1729,7 +1734,7 @@ int do_init(Slice<ZString> argv) } else { - FPRINTF(stderr, "Unknown argument: %s\n", argvi); + FPRINTF(stderr, "Unknown argument: %s\n"_fmt, argvi); runflag = false; } } @@ -1741,7 +1746,7 @@ int do_init(Slice<ZString> argv) } if (!loaded_config_yet) - runflag &= load_config_file("conf/tmwa-map.conf", map_confs); + runflag &= load_config_file("conf/tmwa-map.conf"_s, map_confs); battle_config_check(); runflag &= map_readallmap(); @@ -1758,15 +1763,15 @@ int do_init(Slice<ZString> argv) npc_event_do_oninit(); // npcのOnInitイベント実行 if (battle_config.pk_mode == 1) - PRINTF("The server is running in " SGR_BOLD SGR_RED "PK Mode" SGR_RESET "\n"); + PRINTF("The server is running in " SGR_BOLD SGR_RED "PK Mode" SGR_RESET "\n"_fmt); - PRINTF("The map-server is " SGR_BOLD SGR_GREEN "ready" SGR_RESET " (Server is listening on the port %d).\n\n", + PRINTF("The map-server is " SGR_BOLD SGR_GREEN "ready" SGR_RESET " (Server is listening on the port %d).\n\n"_fmt, clif_getport()); return 0; } -int map_scriptcont(dumb_ptr<map_session_data> sd, int id) +int map_scriptcont(dumb_ptr<map_session_data> sd, BlockId id) { dumb_ptr<block_list> bl = map_id2bl(id); @@ -1784,3 +1789,4 @@ int map_scriptcont(dumb_ptr<map_session_data> sd, int id) return 0; } +} // namespace tmwa diff --git a/src/map/map.hpp b/src/map/map.hpp index 0cec5e8..0e4815c 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_MAP_HPP -#define TMWA_MAP_MAP_HPP +#pragma once // map.hpp - Core of the map server. // // Copyright © ????-2004 Athena Dev Teams @@ -21,48 +20,53 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "map.t.hpp" +#include "map.t.hpp" -# include <netinet/in.h> +#include <chrono> +#include <functional> +#include <list> -# include <functional> -# include <list> +#include "../ints/udl.hpp" -# include "../strings/fwd.hpp" -# include "../strings/rstring.hpp" -# include "../strings/astring.hpp" -# include "../strings/vstring.hpp" +#include "../strings/fwd.hpp" +#include "../strings/rstring.hpp" +#include "../strings/astring.hpp" +#include "../strings/vstring.hpp" -# include "../generic/db.hpp" -# include "../generic/matrix.hpp" +#include "../generic/db.hpp" +#include "../generic/dumb_ptr.hpp" +#include "../generic/matrix.hpp" -# include "../io/cxxstdio.hpp" +#include "../net/socket.hpp" +#include "../net/timer.t.hpp" -# include "../mmo/socket.hpp" -# include "../mmo/timer.t.hpp" +#include "../mmo/utils.hpp" -# include "battle.t.hpp" -# include "magic-interpreter.t.hpp" -# include "mapflag.hpp" -# include "mob.t.hpp" -# include "script.hpp" // change to script.t.hpp -# include "skill.t.hpp" +#include "battle.t.hpp" +#include "clif.t.hpp" +#include "mapflag.hpp" +#include "mob.t.hpp" +#include "script.hpp" // change to script.t.hpp +#include "skill.t.hpp" + +namespace tmwa +{ constexpr int MAX_NPC_PER_MAP = 512; constexpr int BLOCK_SIZE = 8; -# define AREA_SIZE battle_config.area_size -constexpr std::chrono::seconds LIFETIME_FLOORITEM = std::chrono::minutes(1); +#define AREA_SIZE battle_config.area_size +constexpr std::chrono::seconds LIFETIME_FLOORITEM = 1_min; constexpr int MAX_SKILL_LEVEL = 100; constexpr int MAX_EVENTTIMER = 32; -constexpr interval_t NATURAL_HEAL_INTERVAL = std::chrono::milliseconds(500); -constexpr int MAX_FLOORITEM = 500000; +constexpr interval_t NATURAL_HEAL_INTERVAL = 500_ms; +constexpr BlockId MAX_FLOORITEM = wrap<BlockId>(500000_u32); constexpr int MAX_LEVEL = 255; constexpr int MAX_WALKPATH = 48; constexpr int MAX_DROP_PER_MAP = 48; -constexpr interval_t DEFAULT_AUTOSAVE_INTERVAL = std::chrono::minutes(1); +constexpr interval_t DEFAULT_AUTOSAVE_INTERVAL = 1_min; // formerly VString<49>, as name::label struct NpcEvent @@ -89,24 +93,14 @@ struct NpcEvent return l.npc < r.npc || (l.npc == r.npc && l.label < r.label); } - friend VString<49> convert_for_printf(NpcEvent ev) - { - return STRNPRINTF(50, "%s::%s", ev.npc, ev.label); - } + friend VString<49> convert_for_printf(NpcEvent ev); }; bool extract(XString str, NpcEvent *ev); -struct map_session_data; -struct npc_data; -struct mob_data; -struct flooritem_data; -struct invocation; -struct map_local; - struct block_list { dumb_ptr<block_list> bl_next, bl_prev; - int bl_id; + BlockId bl_id; map_local *bl_m; short bl_x, bl_y; BL bl_type; @@ -141,14 +135,9 @@ struct status_change { Timer timer; int val1; - int spell_invocation; /* [Fate] If triggered by a spell, record here */ + BlockId spell_invocation; /* [Fate] If triggered by a spell, record here */ }; -struct invocation; - -struct npc_data; -struct item_data; - struct quick_regeneration { // [Fate] int amount; // Amount of HP/SP left to regenerate @@ -190,13 +179,14 @@ struct map_session_data : block_list, SessionData unsigned unbreakable_armor:1; unsigned deaf:1; } special_state; - int char_id, login_id1, login_id2; + CharId char_id_; + int login_id1, login_id2; SEX sex; unsigned char tmw_version; // tmw client version CharKey status_key; CharData status; - Array<struct item_data *, MAX_INVENTORY> inventory_data; - earray<short, EQUIP, EQUIP::COUNT> equip_index_maybe; + GenericArray<struct item_data *, InventoryIndexing<IOff0, MAX_INVENTORY>> inventory_data; + earray<IOff0, EQUIP, EQUIP::COUNT> equip_index_maybe; int weight, max_weight; MapName mapname_; Session *sess; // use this, you idiots! @@ -206,10 +196,9 @@ struct map_session_data : block_list, SessionData Opt2 opt2; Opt3 opt3; DIR dir, head_dir; - tick_t client_tick, server_tick; struct walkpath_data walkpath; Timer walktimer; - int npc_id, areanpc_id, npc_shopid; + BlockId npc_id, areanpc_id, npc_shopid; // this is important int npc_pos; int npc_menu; @@ -226,20 +215,20 @@ struct map_session_data : block_list, SessionData } npc_flags; Timer attacktimer; - int attacktarget; + BlockId attacktarget; ATK attacktarget_lv; tick_t attackabletime; // used by @hugo and @linus - int followtarget; + BlockId followtarget; tick_t cast_tick; // [Fate] Next tick at which spellcasting is allowed dumb_ptr<invocation> active_spells; // [Fate] Singly-linked list of active spells linked to this PC - int attack_spell_override; // [Fate] When an attack spell is active for this player, they trigger it + BlockId attack_spell_override; // [Fate] When an attack spell is active for this player, they trigger it // like a weapon. Check pc_attack_timer() for details. // Weapon equipment slot (slot 4) item override StatusChange attack_spell_icon_override; - short attack_spell_look_override; // Weapon `look' (attack animation) override + ItemNameId attack_spell_look_override; // Weapon `look' (attack animation) override short attack_spell_charges; // [Fate] Remaining number of charges for the attack spell interval_t attack_spell_delay; // [Fate] ms delay after spell attack short attack_spell_range; // [Fate] spell range @@ -296,16 +285,18 @@ struct map_session_data : block_list, SessionData earray<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; short sc_count; - int trade_partner; - Array<int, TRADE_MAX> deal_item_index; + AccountId trade_partner; + Array<IOff2, TRADE_MAX> deal_item_index; Array<int, TRADE_MAX> deal_item_amount; int deal_zeny; short deal_locked; - int party_sended, party_invite, party_invite_account; + int party_sended; + PartyId party_invite; + AccountId party_invite_account; int party_hp, party_x, party_y; - int partyspy; // [Syrus22] + PartyId partyspy; // [Syrus22] int catch_target_class; @@ -349,18 +340,15 @@ struct npc_label_list }; struct npc_item_list { - int nameid, value; + ItemNameId nameid; + int value; }; -class npc_data_script; -class npc_data_shop; -class npc_data_warp; -class npc_data_message; struct npc_data : block_list { NpcSubtype npc_subtype; short n; - short npc_class; + Species npc_class; DIR dir; interval_t speed; NpcName name; @@ -446,7 +434,7 @@ constexpr int MOB_XP_BONUS_SHIFT = 10; struct mob_data : block_list { short n; - short mob_class; + Species mob_class; DIR dir; MobMode mode; struct @@ -472,7 +460,7 @@ struct mob_data : block_list Timer timer; short to_x, to_y; int hp; - int target_id, attacked_id; + BlockId target_id, attacked_id; ATK target_lv; struct walkpath_data walkpath; tick_t next_walktime; @@ -482,12 +470,12 @@ struct mob_data : block_list short move_fail_count; struct DmgLogEntry { - int id; + BlockId id; int dmg; }; // logically a map ... std::vector<DmgLogEntry> dmglogv; - std::vector<struct item> lootitemv; + std::vector<Item> lootitemv; earray<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; short sc_count; @@ -499,14 +487,15 @@ struct mob_data : block_list Timer deletetimer; Timer skilltimer; - int skilltarget; + BlockId skilltarget; short skillx, skilly; SkillID skillid; short skilllv; struct mob_skill *skillidx; std::unique_ptr<tick_t[]> skilldelayup; // [MAX_MOBSKILL]; LevelElement def_ele; - int master_id, master_dist; + BlockId master_id; + int master_dist; int exclusion_src, exclusion_party; NpcEvent npc_event; // [Fate] mob-specific stats @@ -522,7 +511,7 @@ struct BlockLists struct map_abstract { MapName name_; - // gat is NULL for map_remote and non-NULL or map_local + // gat is nullptr for map_remote and non-nullptr or map_local std::unique_ptr<MapCell[]> gat; virtual ~map_abstract() {} @@ -537,8 +526,8 @@ struct map_local : map_abstract int npc_num; int users; MapFlags flag; - struct point save; - struct point resave; + Point save; + Point resave; Array<dumb_ptr<npc_data>, MAX_NPC_PER_MAP> npc; }; @@ -560,9 +549,9 @@ struct flooritem_data : block_list { short subx, suby; Timer cleartimer; - int first_get_id, second_get_id, third_get_id; + BlockId first_get_id, second_get_id, third_get_id; tick_t first_get_tick, second_get_tick, third_get_tick; - struct item item_data; + Item item_data; }; extern interval_t autosave_time; @@ -607,9 +596,9 @@ void map_foreachinmovearea(std::function<void(dumb_ptr<block_list>)>, //block関連に追加 int map_count_oncell(map_local *m, int x, int y); // 一時的object関連 -int map_addobject(dumb_ptr<block_list>); -int map_delobject(int, BL type); -int map_delobjectnofree(int id, BL type); +BlockId map_addobject(dumb_ptr<block_list>); +void map_delobject(BlockId, BL type); +void map_delobjectnofree(BlockId id, BL type); void map_foreachobject(std::function<void(dumb_ptr<block_list>)>, BL); // @@ -618,64 +607,64 @@ void map_quit(dumb_ptr<map_session_data>); int map_addnpc(map_local *, dumb_ptr<npc_data>); void map_log(XString line); -# define MAP_LOG(format, ...) \ +#define MAP_LOG(format, ...) \ map_log(STRPRINTF(format, ## __VA_ARGS__)) -# define MAP_LOG_PC(sd, fmt, ...) \ +#define MAP_LOG_PC(sd, fmt, ...) \ MAP_LOG("PC%d %s:%d,%d " fmt, \ - sd->status_key.char_id, (sd->bl_m ? sd->bl_m->name_ : stringish<MapName>("undefined.gat")), sd->bl_x, sd->bl_y, ## __VA_ARGS__) + sd->status_key.char_id, (sd->bl_m ? sd->bl_m->name_ : stringish<MapName>("undefined.gat"_s)), sd->bl_x, sd->bl_y, ## __VA_ARGS__) // 床アイテム関連 -void map_clearflooritem_timer(TimerData *, tick_t, int); +void map_clearflooritem_timer(TimerData *, tick_t, BlockId); inline -void map_clearflooritem(int id) +void map_clearflooritem(BlockId id) { map_clearflooritem_timer(nullptr, tick_t(), id); } -int map_addflooritem_any(struct item *, int amount, +BlockId map_addflooritem_any(Item *, int amount, map_local *m, int x, int y, dumb_ptr<map_session_data> *owners, interval_t *owner_protection, interval_t lifetime, int dispersal); -int map_addflooritem(struct item *, int, +BlockId map_addflooritem(Item *, int, map_local *, int, int, dumb_ptr<map_session_data>, dumb_ptr<map_session_data>, dumb_ptr<map_session_data>); // キャラid=>キャラ名 変換関連 extern -DMap<int, dumb_ptr<block_list>> id_db; -void map_addchariddb(int charid, CharName name); -CharName map_charid2nick(int); +DMap<BlockId, dumb_ptr<block_list>> id_db; +void map_addchariddb(CharId charid, CharName name); +CharName map_charid2nick(CharId); -dumb_ptr<map_session_data> map_id2sd(int); -dumb_ptr<block_list> map_id2bl(int); +dumb_ptr<map_session_data> map_id2sd(BlockId); +dumb_ptr<block_list> map_id2bl(BlockId); inline -dumb_ptr<map_session_data> map_id_is_player(int id) +dumb_ptr<map_session_data> map_id_is_player(BlockId id) { dumb_ptr<block_list> bl = map_id2bl(id); return bl ? bl->is_player() : nullptr; } inline -dumb_ptr<npc_data> map_id_is_npc(int id) +dumb_ptr<npc_data> map_id_is_npc(BlockId id) { dumb_ptr<block_list> bl = map_id2bl(id); return bl ? bl->is_npc() : nullptr; } inline -dumb_ptr<mob_data> map_id_is_mob(int id) +dumb_ptr<mob_data> map_id_is_mob(BlockId id) { dumb_ptr<block_list> bl = map_id2bl(id); return bl ? bl->is_mob() : nullptr; } inline -dumb_ptr<flooritem_data> map_id_is_item(int id) +dumb_ptr<flooritem_data> map_id_is_item(BlockId id) { dumb_ptr<block_list> bl = map_id2bl(id); return bl ? bl->is_item() : nullptr; } inline -dumb_ptr<invocation> map_id_is_spell(int id) +dumb_ptr<invocation> map_id_is_spell(BlockId id) { dumb_ptr<block_list> bl = map_id2bl(id); return bl ? bl->is_spell() : nullptr; @@ -688,9 +677,9 @@ int map_setipport(MapName name, IP4Address ip, int port); void map_addiddb(dumb_ptr<block_list>); void map_deliddb(dumb_ptr<block_list> bl); void map_addnickdb(dumb_ptr<map_session_data>); -int map_scriptcont(dumb_ptr<map_session_data> sd, int id); /* Continues a script either on a spell or on an NPC */ +int map_scriptcont(dumb_ptr<map_session_data> sd, BlockId id); /* Continues a script either on a spell or on an NPC */ dumb_ptr<map_session_data> map_nick2sd(CharName); -int compare_item(struct item *a, struct item *b); +int compare_item(Item *a, Item *b); dumb_ptr<map_session_data> map_get_first_session(void); dumb_ptr<map_session_data> map_get_last_session(void); @@ -733,5 +722,4 @@ inline dumb_ptr<npc_data_script> npc_data::is_script() { return npc_subtype == N inline dumb_ptr<npc_data_shop> npc_data::is_shop() { return npc_subtype == NpcSubtype::SHOP ? as_shop() : nullptr ; } inline dumb_ptr<npc_data_warp> npc_data::is_warp() { return npc_subtype == NpcSubtype::WARP ? as_warp() : nullptr ; } inline dumb_ptr<npc_data_message> npc_data::is_message() { return npc_subtype == NpcSubtype::MESSAGE ? as_message() : nullptr ; } - -#endif // TMWA_MAP_MAP_HPP +} // namespace tmwa diff --git a/src/map/map.t.hpp b/src/map/map.t.hpp index b73cbdd..b475f9b 100644 --- a/src/map/map.t.hpp +++ b/src/map/map.t.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_MAP_T_HPP -#define TMWA_MAP_MAP_T_HPP +#pragma once // map.t.hpp - Core of the map server. // // Copyright © ????-2004 Athena Dev Teams @@ -21,73 +20,20 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/vstring.hpp" +#include <cstdint> -# include "../mmo/mmo.hpp" +#include "../strings/vstring.hpp" -namespace e -{ -// [Fate] status.option properties. These are persistent status changes. -// IDs that are not listed are not used in the code (to the best of my knowledge) -enum class Option : uint16_t -{ - ZERO = 0x0000, +#include "../generic/enum.hpp" - // [Fate] This is the GM `@hide' flag - HIDE = 0x0040, - // [Fate] Complete invisibility to other clients - INVISIBILITY = 0x1000, +#include "../mmo/ids.hpp" +#include "../mmo/mmo.hpp" - // ? - REAL_ANY_HIDE = HIDE, -}; -enum class Opt1 : uint16_t -{ - ZERO = 0, - _stone1 = 1, - _freeze = 2, - _stan = 3, - _sleep = 4, - _stone6 = 6, -}; -enum class Opt2 : uint16_t -{ - ZERO = 0x0000, - _poison = 0x0001, - _curse = 0x0002, - _silence = 0x0004, - BLIND = 0x0010, - _speedpotion0 = 0x0020, - _signumcrucis = 0x0040, - _atkpot = 0x0080, - _heal = 0x0100, - _slowpoison = 0x0200, -}; -enum class Opt3 : uint16_t -{ - ZERO = 0x0000, - _concentration = 0x0001, - _overthrust = 0x0002, - _energycoat = 0x0004, - _explosionspirits = 0x0008, - _steelbody = 0x0010, - _berserk = 0x0080, - - _marionette = 0x0400, - _assumptio = 0x0800, -}; - -ENUM_BITWISE_OPERATORS(Option) -ENUM_BITWISE_OPERATORS(Opt2) -ENUM_BITWISE_OPERATORS(Opt3) -} -using e::Option; -using e::Opt1; -using e::Opt2; -using e::Opt3; +namespace tmwa +{ enum class BL : uint8_t { NUL, @@ -103,6 +49,8 @@ enum class NpcSubtype : uint8_t SHOP, SCRIPT, MESSAGE, + + COUNT, }; enum class mob_stat @@ -146,325 +94,6 @@ enum class ATK DEF, }; -enum class SP : uint16_t -{ - // sent to client - SPEED = 0, - - // when used as "no stat" - ZERO = 0, - - // sent to client - BASEEXP = 1, - // sent to client - JOBEXP = 2, -# if 0 - KARMA = 3, -# endif - - // sent to client - HP = 5, - // sent to client - MAXHP = 6, - // sent to client - SP = 7, - // sent to client - MAXSP = 8, - // sent to client - STATUSPOINT = 9, - - // sent to client - BASELEVEL = 11, - // sent to client - SKILLPOINT = 12, - // sent to client - STR = 13, - // sent to client - AGI = 14, - // sent to client - VIT = 15, - // sent to client - INT = 16, - // sent to client - DEX = 17, - // sent to client - LUK = 18, - CLASS = 19, - // sent to client - ZENY = 20, - SEX = 21, - // sent to client - NEXTBASEEXP = 22, - // sent to client - NEXTJOBEXP = 23, - // sent to client - WEIGHT = 24, - // sent to client - MAXWEIGHT = 25, - - // sent to client - USTR = 32, - // sent to client - UAGI = 33, - // sent to client - UVIT = 34, - // sent to client - UINT = 35, - // sent to client - UDEX = 36, - // sent to client - ULUK = 37, - - // sent to client - ATK1 = 41, - // sent to client - ATK2 = 42, - // sent to client - MATK1 = 43, - // sent to client - MATK2 = 44, - // sent to client - DEF1 = 45, - // sent to client - DEF2 = 46, - // sent to client - MDEF1 = 47, - // sent to client - MDEF2 = 48, - // sent to client - HIT = 49, - // sent to client - FLEE1 = 50, - // sent to client - FLEE2 = 51, - // sent to client - CRITICAL = 52, - // sent to client - ASPD = 53, - - // sent to client - JOBLEVEL = 55, - -# if 0 - PARTNER = 57, - CART = 58, - FAME = 59, - UNBREAKABLE = 60, -# endif - - DEAF = 70, - - // sent to client - GM = 500, - - // sent to client - ATTACKRANGE = 1000, -# if 0 - ATKELE = 1001, -# endif -# if 0 - DEFELE = 1002, -# endif -# if 0 - CASTRATE = 1003, -# endif - MAXHPRATE = 1004, -# if 0 - MAXSPRATE = 1005, -# endif -# if 0 - SPRATE = 1006, -# endif - -# if 0 - ADDEFF = 1012, -# endif -# if 0 - RESEFF = 1013, -# endif - BASE_ATK = 1014, - ASPD_RATE = 1015, - HP_RECOV_RATE = 1016, -# if 0 - SP_RECOV_RATE = 1017, -# endif -# if 0 - SPEED_RATE = 1018, -# endif - CRITICAL_DEF = 1019, -# if 0 - NEAR_ATK_DEF = 1020, -# endif -# if 0 - LONG_ATK_DEF = 1021, -# endif -# if 0 - DOUBLE_RATE = 1022, -# endif - DOUBLE_ADD_RATE = 1023, -# if 0 - MATK = 1024, -# endif -# if 0 - MATK_RATE = 1025, -# endif -# if 0 - IGNORE_DEF_ELE = 1026, -# endif -# if 0 - IGNORE_DEF_RACE = 1027, -# endif -# if 0 - ATK_RATE = 1028, -# endif - SPEED_ADDRATE = 1029, -# if 0 - ASPD_ADDRATE = 1030, -# endif -# if 0 - MAGIC_ATK_DEF = 1031, -# endif -# if 0 - MISC_ATK_DEF = 1032, -# endif -# if 0 - IGNORE_MDEF_ELE = 1033, -# endif -# if 0 - IGNORE_MDEF_RACE = 1034, -# endif - -# if 0 - PERFECT_HIT_RATE = 1038, -# endif -# if 0 - PERFECT_HIT_ADD_RATE = 1039, -# endif -# if 0 - CRITICAL_RATE = 1040, -# endif -# if 0 - GET_ZENY_NUM = 1041, -# endif -# if 0 - ADD_GET_ZENY_NUM = 1042, -# endif - -# if 0 - ADD_MONSTER_DROP_ITEM = 1047, -# endif -# if 0 - DEF_RATIO_ATK_ELE = 1048, -# endif -# if 0 - DEF_RATIO_ATK_RACE = 1049, -# endif -# if 0 - ADD_SPEED = 1050, -# endif -# if 0 - HIT_RATE = 1051, -# endif -# if 0 - FLEE_RATE = 1052, -# endif -# if 0 - FLEE2_RATE = 1053, -# endif - DEF_RATE = 1054, - DEF2_RATE = 1055, -# if 0 - MDEF_RATE = 1056, -# endif -# if 0 - MDEF2_RATE = 1057, -# endif -# if 0 - SPLASH_RANGE = 1058, -# endif -# if 0 - SPLASH_ADD_RANGE = 1059, -# endif - - HP_DRAIN_RATE = 1061, -# if 0 - SP_DRAIN_RATE = 1062, -# endif -# if 0 - SHORT_WEAPON_DAMAGE_RETURN = 1063, -# endif -# if 0 - LONG_WEAPON_DAMAGE_RETURN = 1064, -# endif - -# if 0 - ADDEFF2 = 1067, -# endif - BREAK_WEAPON_RATE = 1068, - BREAK_ARMOR_RATE = 1069, - ADD_STEAL_RATE = 1070, - MAGIC_DAMAGE_RETURN = 1071, -# if 0 - RANDOM_ATTACK_INCREASE = 1072, -# endif -}; - -constexpr -SP attr_to_sp(ATTR attr) -{ - return SP(uint16_t(attr) + uint16_t(SP::STR)); -} - -constexpr -ATTR sp_to_attr(SP sp) -{ - return ATTR(uint16_t(sp) - uint16_t(SP::STR)); -} - -constexpr -SP attr_to_usp(ATTR attr) -{ - return SP(uint16_t(attr) + uint16_t(SP::USTR)); -} - -constexpr -ATTR usp_to_attr(SP sp) -{ - return ATTR(uint16_t(sp) - uint16_t(SP::USTR)); -} - -constexpr -SP sp_to_usp(SP sp) -{ - return attr_to_usp(sp_to_attr(sp)); -} - -constexpr -SP usp_to_sp(SP sp) -{ - return attr_to_sp(usp_to_attr(sp)); -} - - -enum class LOOK : uint8_t -{ - BASE = 0, - HAIR = 1, - WEAPON = 2, - HEAD_BOTTOM = 3, - HEAD_TOP = 4, - HEAD_MID = 5, - HAIR_COLOR = 6, - CLOTHES_COLOR = 7, - SHIELD = 8, - SHOES = 9, - GLOVES = 10, - CAPE = 11, - MISC1 = 12, - MISC2 = 13, - - COUNT, -}; enum class EQUIP { @@ -514,22 +143,6 @@ EQUIP EQUIPs_noarrow[] = EQUIP::WEAPON, }; -enum class ItemType : uint8_t -{ - USE = 0, // in eA, healing only - _1 = 1, // unused - _2 = 2, // in eA, other usable items - JUNK = 3, // "useless" items (e.g. quests) - WEAPON = 4, // all weapons - ARMOR = 5, // all other equipment - _6 = 6, // in eA, card - _7 = 7, // in eA, pet egg - _8 = 8, // in eA, pet equipment - _9 = 9, // unused - ARROW = 10, // ammo - _11 = 11, // in eA, delayed use (special script) -}; - namespace e { enum class MobMode : uint16_t @@ -583,4 +196,8 @@ struct NpcName : VString<23> {}; struct ScriptLabel : VString<23> {}; struct ItemName : VString<23> {}; -#endif // TMWA_MAP_MAP_T_HPP +inline +BlockId account_to_block(AccountId a) { return wrap<BlockId>(unwrap<AccountId>(a)); } +inline +AccountId block_to_account(BlockId b) { return wrap<AccountId>(unwrap<BlockId>(b)); } +} // namespace tmwa diff --git a/src/map/mapflag.cpp b/src/map/mapflag.cpp index 51af30a..f9cf8f6 100644 --- a/src/map/mapflag.cpp +++ b/src/map/mapflag.cpp @@ -20,6 +20,9 @@ #include "../poison.hpp" + +namespace tmwa +{ // because bitfields, that's why bool MapFlags::get(MapFlag mf) const @@ -40,41 +43,41 @@ bool extract<MapFlag, void, void>(XString str, MapFlag *mf) { const struct { - ZString str; + LString str; MapFlag id; } flags[] = { - //{ZString("alias"), MapFlag::ALIAS}, - //{ZString("nomemo"), MapFlag::NOMEMO}, - {ZString("noteleport"), MapFlag::NOTELEPORT}, - {ZString("noreturn"), MapFlag::NORETURN}, - {ZString("monster_noteleport"), MapFlag::MONSTER_NOTELEPORT}, - {ZString("nosave"), MapFlag::NOSAVE}, - //{ZString("nobranch"), MapFlag::NOBRANCH}, - {ZString("nopenalty"), MapFlag::NOPENALTY}, - {ZString("pvp"), MapFlag::PVP}, - {ZString("pvp_noparty"), MapFlag::PVP_NOPARTY}, - //{ZString("pvp_noguild"), MapFlag::PVP_NOGUILD}, - //{ZString("pvp_nightmaredrop"), MapFlag::PVP_NIGHTMAREDROP}, - {ZString("pvp_nocalcrank"), MapFlag::PVP_NOCALCRANK}, - //{ZString("gvg"), MapFlag::GVG}, - //{ZString("gvg_noparty"), MapFlag::GVG_NOPARTY}, - //{ZString("nozenypenalty"), MapFlag::NOZENYPENALTY}, - //{ZString("notrade"), MapFlag::NOTRADE}, - //{ZString("noskill"), MapFlag::NOSKILL}, - {ZString("nowarp"), MapFlag::NOWARP}, - {ZString("nowarpto"), MapFlag::NOWARPTO}, - {ZString("nopvp"), MapFlag::NOPVP}, - //{ZString("noicewall"), MapFlag::NOICEWALL}, - {ZString("snow"), MapFlag::SNOW}, - {ZString("fog"), MapFlag::FOG}, - {ZString("sakura"), MapFlag::SAKURA}, - {ZString("leaves"), MapFlag::LEAVES}, - {ZString("rain"), MapFlag::RAIN}, - {ZString("no_player_drops"), MapFlag::NO_PLAYER_DROPS}, - {ZString("town"), MapFlag::TOWN}, - {ZString("outside"), MapFlag::OUTSIDE}, - {ZString("resave"), MapFlag::RESAVE}, + //{"alias"_s, MapFlag::ALIAS}, + //{"nomemo"_s, MapFlag::NOMEMO}, + {"noteleport"_s, MapFlag::NOTELEPORT}, + {"noreturn"_s, MapFlag::NORETURN}, + {"monster_noteleport"_s, MapFlag::MONSTER_NOTELEPORT}, + {"nosave"_s, MapFlag::NOSAVE}, + //{"nobranch"_s, MapFlag::NOBRANCH}, + {"nopenalty"_s, MapFlag::NOPENALTY}, + {"pvp"_s, MapFlag::PVP}, + {"pvp_noparty"_s, MapFlag::PVP_NOPARTY}, + //{"pvp_noguild"_s, MapFlag::PVP_NOGUILD}, + //{"pvp_nightmaredrop"_s, MapFlag::PVP_NIGHTMAREDROP}, + {"pvp_nocalcrank"_s, MapFlag::PVP_NOCALCRANK}, + //{"gvg"_s, MapFlag::GVG}, + //{"gvg_noparty"_s, MapFlag::GVG_NOPARTY}, + //{"nozenypenalty"_s, MapFlag::NOZENYPENALTY}, + //{"notrade"_s, MapFlag::NOTRADE}, + //{"noskill"_s, MapFlag::NOSKILL}, + {"nowarp"_s, MapFlag::NOWARP}, + {"nowarpto"_s, MapFlag::NOWARPTO}, + {"nopvp"_s, MapFlag::NOPVP}, + //{"noicewall"_s, MapFlag::NOICEWALL}, + {"snow"_s, MapFlag::SNOW}, + {"fog"_s, MapFlag::FOG}, + {"sakura"_s, MapFlag::SAKURA}, + {"leaves"_s, MapFlag::LEAVES}, + {"rain"_s, MapFlag::RAIN}, + {"no_player_drops"_s, MapFlag::NO_PLAYER_DROPS}, + {"town"_s, MapFlag::TOWN}, + {"outside"_s, MapFlag::OUTSIDE}, + {"resave"_s, MapFlag::RESAVE}, }; for (auto& pair : flags) if (str == pair.str) @@ -89,3 +92,4 @@ MapFlag map_flag_from_int(int shift) { return static_cast<MapFlag>(1 << shift); } +} // namespace tmwa diff --git a/src/map/mapflag.hpp b/src/map/mapflag.hpp index e3a55f5..197d250 100644 --- a/src/map/mapflag.hpp +++ b/src/map/mapflag.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_MAPFLAG_HPP -#define TMWA_MAP_MAPFLAG_HPP +#pragma once // mapflag.hpp - booleans that apply to an entire map // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,12 +18,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../mmo/extract.hpp" // TODO remove this (requires specializing the *other* half) +#include <cstdint> -# include "../strings/xstring.hpp" +#include "../mmo/extract.hpp" // TODO remove this (requires specializing the *other* half) + +namespace tmwa +{ // originally from script.cpp // These are part of the script API, so they can't change ever, // even though they are silly. @@ -79,5 +81,4 @@ template<> bool extract<MapFlag, void, void>(XString str, MapFlag *mf); MapFlag map_flag_from_int(int shift); - -#endif // TMWA_MAP_MAPFLAG_HPP +} // namespace tmwa diff --git a/src/map/mapflag.py b/src/map/mapflag.py index 3bc9f1a..fec8c05 100644 --- a/src/map/mapflag.py +++ b/src/map/mapflag.py @@ -2,7 +2,7 @@ class MapFlags(object): ''' print a set of map flags ''' __slots__ = ('_value') - name = 'MapFlags' + name = 'tmwa::MapFlags' enabled = True def __init__(self, value): diff --git a/src/map/mob.cpp b/src/map/mob.cpp index a96f829..1fd8cf3 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -23,8 +23,6 @@ #include <cassert> #include <cmath> -#include <cstdlib> -#include <cstring> #include <algorithm> @@ -32,6 +30,7 @@ #include "../compat/nullpo.hpp" #include "../strings/astring.hpp" +#include "../strings/zstring.hpp" #include "../strings/xstring.hpp" #include "../generic/random.hpp" @@ -39,10 +38,11 @@ #include "../io/cxxstdio.hpp" #include "../io/read.hpp" +#include "../net/socket.hpp" +#include "../net/timer.hpp" + #include "../mmo/config_parse.hpp" #include "../mmo/extract.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" #include "battle.hpp" #include "clif.hpp" @@ -56,14 +56,22 @@ #include "../poison.hpp" -constexpr interval_t MIN_MOBTHINKTIME = std::chrono::milliseconds(100); + +namespace tmwa +{ +constexpr interval_t MIN_MOBTHINKTIME = 100_ms; // Move probability in the negligent mode MOB (rate of 1000 minute) constexpr random_::Fraction MOB_LAZYMOVEPERC {50, 1000}; // Warp probability in the negligent mode MOB (rate of 1000 minute) constexpr random_::Fraction MOB_LAZYWARPPERC {20, 1000}; +static struct mob_db_ mob_db[2001]; +struct mob_db_& get_mob_db(Species s) +{ + return mob_db[unwrap<Species>(s)]; +} /*========================================== * Local prototype declaration (only required thing) @@ -72,9 +80,9 @@ struct mob_db_ mob_db[2001]; static int distance(int, int, int, int); static -int mob_makedummymobdb(int); +int mob_makedummymobdb(Species); static -void mob_timer(TimerData *, tick_t, int, unsigned char); +void mob_timer(TimerData *, tick_t, BlockId, unsigned char); static int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target, mob_skill& skill_idx); @@ -83,30 +91,29 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target, * Mob is searched with a name. *------------------------------------------ */ -int mobdb_searchname(MobName str) +Species mobdb_searchname(MobName str) { int i; for (i = 0; i < sizeof(mob_db) / sizeof(mob_db[0]); i++) { if (mob_db[i].name == str || mob_db[i].jname == str) - return i; + return wrap<Species>(i); } - return 0; + return Species(); } /*========================================== * Id Mob is checked. *------------------------------------------ */ -int mobdb_checkid(const int id) +Species mobdb_checkid(Species id) { - if (id <= 0 || id >= (sizeof(mob_db) / sizeof(mob_db[0])) - || !mob_db[id].name) - return 0; - - return id; + // value range is [1001, 2000] + if (wrap<Species>(1000) < id && id < wrap<Species>(2001)) + return id; + return Species(); } static @@ -117,27 +124,27 @@ void mob_init(dumb_ptr<mob_data> md); *------------------------------------------ */ static -void mob_spawn_dataset(dumb_ptr<mob_data> md, MobName mobname, int mob_class) +void mob_spawn_dataset(dumb_ptr<mob_data> md, MobName mobname, Species mob_class) { nullpo_retv(md); if (mobname == ENGLISH_NAME) - md->name = mob_db[mob_class].name; + md->name = get_mob_db(mob_class).name; else if (mobname == JAPANESE_NAME) - md->name = mob_db[mob_class].jname; + md->name = get_mob_db(mob_class).jname; else md->name = mobname; - md->bl_prev = NULL; - md->bl_next = NULL; + md->bl_prev = nullptr; + md->bl_next = nullptr; md->n = 0; md->mob_class = mob_class; md->bl_id = npc_get_new_npc_id(); really_memzero_this(&md->state); // md->timer = nullptr; - md->target_id = 0; - md->attacked_id = 0; + md->target_id = BlockId(); + md->attacked_id = BlockId(); mob_init(md); } @@ -265,12 +272,16 @@ void mob_mutate(dumb_ptr<mob_data> md, mob_stat stat, int intensity) int real_intensity2 = (((new_stat - old_stat) << 8) / mut_base); if (real_intensity < 0) + { if (real_intensity2 > real_intensity) real_intensity = real_intensity2; + } if (real_intensity > 0) + { if (real_intensity2 < real_intensity) real_intensity = real_intensity2; + } } real_intensity *= sign; @@ -322,7 +333,7 @@ int mob_gen_exp(mob_db_ *mob) * static_cast<double>(battle_config.base_exp_rate) / 100.); if (xp < 1) xp = 1; - PRINTF("Exp for mob '%s' generated: %d\n", mob->name, xp); + PRINTF("Exp for mob '%s' generated: %d\n"_fmt, mob->name, xp); return xp; } @@ -330,24 +341,24 @@ static void mob_init(dumb_ptr<mob_data> md) { int i; - const int mob_class = md->mob_class; - const int mutations_nr = mob_db[mob_class].mutations_nr; - const int mutation_power = mob_db[mob_class].mutation_power; - - md->stats[mob_stat::LV] = mob_db[mob_class].lv; - md->stats[mob_stat::MAX_HP] = mob_db[mob_class].max_hp; - md->stats[mob_stat::STR] = mob_db[mob_class].attrs[ATTR::STR]; - md->stats[mob_stat::AGI] = mob_db[mob_class].attrs[ATTR::AGI]; - md->stats[mob_stat::VIT] = mob_db[mob_class].attrs[ATTR::VIT]; - md->stats[mob_stat::INT] = mob_db[mob_class].attrs[ATTR::INT]; - md->stats[mob_stat::DEX] = mob_db[mob_class].attrs[ATTR::DEX]; - md->stats[mob_stat::LUK] = mob_db[mob_class].attrs[ATTR::LUK]; - md->stats[mob_stat::ATK1] = mob_db[mob_class].atk1; - md->stats[mob_stat::ATK2] = mob_db[mob_class].atk2; - md->stats[mob_stat::ADELAY] = mob_db[mob_class].adelay; - md->stats[mob_stat::DEF] = mob_db[mob_class].def; - md->stats[mob_stat::MDEF] = mob_db[mob_class].mdef; - md->stats[mob_stat::SPEED] = mob_db[mob_class].speed; + const Species mob_class = md->mob_class; + const int mutations_nr = get_mob_db(mob_class).mutations_nr; + const int mutation_power = get_mob_db(mob_class).mutation_power; + + md->stats[mob_stat::LV] = get_mob_db(mob_class).lv; + md->stats[mob_stat::MAX_HP] = get_mob_db(mob_class).max_hp; + md->stats[mob_stat::STR] = get_mob_db(mob_class).attrs[ATTR::STR]; + md->stats[mob_stat::AGI] = get_mob_db(mob_class).attrs[ATTR::AGI]; + md->stats[mob_stat::VIT] = get_mob_db(mob_class).attrs[ATTR::VIT]; + md->stats[mob_stat::INT] = get_mob_db(mob_class).attrs[ATTR::INT]; + md->stats[mob_stat::DEX] = get_mob_db(mob_class).attrs[ATTR::DEX]; + md->stats[mob_stat::LUK] = get_mob_db(mob_class).attrs[ATTR::LUK]; + md->stats[mob_stat::ATK1] = get_mob_db(mob_class).atk1; + md->stats[mob_stat::ATK2] = get_mob_db(mob_class).atk2; + md->stats[mob_stat::ADELAY] = get_mob_db(mob_class).adelay; + md->stats[mob_stat::DEF] = get_mob_db(mob_class).def; + md->stats[mob_stat::MDEF] = get_mob_db(mob_class).mdef; + md->stats[mob_stat::SPEED] = get_mob_db(mob_class).speed; md->stats[mob_stat::XP_BONUS] = MOB_XP_BONUS_BASE; for (i = 0; i < mutations_nr; i++) @@ -391,22 +402,22 @@ void mob_init(dumb_ptr<mob_data> md) * The MOB appearance for one time (for scripts) *------------------------------------------ */ -int mob_once_spawn(dumb_ptr<map_session_data> sd, +BlockId mob_once_spawn(dumb_ptr<map_session_data> sd, MapName mapname, int x, int y, - MobName mobname, int mob_class, int amount, + MobName mobname, Species mob_class, int amount, NpcEvent event) { - dumb_ptr<mob_data> md = NULL; + dumb_ptr<mob_data> md = nullptr; map_local *m; - int count, r = mob_class; + int count; if (sd && mapname == MOB_THIS_MAP) m = sd->bl_m; else m = map_mapname2mapid(mapname); - if (m == nullptr || amount <= 0 || (mob_class >= 0 && mob_class <= 1000) || mob_class > 2000) // 値が異常なら召喚を止める - return 0; + if (m == nullptr || amount <= 0 || mobdb_checkid(mob_class) == Species()) + return BlockId(); if (sd) { @@ -417,7 +428,7 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd, } else if (x <= 0 || y <= 0) { - PRINTF("mob_once_spawn: ??\n"); + PRINTF("mob_once_spawn: ??\n"_fmt); } for (count = 0; count < amount; count++) @@ -429,9 +440,6 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd, md->bl_m = m; md->bl_x = x; md->bl_y = y; - if (r < 0 && battle_config.dead_branch_active == 1) - //移動してアクティブで反撃する - md->mode = MobMode::war; md->spawn.m = m; md->spawn.x0 = x; md->spawn.y0 = y; @@ -446,19 +454,20 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd, map_addiddb(md); mob_spawn(md->bl_id); } - return (amount > 0) ? md->bl_id : 0; + return (amount > 0) ? md->bl_id : BlockId(); } /*========================================== * The MOB appearance for one time (& area specification for scripts) *------------------------------------------ */ -int mob_once_spawn_area(dumb_ptr<map_session_data> sd, +BlockId mob_once_spawn_area(dumb_ptr<map_session_data> sd, MapName mapname, int x0, int y0, int x1, int y1, - MobName mobname, int mob_class, int amount, + MobName mobname, Species mob_class, int amount, NpcEvent event) { - int x, y, i, max, lx = -1, ly = -1, id = 0; + int x, y, i, max, lx = -1, ly = -1; + BlockId id; map_local *m; if (mapname == MOB_THIS_MAP) @@ -470,8 +479,8 @@ int mob_once_spawn_area(dumb_ptr<map_session_data> sd, if (max > 1000) max = 1000; - if (m == nullptr || amount <= 0 || (mob_class >= 0 && mob_class <= 1000) || mob_class > 2000) // A summon is stopped if a value is unusual - return 0; + if (m == nullptr || amount <= 0 || (mobdb_checkid(mob_class) == Species())) // A summon is stopped if a value is unusual + return BlockId(); for (i = 0; i < amount; i++) { @@ -491,7 +500,7 @@ int mob_once_spawn_area(dumb_ptr<map_session_data> sd, y = ly; } else - return 0; // Since reference of the place which boils first went wrong, it stops. + return BlockId(); // Since reference of the place which boils first went wrong, it stops. } id = mob_once_spawn(sd, mapname, x, y, mobname, mob_class, 1, event); lx = x; @@ -501,49 +510,49 @@ int mob_once_spawn_area(dumb_ptr<map_session_data> sd, } // TODO: deprecate these -short mob_get_hair(int mob_class) +short mob_get_hair(Species mob_class) { - return mob_db[mob_class].hair; + return get_mob_db(mob_class).hair; } -short mob_get_hair_color(int mob_class) +short mob_get_hair_color(Species mob_class) { - return mob_db[mob_class].hair_color; + return get_mob_db(mob_class).hair_color; } -short mob_get_weapon(int mob_class) +short mob_get_weapon(Species mob_class) { - return mob_db[mob_class].weapon; + return get_mob_db(mob_class).weapon; } -short mob_get_shield(int mob_class) +ItemNameId mob_get_shield(Species mob_class) { - return mob_db[mob_class].shield; + return get_mob_db(mob_class).shield; } -short mob_get_head_top(int mob_class) +ItemNameId mob_get_head_top(Species mob_class) { - return mob_db[mob_class].head_top; + return get_mob_db(mob_class).head_top; } -short mob_get_head_mid(int mob_class) +ItemNameId mob_get_head_mid(Species mob_class) { - return mob_db[mob_class].head_mid; + return get_mob_db(mob_class).head_mid; } -short mob_get_head_buttom(int mob_class) +ItemNameId mob_get_head_buttom(Species mob_class) { - return mob_db[mob_class].head_buttom; + return get_mob_db(mob_class).head_buttom; } -short mob_get_clothes_color(int mob_class) // Add for player monster dye - Valaris +short mob_get_clothes_color(Species mob_class) // Add for player monster dye - Valaris { - return mob_db[mob_class].clothes_color; // End + return get_mob_db(mob_class).clothes_color; // End } -int mob_get_equip(int mob_class) // mob equip [Valaris] +int mob_get_equip(Species mob_class) // mob equip [Valaris] { - return mob_db[mob_class].equip; + return get_mob_db(mob_class).equip; } /*========================================== @@ -553,7 +562,7 @@ int mob_get_equip(int mob_class) // mob equip [Valaris] static int mob_can_move(dumb_ptr<mob_data> md) { - nullpo_ret(md); + nullpo_retz(md); if (md->canmove_tick > gettick() || (bool(md->opt1) && md->opt1 != Opt1::_stone6)) @@ -591,7 +600,7 @@ int mob_walk(dumb_ptr<mob_data> md, tick_t tick, unsigned char data) int moveblock; int x, y, dx, dy; - nullpo_ret(md); + nullpo_retz(md); md->state.state = MS::IDLE; if (md->walkpath.path_pos >= md->walkpath.path_len @@ -667,7 +676,7 @@ int mob_walk(dumb_ptr<mob_data> md, tick_t tick, unsigned char data) { i = i / 2; if (md->walkpath.path_half == 0) - i = std::max(i, std::chrono::milliseconds(1)); + i = std::max(i, 1_ms); md->timer = Timer(tick + i, std::bind(mob_timer, ph::_1, ph::_2, md->bl_id, md->walkpath.path_pos)); @@ -686,14 +695,14 @@ int mob_walk(dumb_ptr<mob_data> md, tick_t tick, unsigned char data) static int mob_check_attack(dumb_ptr<mob_data> md) { - dumb_ptr<block_list> tbl = NULL; - dumb_ptr<map_session_data> tsd = NULL; - dumb_ptr<mob_data> tmd = NULL; + dumb_ptr<block_list> tbl = nullptr; + dumb_ptr<map_session_data> tsd = nullptr; + dumb_ptr<mob_data> tmd = nullptr; MobMode mode; int range; - nullpo_ret(md); + nullpo_retz(md); md->min_chase = 13; md->state.state = MS::IDLE; @@ -705,9 +714,9 @@ int mob_check_attack(dumb_ptr<mob_data> md) if (bool(md->opt1)) return 0; - if ((tbl = map_id2bl(md->target_id)) == NULL) + if ((tbl = map_id2bl(md->target_id)) == nullptr) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; return 0; } @@ -722,34 +731,34 @@ int mob_check_attack(dumb_ptr<mob_data> md) if (tsd) { if (pc_isdead(tsd) || tsd->invincible_timer - || pc_isinvisible(tsd) || md->bl_m != tbl->bl_m || tbl->bl_prev == NULL + || pc_isinvisible(tsd) || md->bl_m != tbl->bl_m || tbl->bl_prev == nullptr || distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y) >= 13) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; return 0; } } if (tmd) { - if (md->bl_m != tbl->bl_m || tbl->bl_prev == NULL + if (md->bl_m != tbl->bl_m || tbl->bl_prev == nullptr || distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y) >= 13) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; return 0; } } if (md->mode == MobMode::ZERO) - mode = mob_db[md->mob_class].mode; + mode = get_mob_db(md->mob_class).mode; else mode = md->mode; - Race race = mob_db[md->mob_class].race; + Race race = get_mob_db(md->mob_class).race; if (!bool(mode & MobMode::CAN_ATTACK)) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; return 0; } @@ -759,12 +768,12 @@ int mob_check_attack(dumb_ptr<mob_data> md) && race != Race::_insect && race != Race::_demon)) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; return 0; } - range = mob_db[md->mob_class].range; + range = get_mob_db(md->mob_class).range; if (bool(mode & MobMode::CAN_MOVE)) range++; if (distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y) > range) @@ -788,11 +797,11 @@ void mob_ancillary_attack(dumb_ptr<block_list> bl, static int mob_attack(dumb_ptr<mob_data> md, tick_t tick) { - dumb_ptr<block_list> tbl = NULL; + dumb_ptr<block_list> tbl = nullptr; - nullpo_ret(md); + nullpo_retz(md); - if ((tbl = map_id2bl(md->target_id)) == NULL) + if ((tbl = map_id2bl(md->target_id)) == nullptr) return 0; if (!mob_check_attack(md)) @@ -834,7 +843,7 @@ int mob_attack(dumb_ptr<mob_data> md, tick_t tick) *------------------------------------------ */ static -void mob_stopattacked(dumb_ptr<map_session_data> sd, int id) +void mob_stopattacked(dumb_ptr<map_session_data> sd, BlockId id) { nullpo_retv(sd); @@ -849,7 +858,7 @@ void mob_stopattacked(dumb_ptr<map_session_data> sd, int id) static int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type) { - nullpo_ret(md); + nullpo_retz(md); md->timer.cancel(); md->state.state = state; @@ -874,7 +883,7 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type) { tick_t tick = gettick(); interval_t i = md->attackabletime - tick; - if (i > interval_t::zero() && i < std::chrono::seconds(2)) + if (i > interval_t::zero() && i < 2_s) md->timer = Timer(md->attackabletime, std::bind(mob_timer, ph::_1, ph::_2, md->bl_id, 0)); @@ -887,7 +896,7 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type) } else { - md->attackabletime = tick + std::chrono::milliseconds(1); + md->attackabletime = tick + 1_ms; md->timer = Timer(md->attackabletime, std::bind(mob_timer, ph::_1, ph::_2, md->bl_id, 0)); @@ -903,7 +912,8 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type) clif_foreachclient(std::bind(mob_stopattacked, ph::_1, md->bl_id)); skill_status_change_clear(md, 2); // The abnormalities in status are canceled. md->deletetimer.cancel(); - md->hp = md->target_id = md->attacked_id = 0; + md->hp = 0; + md->target_id = md->attacked_id = BlockId(); md->state.attackable = false; } break; @@ -918,12 +928,12 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type) *------------------------------------------ */ static -void mob_timer(TimerData *, tick_t tick, int id, unsigned char data) +void mob_timer(TimerData *, tick_t tick, BlockId id, unsigned char data) { dumb_ptr<mob_data> md; dumb_ptr<block_list> bl; bl = map_id2bl(id); - if (bl == NULL) + if (bl == nullptr) { //攻撃してきた敵がもういないのは正常のようだ return; } @@ -933,7 +943,7 @@ void mob_timer(TimerData *, tick_t tick, int id, unsigned char data) md = bl->is_mob(); - if (md->bl_prev == NULL || md->state.state == MS::DEAD) + if (md->bl_prev == nullptr || md->state.state == MS::DEAD) return; MapBlockLock lock; @@ -948,7 +958,7 @@ void mob_timer(TimerData *, tick_t tick, int id, unsigned char data) break; default: if (battle_config.error_log == 1) - PRINTF("mob_timer : %d ?\n", + PRINTF("mob_timer : %d ?\n"_fmt, md->state.state); break; } @@ -963,7 +973,7 @@ int mob_walktoxy_sub(dumb_ptr<mob_data> md) { struct walkpath_data wpd; - nullpo_ret(md); + nullpo_retz(md); if (path_search(&wpd, md->bl_m, md->bl_x, md->bl_y, md->to_x, md->to_y, md->state.walk_easy)) @@ -986,7 +996,7 @@ int mob_walktoxy(dumb_ptr<mob_data> md, int x, int y, int easy) { struct walkpath_data wpd; - nullpo_ret(md); + nullpo_retz(md); if (md->state.state == MS::WALK && path_search(&wpd, md->bl_m, md->bl_x, md->bl_y, x, y, easy)) @@ -1012,7 +1022,7 @@ int mob_walktoxy(dumb_ptr<mob_data> md, int x, int y, int easy) *------------------------------------------ */ static -void mob_delayspawn(TimerData *, tick_t, int m) +void mob_delayspawn(TimerData *, tick_t, BlockId m) { mob_spawn(m); } @@ -1022,12 +1032,12 @@ void mob_delayspawn(TimerData *, tick_t, int m) *------------------------------------------ */ static -int mob_setdelayspawn(int id) +int mob_setdelayspawn(BlockId id) { dumb_ptr<mob_data> md; dumb_ptr<block_list> bl; - if ((bl = map_id2bl(id)) == NULL) + if ((bl = map_id2bl(id)) == nullptr) return -1; if (!bl || bl->bl_type == BL::NUL || bl->bl_type != BL::MOB) @@ -1052,7 +1062,7 @@ int mob_setdelayspawn(int id) tick_t spawntime1 = md->last_spawntime + md->spawn.delay1; tick_t spawntime2 = md->last_deadtime + md->spawn.delay2; - tick_t spawntime3 = gettick() + std::chrono::seconds(5); + tick_t spawntime3 = gettick() + 5_s; tick_t spawntime = std::max({spawntime1, spawntime2, spawntime3}); Timer(spawntime, @@ -1066,7 +1076,7 @@ int mob_setdelayspawn(int id) * Mob spawning. Initialization is also variously here. *------------------------------------------ */ -int mob_spawn(int id) +int mob_spawn(BlockId id) { int x = 0, y = 0; tick_t tick = gettick(); @@ -1086,7 +1096,7 @@ int mob_spawn(int id) return -1; md->last_spawntime = tick; - if (md->bl_prev != NULL) + if (md->bl_prev != nullptr) { map_delblock(md); } @@ -1115,9 +1125,7 @@ int mob_spawn(int id) if (i >= 50) { - // if(battle_config.error_log==1) - // PRINTF("MOB spawn error %d @ %s\n",id,map[md->bl_m].name); - Timer(tick + std::chrono::seconds(5), + Timer(tick + 5_s, std::bind(mob_delayspawn, ph::_1, ph::_2, id) ).detach(); @@ -1132,31 +1140,31 @@ int mob_spawn(int id) map_addblock(md); really_memzero_this(&md->state); - md->attacked_id = 0; - md->target_id = 0; + md->attacked_id = BlockId(); + md->target_id = BlockId(); md->move_fail_count = 0; mob_init(md); if (!md->stats[mob_stat::SPEED]) - md->stats[mob_stat::SPEED] = mob_db[md->mob_class].speed; - md->def_ele = mob_db[md->mob_class].element; - md->master_id = 0; + md->stats[mob_stat::SPEED] = get_mob_db(md->mob_class).speed; + md->def_ele = get_mob_db(md->mob_class).element; + md->master_id = BlockId(); md->master_dist = 0; md->state.state = MS::IDLE; md->state.skillstate = MobSkillState::MSS_IDLE; assert (!md->timer); md->last_thinktime = tick; - md->next_walktime = tick + std::chrono::seconds(5) + std::chrono::milliseconds(random_::to(50)); + md->next_walktime = tick + 5_s + std::chrono::milliseconds(random_::to(50)); md->attackabletime = tick; md->canmove_tick = tick; // md->deletetimer = nullptr; // md->skilltimer = nullptr; - md->skilldelayup = make_unique<tick_t[]>(mob_db[md->mob_class].skills.size()); - for (size_t i = 0; i < mob_db[md->mob_class].skills.size(); i++) - md->skilldelayup[i] = tick - std::chrono::hours(10); + md->skilldelayup = make_unique<tick_t[]>(get_mob_db(md->mob_class).skills.size()); + for (size_t i = 0; i < get_mob_db(md->mob_class).skills.size(); i++) + md->skilldelayup[i] = tick - 10_h; md->skillid = SkillID(); md->skilllv = 0; @@ -1206,9 +1214,9 @@ int distance(int x0, int y0, int x1, int y1) */ int mob_stopattack(dumb_ptr<mob_data> md) { - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; - md->attacked_id = 0; + md->attacked_id = BlockId(); return 0; } @@ -1218,7 +1226,7 @@ int mob_stopattack(dumb_ptr<mob_data> md) */ int mob_stop_walking(dumb_ptr<mob_data> md, int type) { - nullpo_ret(md); + nullpo_retz(md); if (md->state.state == MS::WALK || md->state.state == MS::IDLE) { @@ -1271,8 +1279,8 @@ int mob_can_reach(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int range) struct walkpath_data wpd; int i; - nullpo_ret(md); - nullpo_ret(bl); + nullpo_retz(md); + nullpo_retz(bl); dx = abs(bl->bl_x - md->bl_x); dy = abs(bl->bl_y - md->bl_y); @@ -1328,16 +1336,16 @@ int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist) eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; MobMode mode; - nullpo_ret(md); - nullpo_ret(bl); + nullpo_retz(md); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); Option *option = battle_get_option(bl); - Race race = mob_db[md->mob_class].race; + Race race = get_mob_db(md->mob_class).race; if (md->mode == MobMode::ZERO) { - mode = mob_db[md->mob_class].mode; + mode = get_mob_db(md->mob_class).mode; } else { @@ -1345,25 +1353,25 @@ int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist) } if (!bool(mode & MobMode::CAN_ATTACK)) { - md->target_id = 0; + md->target_id = BlockId(); return 0; } // Nothing will be carried out if there is no mind of changing TAGE by TAGE ending. - if ((md->target_id > 0 && md->state.attackable) + if ((md->target_id && md->state.attackable) && (!bool(mode & MobMode::AGGRESSIVE) || !random_::chance({25 + 1, 100}))) return 0; // Coercion is exerted if it is MVPMOB. if (bool(mode & MobMode::BOSS) - || (option != NULL + || (option != nullptr || race == Race::_insect || race == Race::_demon)) { if (bl->bl_type == BL::PC) { sd = bl->is_player(); - nullpo_ret(sd); + nullpo_retz(sd); if (sd->invincible_timer || pc_isinvisible(sd)) return 0; if (!bool(mode & MobMode::BOSS) && race != Race::_insect && race != Race::_demon @@ -1391,8 +1399,8 @@ static void mob_ai_sub_hard_activesearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> smd, int *pcc) { - dumb_ptr<map_session_data> tsd = NULL; - dumb_ptr<mob_data> tmd = NULL; + dumb_ptr<map_session_data> tsd = nullptr; + dumb_ptr<mob_data> tmd = nullptr; MobMode mode; int dist; @@ -1412,14 +1420,14 @@ void mob_ai_sub_hard_activesearch(dumb_ptr<block_list> bl, return; if (smd->mode == MobMode::ZERO) - mode = mob_db[smd->mob_class].mode; + mode = get_mob_db(smd->mob_class).mode; else mode = smd->mode; // アクティブでターゲット射程内にいるなら、ロックする if (bool(mode & MobMode::AGGRESSIVE)) { - Race race = mob_db[smd->mob_class].race; + Race race = get_mob_db(smd->mob_class).race; //対象がPCの場合 if (tsd && !pc_isdead(tsd) && @@ -1479,7 +1487,7 @@ void mob_ai_sub_hard_lootsearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md, if (md->mode == MobMode::ZERO) { - mode = mob_db[md->mob_class].mode; + mode = get_mob_db(md->mob_class).mode; } else { @@ -1518,8 +1526,8 @@ void mob_ai_sub_hard_linksearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md, nullpo_retv(md); nullpo_retv(target); - if (md->attacked_id > 0 - && bool(mob_db[md->mob_class].mode & MobMode::ASSIST)) + if (md->attacked_id + && bool(get_mob_db(md->mob_class).mode & MobMode::ASSIST)) { if (tmd->mob_class == md->mob_class && tmd->bl_m == md->bl_m @@ -1543,17 +1551,17 @@ void mob_ai_sub_hard_linksearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md, static int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick) { - dumb_ptr<mob_data> mmd = NULL; + dumb_ptr<mob_data> mmd = nullptr; dumb_ptr<block_list> bl; MobMode mode; int old_dist; - nullpo_ret(md); + nullpo_retz(md); - if ((bl = map_id2bl(md->master_id)) != NULL) + if ((bl = map_id2bl(md->master_id)) != nullptr) mmd = bl->is_mob(); - mode = mob_db[md->mob_class].mode; + mode = get_mob_db(md->mob_class).mode; // It is not main monster/leader. if (!mmd || mmd->bl_type != BL::MOB || mmd->bl_id != md->master_id) @@ -1636,20 +1644,20 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick) while (ret && i < 10); } - md->next_walktime = tick + std::chrono::milliseconds(500); + md->next_walktime = tick + 500_ms; md->state.master_check = 1; } // There is the master, the master locks a target and he does not lock. - if ((mmd->target_id > 0 && mmd->state.attackable) + if ((mmd->target_id && mmd->state.attackable) && (!md->target_id || !md->state.attackable)) { dumb_ptr<map_session_data> sd = map_id2sd(mmd->target_id); - if (sd != NULL && !pc_isdead(sd) && !sd->invincible_timer + if (sd != nullptr && !pc_isdead(sd) && !sd->invincible_timer && !pc_isinvisible(sd)) { - Race race = mob_db[md->mob_class].race; + Race race = get_mob_db(md->mob_class).race; if (bool(mode & MobMode::BOSS) || (!sd->state.gangsterparadise || race == Race::_insect @@ -1675,12 +1683,12 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick) static int mob_unlocktarget(dumb_ptr<mob_data> md, tick_t tick) { - nullpo_ret(md); + nullpo_retz(md); - md->target_id = 0; + md->target_id = BlockId(); md->state.attackable = false; md->state.skillstate = MobSkillState::MSS_IDLE; - md->next_walktime = tick + std::chrono::seconds(3) + std::chrono::milliseconds(random_::to(3000)); + md->next_walktime = tick + 3_s + std::chrono::milliseconds(random_::to(3000)); return 0; } @@ -1693,7 +1701,7 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick) { const int retrycount = 20; - nullpo_ret(md); + nullpo_retz(md); interval_t speed = battle_get_speed(md); if (md->next_walktime < tick) @@ -1718,8 +1726,8 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick) if (md->move_fail_count > 1000) { if (battle_config.error_log == 1) - PRINTF("MOB cant move. random spawn %d, mob_class = %d\n", - md->bl_id, md->mob_class); + PRINTF("MOB cant move. random spawn %d, mob_class = %d\n"_fmt, + md->bl_id, md->mob_class); md->move_fail_count = 0; mob_spawn(md->bl_id); } @@ -1734,7 +1742,7 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick) else c += speed; } - md->next_walktime = tick + std::chrono::seconds(3) + std::chrono::milliseconds(random_::to(3000)) + c; + md->next_walktime = tick + 3_s + std::chrono::milliseconds(random_::to(3000)) + c; md->state.skillstate = MobSkillState::MSS_WALK; return 1; } @@ -1748,9 +1756,9 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick) static void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) { - dumb_ptr<mob_data> md, tmd = NULL; - dumb_ptr<map_session_data> tsd = NULL; - dumb_ptr<block_list> tbl = NULL; + dumb_ptr<mob_data> md, tmd = nullptr; + dumb_ptr<map_session_data> tsd = nullptr; + dumb_ptr<block_list> tbl = nullptr; dumb_ptr<flooritem_data> fitem; int i, dx, dy, ret, dist; int attack_type = 0; @@ -1763,7 +1771,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) return; md->last_thinktime = tick; - if (md->skilltimer || md->bl_prev == NULL) + if (md->skilltimer || md->bl_prev == nullptr) { // Under a skill aria and death if (tick > md->next_walktime + MIN_MOBTHINKTIME) @@ -1772,20 +1780,20 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) } if (md->mode == MobMode::ZERO) - mode = mob_db[md->mob_class].mode; + mode = get_mob_db(md->mob_class).mode; else mode = md->mode; - Race race = mob_db[md->mob_class].race; + Race race = get_mob_db(md->mob_class).race; // Abnormalities if (bool(md->opt1) && md->opt1 != Opt1::_stone6) return; - if (!bool(mode & MobMode::CAN_ATTACK) && md->target_id > 0) - md->target_id = 0; + if (!bool(mode & MobMode::CAN_ATTACK) && md->target_id) + md->target_id = BlockId(); - if (md->attacked_id > 0 && bool(mode & MobMode::ASSIST)) + if (md->attacked_id && bool(mode & MobMode::ASSIST)) { // Link monster dumb_ptr<map_session_data> asd = map_id2sd(md->attacked_id); if (asd) @@ -1802,28 +1810,28 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) } // It checks to see it was attacked first (if active, it is target change at 25% of probability). - if (mode != MobMode::ZERO && md->attacked_id > 0 + if (mode != MobMode::ZERO && md->attacked_id && (!md->target_id || !md->state.attackable || (bool(mode & MobMode::AGGRESSIVE) && random_::chance({25, 100})))) { dumb_ptr<block_list> abl = map_id2bl(md->attacked_id); - dumb_ptr<map_session_data> asd = NULL; + dumb_ptr<map_session_data> asd = nullptr; if (abl) { if (abl->bl_type == BL::PC) asd = abl->is_player(); - if (asd == NULL || md->bl_m != abl->bl_m || abl->bl_prev == NULL + if (asd == nullptr || md->bl_m != abl->bl_m || abl->bl_prev == nullptr || asd->invincible_timer || pc_isinvisible(asd) || (dist = distance(md->bl_x, md->bl_y, abl->bl_x, abl->bl_y)) >= 32 || battle_check_target(bl, abl, BCT_ENEMY) == 0) - md->attacked_id = 0; + md->attacked_id = BlockId(); else { md->target_id = md->attacked_id; // set target md->state.attackable = true; attack_type = 1; - md->attacked_id = 0; + md->attacked_id = BlockId(); md->min_chase = dist + 13; if (md->min_chase > 26) md->min_chase = 26; @@ -1833,7 +1841,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) md->state.master_check = 0; // Processing of slave monster - if (md->master_id > 0 && md->state.special_mob_ai == 0) + if (md->master_id && md->state.special_mob_ai == 0) mob_ai_sub_hard_slavemob(md, tick); // アクティヴモンスターの策敵 (?? of a bitter taste TIVU monster) @@ -1874,7 +1882,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) } // It will attack, if the candidate for an attack is. - if (md->target_id > 0) + if (md->target_id) { if ((tbl = map_id2bl(md->target_id))) { @@ -1884,7 +1892,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) tmd = tbl->is_mob(); if (tsd || tmd) { - if (tbl->bl_m != md->bl_m || tbl->bl_prev == NULL + if (tbl->bl_m != md->bl_m || tbl->bl_prev == nullptr || (dist = distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y)) >= md->min_chase) @@ -1894,7 +1902,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) && race != Race::_insect && race != Race::_demon)) mob_unlocktarget(md, tick); // スキルなどによる策敵妨害 - else if (!battle_check_range(md, tbl, mob_db[md->mob_class].range)) + else if (!battle_check_range(md, tbl, get_mob_db(md->mob_class).range)) { // 攻撃範囲外なので移動 if (!bool(mode & MobMode::CAN_MOVE)) @@ -1915,7 +1923,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) else { // 追跡 - md->next_walktime = tick + std::chrono::milliseconds(500); + md->next_walktime = tick + 500_ms; i = 0; do { @@ -1973,11 +1981,11 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) } else { // ルートモンスター処理 - if (tbl == NULL || tbl->bl_type != BL::ITEM || tbl->bl_m != md->bl_m + if (tbl == nullptr || tbl->bl_type != BL::ITEM || tbl->bl_m != md->bl_m || (dist = distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y)) >= md->min_chase - || !bool(mob_db[md->mob_class].mode & MobMode::LOOTER)) + || !bool(get_mob_db(md->mob_class).mode & MobMode::LOOTER)) { // 遠すぎるかアイテムがなくなった mob_unlocktarget(md, tick); @@ -1999,7 +2007,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) && (md->next_walktime < tick || distance(md->to_x, md->to_y, tbl->bl_x, tbl->bl_y) <= 0)) return; // 既に移動中 - md->next_walktime = tick + std::chrono::milliseconds(500); + md->next_walktime = tick + 500_ms; dx = tbl->bl_x - md->bl_x; dy = tbl->bl_y - md->bl_y; ret = mob_walktoxy(md, md->bl_x + dx, md->bl_y + dy, 0); @@ -2036,16 +2044,16 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick) // mobs that are not slaves can random-walk if (bool(mode & MobMode::CAN_MOVE) && mob_can_move(md) - && (md->master_id == 0 || md->state.special_mob_ai + && (!md->master_id || md->state.special_mob_ai || md->master_dist > 10)) { // if walktime is more than 7 seconds in the future, // set it to somewhere between 3 and 5 seconds - if (md->next_walktime > tick + std::chrono::seconds(7) + if (md->next_walktime > tick + 7_s && (md->walkpath.path_len == 0 || md->walkpath.path_pos >= md->walkpath.path_len)) { - md->next_walktime = tick + std::chrono::seconds(3) + md->next_walktime = tick + 3_s + std::chrono::milliseconds(random_::to(2000)); } @@ -2104,7 +2112,7 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick) return; md->last_thinktime = tick; - if (md->bl_prev == NULL || md->skilltimer) + if (md->bl_prev == nullptr || md->skilltimer) { if (tick > md->next_walktime + MIN_MOBTHINKTIME * 10) md->next_walktime = tick; @@ -2112,7 +2120,7 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick) } if (md->next_walktime < tick - && bool(mob_db[md->mob_class].mode & MobMode::CAN_MOVE) + && bool(get_mob_db(md->mob_class).mode & MobMode::CAN_MOVE) && mob_can_move(md)) { @@ -2127,8 +2135,8 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick) // MOB which is not not the summons MOB but BOSS, either sometimes reboils. else if (random_::chance(MOB_LAZYWARPPERC) && md->spawn.x0 <= 0 - && md->master_id != 0 - && !bool(mob_db[md->mob_class].mode & MobMode::BOSS)) + && md->master_id + && !bool(get_mob_db(md->mob_class).mode & MobMode::BOSS)) mob_spawn(md->bl_id); } @@ -2139,12 +2147,12 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick) // MOB which is not BOSS which is not Summons MOB, either -- a case -- sometimes -- leaping if (random_::chance(MOB_LAZYWARPPERC) && md->spawn.x0 <= 0 - && md->master_id != 0 - && !bool(mob_db[md->mob_class].mode & MobMode::BOSS)) + && md->master_id + && !bool(get_mob_db(md->mob_class).mode & MobMode::BOSS)) mob_warp(md, nullptr, -1, -1, BeingRemoveWhy::NEGATIVE1); } - md->next_walktime = tick + std::chrono::seconds(5) + std::chrono::milliseconds(random_::to(10 * 1000)); + md->next_walktime = tick + 5_s + std::chrono::milliseconds(random_::to(10 * 1000)); } } @@ -2169,7 +2177,8 @@ struct delay_item_drop { map_local *m; int x, y; - int nameid, amount; + ItemNameId nameid; + int amount; dumb_ptr<map_session_data> first_sd, second_sd, third_sd; }; @@ -2177,7 +2186,7 @@ struct delay_item_drop2 { map_local *m; int x, y; - struct item item_data; + Item item_data; dumb_ptr<map_session_data> first_sd, second_sd, third_sd; }; @@ -2188,7 +2197,7 @@ struct delay_item_drop2 static void mob_delay_item_drop(TimerData *, tick_t, struct delay_item_drop ditem) { - struct item temp_item {}; + Item temp_item {}; PickupFail flag; temp_item.nameid = ditem.nameid; @@ -2201,7 +2210,7 @@ void mob_delay_item_drop(TimerData *, tick_t, struct delay_item_drop ditem) pc_additem(ditem.first_sd, &temp_item, ditem.amount)) != PickupFail::OKAY) { - clif_additem(ditem.first_sd, 0, 0, flag); + clif_additem(ditem.first_sd, IOff0::from(0), 0, flag); map_addflooritem(&temp_item, 1, ditem.m, ditem.x, ditem.y, ditem.first_sd, ditem.second_sd, ditem.third_sd); @@ -2231,7 +2240,7 @@ void mob_delay_item_drop2(TimerData *, tick_t, struct delay_item_drop2 ditem) ditem.item_data.amount)) != PickupFail::OKAY) { - clif_additem(ditem.first_sd, 0, 0, flag); + clif_additem(ditem.first_sd, IOff0::from(0), 0, flag); map_addflooritem(&ditem.item_data, ditem.item_data.amount, ditem.m, ditem.x, ditem.y, ditem.first_sd, ditem.second_sd, ditem.third_sd); @@ -2252,7 +2261,7 @@ int mob_delete(dumb_ptr<mob_data> md) { nullpo_retr(1, md); - if (md->bl_prev == NULL) + if (md->bl_prev == nullptr) return 1; mob_changestate(md, MS::DEAD, 0); clif_clearchar(md, BeingRemoveWhy::DEAD); @@ -2266,7 +2275,7 @@ int mob_catch_delete(dumb_ptr<mob_data> md, BeingRemoveWhy type) { nullpo_retr(1, md); - if (md->bl_prev == NULL) + if (md->bl_prev == nullptr) return 1; mob_changestate(md, MS::DEAD, 0); clif_clearchar(md, type); @@ -2275,7 +2284,7 @@ int mob_catch_delete(dumb_ptr<mob_data> md, BeingRemoveWhy type) return 0; } -void mob_timer_delete(TimerData *, tick_t, int id) +void mob_timer_delete(TimerData *, tick_t, BlockId id) { dumb_ptr<block_list> bl = map_id2bl(id); dumb_ptr<mob_data> md; @@ -2291,15 +2300,15 @@ void mob_timer_delete(TimerData *, tick_t, int id) *------------------------------------------ */ static -void mob_deleteslave_sub(dumb_ptr<block_list> bl, int id) +void mob_deleteslave_sub(dumb_ptr<block_list> bl, BlockId id) { dumb_ptr<mob_data> md; nullpo_retv(bl); md = bl->is_mob(); - if (md->master_id > 0 && md->master_id == id) - mob_damage(NULL, md, md->hp, 1); + if (md->master_id && md->master_id == id) + mob_damage(nullptr, md, md->hp, 1); } /*========================================== @@ -2308,7 +2317,7 @@ void mob_deleteslave_sub(dumb_ptr<block_list> bl, int id) */ int mob_deleteslave(dumb_ptr<mob_data> md) { - nullpo_ret(md); + nullpo_retz(md); map_foreachinarea(std::bind(mob_deleteslave_sub, ph::_1, md->bl_id), md->bl_m, @@ -2333,18 +2342,18 @@ double damage_bonus_factor[DAMAGE_BONUS_COUNT + 1] = int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, int type) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; int max_hp; tick_t tick = gettick(); - dumb_ptr<map_session_data> mvp_sd = NULL, second_sd = NULL, third_sd = NULL; + dumb_ptr<map_session_data> mvp_sd = nullptr, second_sd = nullptr, third_sd = nullptr; - nullpo_ret(md); //srcはNULLで呼ばれる場合もあるので、他でチェック + nullpo_retz(md); //srcはNULLで呼ばれる場合もあるので、他でチェック if (src && src->bl_id == md->master_id && bool(md->mode & MobMode::TURNS_AGAINST_BAD_MASTER)) { /* If the master hits a monster, have the monster turn against him */ - md->master_id = 0; + md->master_id = BlockId(); md->mode = MobMode::war; /* Regular war mode */ md->target_id = src->bl_id; md->attacked_id = src->bl_id; @@ -2358,18 +2367,16 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, mvp_sd = sd; } -// if(battle_config.battle_log) -// PRINTF("mob_damage %d %d %d\n",md->hp,max_hp,damage); - if (md->bl_prev == NULL) + if (md->bl_prev == nullptr) { if (battle_config.error_log == 1) - PRINTF("mob_damage : BlockError!!\n"); + PRINTF("mob_damage : BlockError!!\n"_fmt); return 0; } if (md->state.state == MS::DEAD || md->hp <= 0) { - if (md->bl_prev != NULL) + if (md->bl_prev != nullptr) { mob_changestate(md, MS::DEAD, 0); // It is skill at the time of death. @@ -2395,7 +2402,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, if (!(type & 2)) { - if (sd != NULL) + if (sd != nullptr) { for (mob_data::DmgLogEntry& dle : md->dmglogv) { @@ -2414,7 +2421,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, } damage_logged_pc: - if (md->attacked_id <= 0 && md->state.special_mob_ai == 0) + if (!md->attacked_id && md->state.special_mob_ai == 0) md->attacked_id = sd->bl_id; } if (src && src->bl_type == BL::MOB @@ -2425,12 +2432,12 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, if (master_bl && master_bl->bl_type == BL::PC) { MAP_LOG_PC(master_bl->is_player(), - "MOB-TO-MOB-DMG FROM MOB%d %d TO MOB%d %d FOR %d", - md2->bl_id, md2->mob_class, md->bl_id, md->mob_class, - damage); + "MOB-TO-MOB-DMG FROM MOB%d %d TO MOB%d %d FOR %d"_fmt, + md2->bl_id, md2->mob_class, md->bl_id, md->mob_class, + damage); } - nullpo_ret(md2); + nullpo_retz(md2); for (mob_data::DmgLogEntry& dle : md->dmglogv) { if (dle.id == md2->master_id) @@ -2446,7 +2453,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, app.dmg = damage; md->dmglogv.push_back(app); - if (md->attacked_id <= 0 && md->state.special_mob_ai == 0) + if (!md->attacked_id && md->state.special_mob_ai == 0) md->attacked_id = md2->master_id; } damage_logged_slave: @@ -2461,7 +2468,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, return 0; } - MAP_LOG("MOB%d DEAD", md->bl_id); + MAP_LOG("MOB%d DEAD"_fmt, md->bl_id); // ----- ここから死亡処理 ----- @@ -2491,7 +2498,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, { struct DmgLogParty { - struct party *p; + PartyPair p; int base_exp, job_exp; }; std::vector<DmgLogParty> ptv; @@ -2501,7 +2508,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, { dumb_ptr<map_session_data> tmpsdi = map_id2sd(dle.id); int tmpdmg = dle.dmg; - if (tmpsdi == NULL) + if (tmpsdi == nullptr) continue; if (tmpsdi->bl_m != md->bl_m || pc_isdead(tmpsdi)) continue; @@ -2532,7 +2539,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, int base_exp, job_exp, flag = 1; double per; - struct party *p; + PartyPair p; // [Fate] The above is the old formula. We do a more involved computation below. // [o11c] Look in git history for old code, you idiot! @@ -2548,23 +2555,23 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, per = 1; base_exp = - ((mob_db[md->mob_class].base_exp * + ((get_mob_db(md->mob_class).base_exp * md->stats[mob_stat::XP_BONUS]) >> MOB_XP_BONUS_SHIFT) * per / 256; if (base_exp < 1) base_exp = 1; if (sd && md && battle_config.pk_mode == 1 - && (mob_db[md->mob_class].lv - sd->status.base_level >= 20)) + && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20)) { base_exp *= 1.15; // pk_mode additional exp if monster >20 levels [Valaris] } if (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1) base_exp = 0; // Added [Valaris] - job_exp = mob_db[md->mob_class].job_exp * per / 256; + job_exp = get_mob_db(md->mob_class).job_exp * per / 256; if (job_exp < 1) job_exp = 1; if (sd && md && battle_config.pk_mode == 1 - && (mob_db[md->mob_class].lv - sd->status.base_level >= 20)) + && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20)) { job_exp *= 1.15; // pk_mode additional exp if monster >20 levels [Valaris] } @@ -2572,19 +2579,19 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, && battle_config.alchemist_summon_reward != 1) job_exp = 0; // Added [Valaris] - int pid = tmpsdi->status.party_id; - if (pid > 0) + PartyId pid = tmpsdi->status.party_id; + if (pid) { std::vector<DmgLogParty>::iterator it = std::find_if(ptv.begin(), ptv.end(), [pid](const DmgLogParty& dlp) { - return dlp.p->party_id == pid; + return dlp.p.party_id == pid; } ); if (it == ptv.end()) { p = party_search(pid); - if (p != NULL && p->exp != 0) + if (p && p->exp != 0) { DmgLogParty pn {}; pn.p = p; @@ -2617,19 +2624,19 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, if (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1) // Added [Valaris] break; // End - if (mob_db[md->mob_class].dropitem[i].nameid <= 0) + if (!get_mob_db(md->mob_class).dropitem[i].nameid) continue; - random_::Fixed<int, 10000> drop_rate = mob_db[md->mob_class].dropitem[i].p; + random_::Fixed<int, 10000> drop_rate = get_mob_db(md->mob_class).dropitem[i].p; if (battle_config.drops_by_luk > 0 && sd && md) drop_rate.num += (sd->status.attrs[ATTR::LUK] * battle_config.drops_by_luk) / 100; // drops affected by luk [Valaris] if (sd && md && battle_config.pk_mode == 1 - && (mob_db[md->mob_class].lv - sd->status.base_level >= 20)) + && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20)) drop_rate.num *= 1.25; // pk_mode increase drops if 20 level difference [Valaris] if (!random_::chance(drop_rate)) continue; struct delay_item_drop ditem {}; - ditem.nameid = mob_db[md->mob_class].dropitem[i].nameid; + ditem.nameid = get_mob_db(md->mob_class).dropitem[i].nameid; ditem.amount = 1; ditem.m = md->bl_m; ditem.x = md->bl_x; @@ -2637,14 +2644,14 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, ditem.first_sd = mvp_sd; ditem.second_sd = second_sd; ditem.third_sd = third_sd; - Timer(tick + std::chrono::milliseconds(500) + static_cast<interval_t>(i), + Timer(tick + 500_ms + static_cast<interval_t>(i), std::bind(mob_delay_item_drop, ph::_1, ph::_2, ditem) ).detach(); } { int i = 0; - for (struct item lit : md->lootitemv) + for (Item lit : md->lootitemv) { struct delay_item_drop2 ditem {}; ditem.item_data = lit; @@ -2655,7 +2662,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, ditem.second_sd = second_sd; ditem.third_sd = third_sd; // ? - Timer(tick + std::chrono::milliseconds(540) + static_cast<interval_t>(i), + Timer(tick + 540_ms + static_cast<interval_t>(i), std::bind(mob_delay_item_drop2, ph::_1, ph::_2, ditem) ).detach(); @@ -2668,9 +2675,9 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, // SCRIPT実行 if (md->npc_event) { - if (sd == NULL) + if (sd == nullptr) { - if (mvp_sd != NULL) + if (mvp_sd != nullptr) sd = mvp_sd; else { @@ -2711,7 +2718,7 @@ int mob_heal(dumb_ptr<mob_data> md, int heal) { int max_hp = battle_get_max_hp(md); - nullpo_ret(md); + nullpo_retz(md); md->hp += heal; if (max_hp < md->hp) @@ -2725,7 +2732,7 @@ int mob_heal(dumb_ptr<mob_data> md, int heal) *------------------------------------------ */ static -void mob_warpslave_sub(dumb_ptr<block_list> bl, int id, int x, int y) +void mob_warpslave_sub(dumb_ptr<block_list> bl, BlockId id, int x, int y) { dumb_ptr<mob_data> md = bl->is_mob(); @@ -2742,7 +2749,6 @@ void mob_warpslave_sub(dumb_ptr<block_list> bl, int id, int x, int y) static int mob_warpslave(dumb_ptr<mob_data> md, int x, int y) { -//PRINTF("warp slave\n"); map_foreachinarea(std::bind(mob_warpslave_sub, ph::_1, md->bl_id, md->bl_x, md->bl_y), md->bl_m, x - AREA_SIZE, y - AREA_SIZE, @@ -2759,9 +2765,9 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t { int i = 0, xs = 0, ys = 0, bx = x, by = y; - nullpo_ret(md); + nullpo_retz(md); - if (md->bl_prev == NULL) + if (md->bl_prev == nullptr) return 0; if (m == nullptr) @@ -2808,12 +2814,12 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t else { if (battle_config.error_log == 1) - PRINTF("MOB %d warp failed, mob_class = %d\n", md->bl_id, md->mob_class); + PRINTF("MOB %d warp failed, mob_class = %d\n"_fmt, md->bl_id, md->mob_class); } - md->target_id = 0; // タゲを解除する + md->target_id = BlockId(); // タゲを解除する md->state.attackable = false; - md->attacked_id = 0; + md->attacked_id = BlockId(); md->state.skillstate = MobSkillState::MSS_IDLE; mob_changestate(md, MS::IDLE, 0); @@ -2821,7 +2827,7 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t && i == 1000) { if (battle_config.battle_log == 1) - PRINTF("MOB %d warp to (%d,%d), mob_class = %d\n", md->bl_id, x, y, + PRINTF("MOB %d warp to (%d,%d), mob_class = %d\n"_fmt, md->bl_id, x, y, md->mob_class); } @@ -2840,7 +2846,7 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t *------------------------------------------ */ static -void mob_countslave_sub(dumb_ptr<block_list> bl, int id, int *c) +void mob_countslave_sub(dumb_ptr<block_list> bl, BlockId id, int *c) { dumb_ptr<mob_data> md; @@ -2860,7 +2866,7 @@ int mob_countslave(dumb_ptr<mob_data> md) { int c = 0; - nullpo_ret(md); + nullpo_retz(md); map_foreachinarea(std::bind(mob_countslave_sub, ph::_1, md->bl_id, &c), md->bl_m, @@ -2874,36 +2880,38 @@ int mob_countslave(dumb_ptr<mob_data> md) * 手下MOB召喚 *------------------------------------------ */ -int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag) +int mob_summonslave(dumb_ptr<mob_data> md2, int *value_, int amount, int flag) { dumb_ptr<mob_data> md; - int bx, by, count = 0, mob_class, k, a = amount; + int bx, by, count = 0, a = amount; - nullpo_ret(md2); - nullpo_ret(value); + nullpo_retz(md2); + nullpo_retz(value_); bx = md2->bl_x; by = md2->bl_y; map_local *m = md2->bl_m; - if (value[0] <= 1000 || value[0] > 2000) // 値が異常なら召喚を止める - return 0; - while (count < 5 && value[count] > 1000 && value[count] <= 2000) - count++; + Species values[5]; + for (count = 0; count < 5 && values[count] != Species(); ++count) + values[count] = wrap<Species>(value_[count]); if (count < 1) return 0; - for (k = 0; k < count; k++) + for (int k = 0; k < count; k++) { amount = a; - mob_class = value[k]; - if (mob_class <= 1000 || mob_class > 2000) + Species mob_class = values[k]; + if (mobdb_checkid(mob_class) == Species()) + { + PRINTF("Warning: bad slave class %u\n"_fmt, mob_class); continue; + } for (; amount > 0; amount--) { int x = 0, y = 0, i = 0; md.new_(); - if (bool(mob_db[mob_class].mode & MobMode::LOOTER)) + if (bool(get_mob_db(mob_class).mode & MobMode::LOOTER)) md->lootitemv.clear(); while ((x <= 0 @@ -2921,8 +2929,8 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag) } mob_spawn_dataset(md, JAPANESE_NAME, mob_class); - md->bl_prev = NULL; - md->bl_next = NULL; + md->bl_prev = nullptr; + md->bl_next = nullptr; md->bl_m = m; md->bl_x = x; md->bl_y = y; @@ -2954,7 +2962,7 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag) */ static void mob_counttargeted_sub(dumb_ptr<block_list> bl, - int id, int *c, dumb_ptr<block_list> src, ATK target_lv) + BlockId id, int *c, dumb_ptr<block_list> src, ATK target_lv) { nullpo_retv(bl); nullpo_retv(c); @@ -2986,7 +2994,7 @@ int mob_counttargeted(dumb_ptr<mob_data> md, dumb_ptr<block_list> src, { int c = 0; - nullpo_ret(md); + nullpo_retz(md); map_foreachinarea(std::bind(mob_counttargeted_sub, ph::_1, md->bl_id, &c, src, target_lv), md->bl_m, @@ -3004,21 +3012,21 @@ int mob_counttargeted(dumb_ptr<mob_data> md, dumb_ptr<block_list> src, * スキル使用(詠唱完了、ID指定) *------------------------------------------ */ -void mobskill_castend_id(TimerData *, tick_t tick, int id) +void mobskill_castend_id(TimerData *, tick_t tick, BlockId id) { - dumb_ptr<mob_data> md = NULL; + dumb_ptr<mob_data> md = nullptr; dumb_ptr<block_list> bl; dumb_ptr<block_list> mbl; int range; - if ((mbl = map_id2bl(id)) == NULL) //詠唱したMobがもういないというのは良くある正常処理 + if ((mbl = map_id2bl(id)) == nullptr) //詠唱したMobがもういないというのは良くある正常処理 return; - if ((md = mbl->is_mob()) == NULL) + if ((md = mbl->is_mob()) == nullptr) { - PRINTF("mobskill_castend_id nullpo mbl->bl_id:%d\n", mbl->bl_id); + PRINTF("mobskill_castend_id nullpo mbl->bl_id:%d\n"_fmt, mbl->bl_id); return; } - if (md->bl_type != BL::MOB || md->bl_prev == NULL) + if (md->bl_type != BL::MOB || md->bl_prev == nullptr) return; if (bool(md->opt1)) @@ -3027,9 +3035,8 @@ void mobskill_castend_id(TimerData *, tick_t tick, int id) if (md->skillid != SkillID::NPC_EMOTION) md->last_thinktime = tick + battle_get_adelay(md); - if ((bl = map_id2bl(md->skilltarget)) == NULL || bl->bl_prev == NULL) + if ((bl = map_id2bl(md->skilltarget)) == nullptr || bl->bl_prev == nullptr) { //スキルターゲットが存在しない - //PRINTF("mobskill_castend_id nullpo\n");//ターゲットがいないときはnullpoじゃなくて普通に終了 return; } if (md->bl_m != bl->bl_m) @@ -3044,10 +3051,10 @@ void mobskill_castend_id(TimerData *, tick_t tick, int id) if (range + battle_config.monster_skill_add_range < distance(md->bl_x, md->bl_y, bl->bl_x, bl->bl_y)) return; - md->skilldelayup[md->skillidx - &mob_db[md->mob_class].skills.front()] = tick; + md->skilldelayup[md->skillidx - &get_mob_db(md->mob_class).skills.front()] = tick; if (battle_config.monster_skill_log == 1) - PRINTF("MOB skill castend skill=%d, mob_class = %d\n", + PRINTF("MOB skill castend skill=%d, mob_class = %d\n"_fmt, md->skillid, md->mob_class); mob_stop_walking(md, 0); @@ -3071,20 +3078,20 @@ void mobskill_castend_id(TimerData *, tick_t tick, int id) * スキル使用(詠唱完了、場所指定) *------------------------------------------ */ -void mobskill_castend_pos(TimerData *, tick_t tick, int id) +void mobskill_castend_pos(TimerData *, tick_t tick, BlockId id) { - dumb_ptr<mob_data> md = NULL; + dumb_ptr<mob_data> md = nullptr; dumb_ptr<block_list> bl; int range; //mobskill_castend_id同様詠唱したMobが詠唱完了時にもういないというのはありそうなのでnullpoから除外 - if ((bl = map_id2bl(id)) == NULL) + if ((bl = map_id2bl(id)) == nullptr) return; md = bl->is_mob(); nullpo_retv(md); - if (md->bl_type != BL::MOB || md->bl_prev == NULL) + if (md->bl_type != BL::MOB || md->bl_prev == nullptr) return; if (bool(md->opt1)) @@ -3095,10 +3102,10 @@ void mobskill_castend_pos(TimerData *, tick_t tick, int id) range = battle_get_range(md) - (range + 1); if (range + battle_config.monster_skill_add_range < distance(md->bl_x, md->bl_y, md->skillx, md->skilly)) return; - md->skilldelayup[md->skillidx - &mob_db[md->mob_class].skills.front()] = tick; + md->skilldelayup[md->skillidx - &get_mob_db(md->mob_class).skills.front()] = tick; if (battle_config.monster_skill_log == 1) - PRINTF("MOB skill castend skill=%d, mob_class = %d\n", + PRINTF("MOB skill castend skill=%d, mob_class = %d\n"_fmt, md->skillid, md->mob_class); mob_stop_walking(md, 0); } @@ -3115,13 +3122,13 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target, SkillID skill_id; int skill_lv; - nullpo_ret(md); + nullpo_retz(md); ms = &skill_idx; - if (target == NULL && (target = map_id2bl(md->target_id)) == NULL) + if (target == nullptr && (target = map_id2bl(md->target_id)) == nullptr) return 0; - if (target->bl_prev == NULL || md->bl_prev == NULL) + if (target->bl_prev == nullptr || md->bl_prev == nullptr) return 0; skill_id = ms->skill_id; @@ -3145,10 +3152,10 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target, interval_t casttime = skill_castfix(md, ms->casttime); md->state.skillcastcancel = ms->cancel; - md->skilldelayup[ms - &mob_db[md->mob_class].skills.front()] = gettick(); + md->skilldelayup[ms - &get_mob_db(md->mob_class).skills.front()] = gettick(); if (battle_config.monster_skill_log == 1) - PRINTF("MOB skill use target_id=%d skill=%d lv=%d cast=%d, mob_class = %d\n", + PRINTF("MOB skill use target_id=%d skill=%d lv=%d cast=%d, mob_class = %d\n"_fmt, target->bl_id, skill_id, skill_lv, static_cast<uint32_t>(casttime.count()), md->mob_class); @@ -3190,10 +3197,10 @@ int mobskill_use_pos(dumb_ptr<mob_data> md, struct block_list bl; int skill_lv; - nullpo_ret(md); + nullpo_retz(md); ms = &skill_idx; - if (md->bl_prev == NULL) + if (md->bl_prev == nullptr) return 0; SkillID skill_id = ms->skill_id; @@ -3215,13 +3222,13 @@ int mobskill_use_pos(dumb_ptr<mob_data> md, // delay=skill_delayfix(sd, skill_get_delay( skill_id,skill_lv) ); interval_t casttime = skill_castfix(md, ms->casttime); - md->skilldelayup[ms - &mob_db[md->mob_class].skills.front()] = gettick(); + md->skilldelayup[ms - &get_mob_db(md->mob_class).skills.front()] = gettick(); md->state.skillcastcancel = ms->cancel; if (battle_config.monster_skill_log == 1) - PRINTF("MOB skill use target_pos= (%d,%d) skill=%d lv=%d cast=%d, mob_class = %d\n", - skill_x, skill_y, skill_id, skill_lv, - static_cast<uint32_t>(casttime.count()), md->mob_class); + PRINTF("MOB skill use target_pos= (%d,%d) skill=%d lv=%d cast=%d, mob_class = %d\n"_fmt, + skill_x, skill_y, skill_id, skill_lv, + static_cast<uint32_t>(casttime.count()), md->mob_class); if (casttime <= interval_t::zero()) // A skill without a cast time wont be cancelled. @@ -3229,7 +3236,7 @@ int mobskill_use_pos(dumb_ptr<mob_data> md, md->skillx = skill_x; md->skilly = skill_y; - md->skilltarget = 0; + md->skilltarget = BlockId(); md->skillid = skill_id; md->skilllv = skill_lv; md->skillidx = &skill_idx; @@ -3257,8 +3264,8 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick, { int max_hp; - nullpo_ret(md); - std::vector<mob_skill>& ms = mob_db[md->mob_class].skills; + nullpo_retz(md); + std::vector<mob_skill>& ms = get_mob_db(md->mob_class).skills; max_hp = battle_get_max_hp(md); @@ -3312,7 +3319,7 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick, if (skill_get_inf(msii.skill_id) & 2) { // 場所指定 - dumb_ptr<block_list> bl = NULL; + dumb_ptr<block_list> bl = nullptr; int x = 0, y = 0; { if (msii.target == MobSkillTarget::MST_TARGET) @@ -3334,7 +3341,7 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick, else { { - dumb_ptr<block_list> bl = NULL; + dumb_ptr<block_list> bl = nullptr; if (msii.target == MobSkillTarget::MST_TARGET) bl = map_id2bl(md->target_id); else @@ -3358,7 +3365,7 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick, */ int mobskill_event(dumb_ptr<mob_data> md, BF flag) { - nullpo_ret(md); + nullpo_retz(md); if (flag == BF::NEGATIVE_1 && mobskill_use(md, gettick(), MobSkillCondition::ANY)) @@ -3380,42 +3387,42 @@ int mobskill_event(dumb_ptr<mob_data> md, BF flag) *------------------------------------------ */ static -int mob_makedummymobdb(int mob_class) +int mob_makedummymobdb(Species mob_class) { int i; - SNPRINTF(mob_db[mob_class].name, 24, "mob%d", mob_class); - SNPRINTF(mob_db[mob_class].jname, 24, "mob%d", mob_class); - mob_db[mob_class].lv = 1; - mob_db[mob_class].max_hp = 1000; - mob_db[mob_class].max_sp = 1; - mob_db[mob_class].base_exp = 2; - mob_db[mob_class].job_exp = 1; - mob_db[mob_class].range = 1; - mob_db[mob_class].atk1 = 7; - mob_db[mob_class].atk2 = 10; - mob_db[mob_class].def = 0; - mob_db[mob_class].mdef = 0; - mob_db[mob_class].attrs[ATTR::STR] = 1; - mob_db[mob_class].attrs[ATTR::AGI] = 1; - mob_db[mob_class].attrs[ATTR::VIT] = 1; - mob_db[mob_class].attrs[ATTR::INT] = 1; - mob_db[mob_class].attrs[ATTR::DEX] = 6; - mob_db[mob_class].attrs[ATTR::LUK] = 2; - mob_db[mob_class].range2 = 10; - mob_db[mob_class].range3 = 10; - mob_db[mob_class].size = 0; // 1 - mob_db[mob_class].race = Race::formless; - mob_db[mob_class].element = LevelElement{0, Element::neutral}; - mob_db[mob_class].mode = MobMode::ZERO; - mob_db[mob_class].speed = 300; - mob_db[mob_class].adelay = 1000; - mob_db[mob_class].amotion = 500; - mob_db[mob_class].dmotion = 500; + SNPRINTF(get_mob_db(mob_class).name, 24, "mob%d"_fmt, mob_class); + SNPRINTF(get_mob_db(mob_class).jname, 24, "mob%d"_fmt, mob_class); + get_mob_db(mob_class).lv = 1; + get_mob_db(mob_class).max_hp = 1000; + get_mob_db(mob_class).max_sp = 1; + get_mob_db(mob_class).base_exp = 2; + get_mob_db(mob_class).job_exp = 1; + get_mob_db(mob_class).range = 1; + get_mob_db(mob_class).atk1 = 7; + get_mob_db(mob_class).atk2 = 10; + get_mob_db(mob_class).def = 0; + get_mob_db(mob_class).mdef = 0; + get_mob_db(mob_class).attrs[ATTR::STR] = 1; + get_mob_db(mob_class).attrs[ATTR::AGI] = 1; + get_mob_db(mob_class).attrs[ATTR::VIT] = 1; + get_mob_db(mob_class).attrs[ATTR::INT] = 1; + get_mob_db(mob_class).attrs[ATTR::DEX] = 6; + get_mob_db(mob_class).attrs[ATTR::LUK] = 2; + get_mob_db(mob_class).range2 = 10; + get_mob_db(mob_class).range3 = 10; + get_mob_db(mob_class).size = 0; // 1 + get_mob_db(mob_class).race = Race::formless; + get_mob_db(mob_class).element = LevelElement{0, Element::neutral}; + get_mob_db(mob_class).mode = MobMode::ZERO; + get_mob_db(mob_class).speed = 300; + get_mob_db(mob_class).adelay = 1000; + get_mob_db(mob_class).amotion = 500; + get_mob_db(mob_class).dmotion = 500; for (i = 0; i < 8; i++) { - mob_db[mob_class].dropitem[i].nameid = 0; - mob_db[mob_class].dropitem[i].p.num = 0; + get_mob_db(mob_class).dropitem[i].nameid = ItemNameId(); + get_mob_db(mob_class).dropitem[i].p.num = 0; } return 0; } @@ -3439,13 +3446,13 @@ bool mob_readdb(ZString filename) io::ReadFile in(filename); if (!in.is_open()) { - PRINTF("Unable to read mob db: %s\n", filename); + PRINTF("Unable to read mob db: %s\n"_fmt, filename); return false; } AString line; while (in.getline(line)) { - int mob_class; + Species mob_class; if (is_comment(line)) continue; @@ -3515,62 +3522,62 @@ bool mob_readdb(ZString filename) ) ); - if (!okay || mob_class <= 1000 || mob_class > 2000) + if (!okay || mobdb_checkid(mob_class) == Species()) { - PRINTF("bad mob line: %s\n", line); + PRINTF("bad mob line: %s\n"_fmt, line); rv = false; continue; } // TODO move this lower - mob_db[mob_class] = std::move(mdbv); + get_mob_db(mob_class) = std::move(mdbv); - if (mob_db[mob_class].base_exp < 0) - mob_db[mob_class].base_exp = 0; - else if (mob_db[mob_class].base_exp > 0 - && (mob_db[mob_class].base_exp * + if (get_mob_db(mob_class).base_exp < 0) + get_mob_db(mob_class).base_exp = 0; + else if (get_mob_db(mob_class).base_exp > 0 + && (get_mob_db(mob_class).base_exp * battle_config.base_exp_rate / 100 > 1000000000 - || mob_db[mob_class].base_exp * + || get_mob_db(mob_class).base_exp * battle_config.base_exp_rate / 100 < 0)) - mob_db[mob_class].base_exp = 1000000000; + get_mob_db(mob_class).base_exp = 1000000000; else - mob_db[mob_class].base_exp = mob_db[mob_class].base_exp * battle_config.base_exp_rate / 100; + get_mob_db(mob_class).base_exp = get_mob_db(mob_class).base_exp * battle_config.base_exp_rate / 100; - if (mob_db[mob_class].job_exp < 0) - mob_db[mob_class].job_exp = 0; - else if (mob_db[mob_class].job_exp > 0 - && (mob_db[mob_class].job_exp * battle_config.job_exp_rate / + if (get_mob_db(mob_class).job_exp < 0) + get_mob_db(mob_class).job_exp = 0; + else if (get_mob_db(mob_class).job_exp > 0 + && (get_mob_db(mob_class).job_exp * battle_config.job_exp_rate / 100 > 1000000000 - || mob_db[mob_class].job_exp * + || get_mob_db(mob_class).job_exp * battle_config.job_exp_rate / 100 < 0)) - mob_db[mob_class].job_exp = 1000000000; + get_mob_db(mob_class).job_exp = 1000000000; else - mob_db[mob_class].job_exp = mob_db[mob_class].job_exp * battle_config.job_exp_rate / 100; + get_mob_db(mob_class).job_exp = get_mob_db(mob_class).job_exp * battle_config.job_exp_rate / 100; for (int i = 0; i < 8; i++) { - int rate = mob_db[mob_class].dropitem[i].p.num; + int rate = get_mob_db(mob_class).dropitem[i].p.num; if (rate < 1) rate = 1; if (rate > 10000) rate = 10000; - mob_db[mob_class].dropitem[i].p.num = rate; + get_mob_db(mob_class).dropitem[i].p.num = rate; } - mob_db[mob_class].skills.clear(); + get_mob_db(mob_class).skills.clear(); - mob_db[mob_class].hair = 0; - mob_db[mob_class].hair_color = 0; - mob_db[mob_class].weapon = 0; - mob_db[mob_class].shield = 0; - mob_db[mob_class].head_top = 0; - mob_db[mob_class].head_mid = 0; - mob_db[mob_class].head_buttom = 0; - mob_db[mob_class].clothes_color = 0; //Add for player monster dye - Valaris + get_mob_db(mob_class).hair = 0; + get_mob_db(mob_class).hair_color = 0; + get_mob_db(mob_class).weapon = 0; + get_mob_db(mob_class).shield = ItemNameId(); + get_mob_db(mob_class).head_top = ItemNameId(); + get_mob_db(mob_class).head_mid = ItemNameId(); + get_mob_db(mob_class).head_buttom = ItemNameId(); + get_mob_db(mob_class).clothes_color = 0; //Add for player monster dye - Valaris - if (mob_db[mob_class].base_exp == 0) - mob_db[mob_class].base_exp = mob_gen_exp(&mob_db[mob_class]); + if (get_mob_db(mob_class).base_exp == 0) + get_mob_db(mob_class).base_exp = mob_gen_exp(&get_mob_db(mob_class)); } - PRINTF("read %s done\n", filename); + PRINTF("read %s done\n"_fmt, filename); } return rv; } @@ -3580,15 +3587,15 @@ bool extract<MobSkillCondition, void, void>(XString str, MobSkillCondition *msc) { const struct { - ZString str; + LString str; MobSkillCondition id; } cond1[] = { - {ZString("always"), MobSkillCondition::MSC_ALWAYS}, - {ZString("myhpltmaxrate"), MobSkillCondition::MSC_MYHPLTMAXRATE}, - {ZString("notintown"), MobSkillCondition::MSC_NOTINTOWN}, - {ZString("slavelt"), MobSkillCondition::MSC_SLAVELT}, - {ZString("slavele"), MobSkillCondition::MSC_SLAVELE}, + {"always"_s, MobSkillCondition::MSC_ALWAYS}, + {"myhpltmaxrate"_s, MobSkillCondition::MSC_MYHPLTMAXRATE}, + {"notintown"_s, MobSkillCondition::MSC_NOTINTOWN}, + {"slavelt"_s, MobSkillCondition::MSC_SLAVELT}, + {"slavele"_s, MobSkillCondition::MSC_SLAVELE}, }; for (auto& pair : cond1) if (str == pair.str) @@ -3604,14 +3611,14 @@ bool extract<MobSkillState, void, void>(XString str, MobSkillState *mss) { const struct { - ZString str; + LString str; MobSkillState id; } state[] = { - {ZString("any"), MobSkillState::ANY}, - {ZString("idle"), MobSkillState::MSS_IDLE}, - {ZString("walk"), MobSkillState::MSS_WALK}, - {ZString("attack"), MobSkillState::MSS_ATTACK}, + {"any"_s, MobSkillState::ANY}, + {"idle"_s, MobSkillState::MSS_IDLE}, + {"walk"_s, MobSkillState::MSS_WALK}, + {"attack"_s, MobSkillState::MSS_ATTACK}, }; for (auto& pair : state) if (str == pair.str) @@ -3627,12 +3634,12 @@ bool extract<MobSkillTarget, void, void>(XString str, MobSkillTarget *mst) { const struct { - ZString str; + LString str; MobSkillTarget id; } target[] = { - {ZString("target"), MobSkillTarget::MST_TARGET}, - {ZString("self"), MobSkillTarget::MST_SELF}, + {"target"_s, MobSkillTarget::MST_TARGET}, + {"self"_s, MobSkillTarget::MST_SELF}, }; for (auto& pair : target) if (str == pair.str) @@ -3650,21 +3657,21 @@ bool mob_readskilldb(ZString filename) io::ReadFile in(filename); if (!in.is_open()) { - PRINTF("can't read %s\n", filename); + PRINTF("can't read %s\n"_fmt, filename); return false; } AString line; while (in.getline(line)) { - int mob_id; + Species mob_id; if (is_comment(line)) continue; XString blah; - if (extract(line, record<','>(&mob_id, &blah)) && mob_id > 0 && blah == "clear") + if (extract(line, record<','>(&mob_id, &blah)) && mobdb_checkid(mob_id) != Species() && blah == "clear"_s) { - mob_db[mob_id].skills.clear(); + get_mob_db(mob_id).skills.clear(); continue; } @@ -3699,9 +3706,9 @@ bool mob_readskilldb(ZString filename) ) ) continue; - if (cancellable == "yes") + if (cancellable == "yes"_s) msv.cancel = true; - else if (cancellable == "no") + else if (cancellable == "no"_s) msv.cancel = false; else { @@ -3712,15 +3719,15 @@ bool mob_readskilldb(ZString filename) msv.casttime = std::chrono::milliseconds(casttime); msv.delay = std::chrono::milliseconds(delay); - if (mob_id <= 0) + if (mobdb_checkid(mob_id) == Species()) { rv = false; continue; } - mob_db[mob_id].skills.push_back(std::move(msv)); + get_mob_db(mob_id).skills.push_back(std::move(msv)); } - PRINTF("read %s done\n", filename); + PRINTF("read %s done\n"_fmt, filename); } return rv; } @@ -3736,3 +3743,4 @@ void do_init_mob2(void) MIN_MOBTHINKTIME * 10 ).detach(); } +} // namespace tmwa diff --git a/src/map/mob.hpp b/src/map/mob.hpp index e7d81bd..d0cc07a 100644 --- a/src/map/mob.hpp +++ b/src/map/mob.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_MOB_HPP -#define TMWA_MAP_MOB_HPP +#pragma once // mob.hpp - Really scary code. // // Copyright © ????-2004 Athena Dev Teams @@ -21,22 +20,27 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "mob.t.hpp" +#include "mob.t.hpp" -# include "../generic/random.t.hpp" +#include "../generic/fwd.hpp" +#include "../generic/enum.hpp" +#include "../generic/random.t.hpp" -# include "../mmo/mmo.hpp" -# include "../mmo/timer.t.hpp" +#include "../net/timer.t.hpp" -# include "clif.t.hpp" -# include "map.hpp" -# include "skill.t.hpp" +#include "battle.t.hpp" +#include "clif.t.hpp" +#include "map.hpp" +#include "skill.t.hpp" -# define ENGLISH_NAME stringish<MobName>("--en--") -# define JAPANESE_NAME stringish<MobName>("--ja--") -# define MOB_THIS_MAP stringish<MapName>("this") + +namespace tmwa +{ +#define ENGLISH_NAME stringish<MobName>("--en--"_s) +#define JAPANESE_NAME stringish<MobName>("--ja--"_s) +#define MOB_THIS_MAP stringish<MapName>("this"_s) struct mob_skill { @@ -72,41 +76,43 @@ struct mob_db_ int mutations_nr, mutation_power; struct { - int nameid; + ItemNameId nameid; random_::Fixed<int, 10000> p; } dropitem[8]; - short hair, hair_color, weapon, shield, head_top, head_mid, head_buttom, option, clothes_color; // [Valaris] + short hair, hair_color, weapon; + ItemNameId shield, head_top, head_mid, head_buttom; + short option, clothes_color; // [Valaris] int equip; // [Valaris] std::vector<struct mob_skill> skills; }; -extern struct mob_db_ mob_db[]; +struct mob_db_& get_mob_db(Species); -int mobdb_searchname(MobName str); -int mobdb_checkid(const int id); -int mob_once_spawn(dumb_ptr<map_session_data> sd, +Species mobdb_searchname(MobName str); +Species mobdb_checkid(Species id); +BlockId mob_once_spawn(dumb_ptr<map_session_data> sd, MapName mapname, int x, int y, - MobName mobname, int class_, int amount, + MobName mobname, Species class_, int amount, NpcEvent event); -int mob_once_spawn_area(dumb_ptr<map_session_data> sd, +BlockId mob_once_spawn_area(dumb_ptr<map_session_data> sd, MapName mapname, int x0, int y0, int x1, int y1, - MobName mobname, int class_, int amount, + MobName mobname, Species class_, int amount, NpcEvent event); int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist); int mob_stop_walking(dumb_ptr<mob_data> md, int type); int mob_stopattack(dumb_ptr<mob_data>); -int mob_spawn(int); +int mob_spawn(BlockId); int mob_damage(dumb_ptr<block_list>, dumb_ptr<mob_data>, int, int); int mob_heal(dumb_ptr<mob_data>, int); -short mob_get_hair(int); -short mob_get_hair_color(int); -short mob_get_weapon(int); -short mob_get_shield(int); -short mob_get_head_top(int); -short mob_get_head_mid(int); -short mob_get_head_buttom(int); -short mob_get_clothes_color(int); //player mob dye [Valaris] -int mob_get_equip(int); // mob equip [Valaris] +short mob_get_hair(Species); +short mob_get_hair_color(Species); +short mob_get_weapon(Species); +ItemNameId mob_get_shield(Species); +ItemNameId mob_get_head_top(Species); +ItemNameId mob_get_head_mid(Species); +ItemNameId mob_get_head_buttom(Species); +short mob_get_clothes_color(Species); //player mob dye [Valaris] +int mob_get_equip(Species); // mob equip [Valaris] bool mob_readdb(ZString filename); bool mob_readskilldb(ZString filename); @@ -114,7 +120,7 @@ void do_init_mob2(void); int mob_delete(dumb_ptr<mob_data> md); int mob_catch_delete(dumb_ptr<mob_data> md, BeingRemoveWhy type); -void mob_timer_delete(TimerData *, tick_t, int); +void mob_timer_delete(TimerData *, tick_t, BlockId); int mob_deleteslave(dumb_ptr<mob_data> md); @@ -125,10 +131,9 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t int mobskill_use(dumb_ptr<mob_data> md, tick_t tick, MobSkillCondition event); int mobskill_event(dumb_ptr<mob_data> md, BF flag); -void mobskill_castend_id(TimerData *tid, tick_t tick, int id); -void mobskill_castend_pos(TimerData *tid, tick_t tick, int id); +void mobskill_castend_id(TimerData *tid, tick_t tick, BlockId id); +void mobskill_castend_pos(TimerData *tid, tick_t tick, BlockId id); int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag); void mob_reload(void); - -#endif // TMWA_MAP_MOB_HPP +} // namespace tmwa diff --git a/src/map/mob.t.hpp b/src/map/mob.t.hpp index 37fd13e..160a8a3 100644 --- a/src/map/mob.t.hpp +++ b/src/map/mob.t.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_MOB_T_HPP -#define TMWA_MAP_MOB_T_HPP +#pragma once // mob.t.hpp - Really scary code. // // Copyright © ????-2004 Athena Dev Teams @@ -21,10 +20,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdint> +#include <cstdint> + +namespace tmwa +{ enum class MobSkillTarget { MST_TARGET = 0, @@ -59,5 +61,4 @@ enum class MobSkillState : uint8_t MSS_LOOT, MSS_CHASE, }; - -#endif // TMWA_MAP_MOB_T_HPP +} // namespace tmwa diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 7fe13f1..a6427d6 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -21,10 +21,9 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include <cassert> -#include <cstdlib> -#include <cstring> #include <ctime> +#include <algorithm> #include <list> #include "../compat/fun.hpp" @@ -34,16 +33,20 @@ #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" +#include "../strings/literal.hpp" #include "../generic/db.hpp" #include "../io/cxxstdio.hpp" #include "../io/read.hpp" +#include "../net/timer.hpp" + #include "../mmo/config_parse.hpp" #include "../mmo/extract.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" +#include "../mmo/utils.hpp" + +#include "../proto2/map-user.hpp" #include "battle.hpp" #include "clif.hpp" @@ -56,17 +59,22 @@ #include "../poison.hpp" + +namespace tmwa +{ static std::list<AString> npc_srcs; static -int npc_id = START_NPC_NUM; +BlockId npc_id = START_NPC_NUM; static int npc_warp, npc_shop, npc_script, npc_mob; -int npc_get_new_npc_id(void) +BlockId npc_get_new_npc_id(void) { - return npc_id++; + BlockId rv = npc_id; + npc_id = next(npc_id); + return rv; } struct event_data @@ -107,7 +115,7 @@ void npc_enable_sub(dumb_ptr<block_list> bl, dumb_ptr<npc_data> nd) NpcEvent aname; aname.npc = nd->name; - aname.label = stringish<ScriptLabel>("OnTouch"); + aname.label = stringish<ScriptLabel>("OnTouch"_s); if (sd->areanpc_id == nd->bl_id) return; sd->areanpc_id = nd->bl_id; @@ -118,9 +126,9 @@ void npc_enable_sub(dumb_ptr<block_list> bl, dumb_ptr<npc_data> nd) int npc_enable(NpcName name, bool flag) { dumb_ptr<npc_data> nd = npc_name2id(name); - if (nd == NULL) + if (nd == nullptr) { - PRINTF("npc_enable(%s, %s) failed.\n", name, flag ? "true" : "false"); + PRINTF("npc_enable(%s, %s) failed.\n"_fmt, name, flag ? "true"_s : "false"_s); return 0; } @@ -167,15 +175,15 @@ dumb_ptr<npc_data> npc_name2id(NpcName name) */ int npc_event_dequeue(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); - sd->npc_id = 0; + sd->npc_id = BlockId(); if (!sd->eventqueuel.empty()) { - if (!pc_addeventtimer(sd, std::chrono::milliseconds(100), sd->eventqueuel.front())) + if (!pc_addeventtimer(sd, 100_ms, sd->eventqueuel.front())) { - PRINTF("npc_event_dequeue(): Event timer is full.\n"); + PRINTF("npc_event_dequeue(): Event timer is full.\n"_fmt); return 0; } @@ -190,7 +198,7 @@ int npc_delete(dumb_ptr<npc_data> nd) { nullpo_retr(1, nd); - if (nd->bl_prev == NULL) + if (nd->bl_prev == nullptr) return 1; clif_clearchar(nd, BeingRemoveWhy::DEAD); @@ -204,9 +212,9 @@ void npc_timer_event(NpcEvent eventname) dumb_ptr<npc_data_script> nd; // int xs,ys; - if ((ev == NULL || (nd = ev->nd) == NULL)) + if ((ev == nullptr || (nd = ev->nd) == nullptr)) { - PRINTF("npc_event: event not found [%s]\n", + PRINTF("npc_event: event not found [%s]\n"_fmt, eventname); return; } @@ -220,7 +228,7 @@ void npc_timer_event(NpcEvent eventname) */ static void npc_event_doall_sub(NpcEvent key, struct event_data *ev, - int *c, ScriptLabel name, int rid, Slice<argrec_t> argv) + int *c, ScriptLabel name, BlockId rid, Slice<argrec_t> argv) { ScriptLabel p = key.label; @@ -234,7 +242,7 @@ void npc_event_doall_sub(NpcEvent key, struct event_data *ev, } } -int npc_event_doall_l(ScriptLabel name, int rid, Slice<argrec_t> args) +int npc_event_doall_l(ScriptLabel name, BlockId rid, Slice<argrec_t> args) { int c = 0; @@ -245,7 +253,7 @@ int npc_event_doall_l(ScriptLabel name, int rid, Slice<argrec_t> args) static void npc_event_do_sub(NpcEvent key, struct event_data *ev, - int *c, NpcEvent name, int rid, Slice<argrec_t> argv) + int *c, NpcEvent name, BlockId rid, Slice<argrec_t> argv) { nullpo_retv(ev); @@ -257,7 +265,7 @@ void npc_event_do_sub(NpcEvent key, struct event_data *ev, } } -int npc_event_do_l(NpcEvent name, int rid, Slice<argrec_t> args) +int npc_event_do_l(NpcEvent name, BlockId rid, Slice<argrec_t> args) { int c = 0; @@ -283,19 +291,19 @@ void npc_event_do_clock(TimerData *, tick_t) ScriptLabel buf; if (t.tm_min != ev_tm_b.tm_min) { - SNPRINTF(buf, 24, "OnMinute%02d", t.tm_min); + SNPRINTF(buf, 24, "OnMinute%02d"_fmt, t.tm_min); npc_event_doall(buf); - SNPRINTF(buf, 24, "OnClock%02d%02d", t.tm_hour, t.tm_min); + SNPRINTF(buf, 24, "OnClock%02d%02d"_fmt, t.tm_hour, t.tm_min); npc_event_doall(buf); } if (t.tm_hour != ev_tm_b.tm_hour) { - SNPRINTF(buf, 24, "OnHour%02d", t.tm_hour); + SNPRINTF(buf, 24, "OnHour%02d"_fmt, t.tm_hour); npc_event_doall(buf); } if (t.tm_mday != ev_tm_b.tm_mday) { - SNPRINTF(buf, 24, "OnDay%02d%02d", t.tm_mon + 1, t.tm_mday); + SNPRINTF(buf, 24, "OnDay%02d%02d"_fmt, t.tm_mon + 1, t.tm_mday); npc_event_doall(buf); } ev_tm_b = t; @@ -307,12 +315,12 @@ void npc_event_do_clock(TimerData *, tick_t) */ int npc_event_do_oninit(void) { - int c = npc_event_doall(stringish<ScriptLabel>("OnInit")); - PRINTF("npc: OnInit Event done. (%d npc)\n", c); + int c = npc_event_doall(stringish<ScriptLabel>("OnInit"_s)); + PRINTF("npc: OnInit Event done. (%d npc)\n"_fmt, c); - Timer(gettick() + std::chrono::milliseconds(100), + Timer(gettick() + 100_ms, npc_event_do_clock, - std::chrono::seconds(1) + 1_s ).detach(); return 0; @@ -322,10 +330,10 @@ int npc_event_do_oninit(void) /// This will be called later if you call npc_timerevent_start. /// This function may only expire, but not deactivate, the counter. static -void npc_timerevent(TimerData *, tick_t tick, int id, interval_t data) +void npc_timerevent(TimerData *, tick_t tick, BlockId id, interval_t data) { dumb_ptr<npc_data_script> nd = map_id2bl(id)->is_npc()->is_script(); - assert (nd != NULL); + assert (nd != nullptr); assert (nd->npc_subtype == NpcSubtype::SCRIPT); assert (nd->scr.next_event != nd->scr.timer_eventv.end()); @@ -345,7 +353,7 @@ void npc_timerevent(TimerData *, tick_t tick, int id, interval_t data) id, next)); } - run_script(ScriptPointer(nd->scr.script.get(), te->pos), 0, nd->bl_id); + run_script(ScriptPointer(nd->scr.script.get(), te->pos), BlockId(), nd->bl_id); } /// Start (or resume) counting ticks to the next npc_timerevent. @@ -461,15 +469,15 @@ int npc_event(dumb_ptr<map_session_data> sd, NpcEvent eventname, dumb_ptr<npc_data_script> nd; int xs, ys; - if (sd == NULL) + if (sd == nullptr) { - PRINTF("npc_event nullpo?\n"); + PRINTF("npc_event nullpo?\n"_fmt); } - if (ev == NULL && eventname.label == stringish<ScriptLabel>("OnTouch")) + if (ev == nullptr && eventname.label == stringish<ScriptLabel>("OnTouch"_s)) return 1; - if (ev == NULL || (nd = ev->nd) == NULL) + if (ev == nullptr || (nd = ev->nd) == nullptr) { if (mob_kill) { @@ -480,7 +488,7 @@ int npc_event(dumb_ptr<map_session_data> sd, NpcEvent eventname, else { if (battle_config.error_log) - PRINTF("npc_event: event not found [%s]\n", + PRINTF("npc_event: event not found [%s]\n"_fmt, eventname); return 0; } @@ -500,7 +508,7 @@ int npc_event(dumb_ptr<map_session_data> sd, NpcEvent eventname, return 1; } - if (sd->npc_id != 0) + if (sd->npc_id) { sd->eventqueuel.push_back(eventname); return 1; @@ -521,12 +529,12 @@ static void npc_command_sub(NpcEvent key, struct event_data *ev, NpcName npcname, XString command) { if (ev->nd->name == npcname - && key.label.startswith("OnCommand")) + && key.label.startswith("OnCommand"_s)) { XString temp = key.label.xslice_t(9); if (command == temp) - run_script(ScriptPointer(ev->nd->scr.script.get(), ev->pos), 0, ev->nd->bl_id); + run_script(ScriptPointer(ev->nd->scr.script.get(), ev->pos), BlockId(), ev->nd->bl_id); } } @@ -567,7 +575,7 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, map_local *m, int x, int y) ys = m->npc[i]->is_warp()->warp.ys; break; case NpcSubtype::MESSAGE: - assert (0 && "I'm pretty sure these are never put on a map"); + assert (0 && "I'm pretty sure these are never put on a map"_s); xs = 0; ys = 0; break; @@ -589,7 +597,7 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, map_local *m, int x, int y) if (f) { if (battle_config.error_log) - PRINTF("npc_touch_areanpc : some bug \n"); + PRINTF("npc_touch_areanpc : some bug \n"_fmt); } return 1; } @@ -601,13 +609,13 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, map_local *m, int x, int y) m->npc[i]->is_warp()->warp.x, m->npc[i]->is_warp()->warp.y, BeingRemoveWhy::GONE); break; case NpcSubtype::MESSAGE: - assert (0 && "I'm pretty sure these NPCs are never put on a map."); + assert (0 && "I'm pretty sure these NPCs are never put on a map."_s); break; case NpcSubtype::SCRIPT: { NpcEvent aname; aname.npc = m->npc[i]->name; - aname.label = stringish<ScriptLabel>("OnTouch"); + aname.label = stringish<ScriptLabel>("OnTouch"_s); if (sd->areanpc_id == m->npc[i]->bl_id) return 1; @@ -626,20 +634,20 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, map_local *m, int x, int y) *------------------------------------------ */ static -int npc_checknear(dumb_ptr<map_session_data> sd, int id) +int npc_checknear(dumb_ptr<map_session_data> sd, BlockId id) { dumb_ptr<npc_data> nd; - nullpo_ret(sd); + nullpo_retz(sd); nd = map_id_is_npc(id); // this actually happens - if (nd == NULL) + if (nd == nullptr) return 1; if (nd->bl_type != BL::NPC) return 1; - if (nd->npc_class < 0) // イベント系は常にOK + if (nd->npc_class == NEGATIVE_SPECIES) return 0; // エリア判定 @@ -657,16 +665,16 @@ int npc_checknear(dumb_ptr<map_session_data> sd, int id) * クリック時のNPC処理 *------------------------------------------ */ -int npc_click(dumb_ptr<map_session_data> sd, int id) +int npc_click(dumb_ptr<map_session_data> sd, BlockId id) { dumb_ptr<npc_data> nd; nullpo_retr(1, sd); - if (sd->npc_id != 0) + if (sd->npc_id) { if (battle_config.error_log) - PRINTF("npc_click: npc_id != 0\n"); + PRINTF("npc_click: npc_id != 0\n"_fmt); return 1; } @@ -706,7 +714,7 @@ int npc_click(dumb_ptr<map_session_data> sd, int id) * *------------------------------------------ */ -int npc_scriptcont(dumb_ptr<map_session_data> sd, int id) +int npc_scriptcont(dumb_ptr<map_session_data> sd, BlockId id) { dumb_ptr<npc_data> nd; @@ -738,7 +746,7 @@ int npc_scriptcont(dumb_ptr<map_session_data> sd, int id) * *------------------------------------------ */ -int npc_buysellsel(dumb_ptr<map_session_data> sd, int id, int type) +int npc_buysellsel(dumb_ptr<map_session_data> sd, BlockId id, int type) { dumb_ptr<npc_data> nd; @@ -751,8 +759,8 @@ int npc_buysellsel(dumb_ptr<map_session_data> sd, int id, int type) if (nd->npc_subtype != NpcSubtype::SHOP) { if (battle_config.error_log) - PRINTF("no such shop npc : %d\n", id); - sd->npc_id = 0; + PRINTF("no such shop npc : %d\n"_fmt, id); + sd->npc_id = BlockId(); return 1; } if (nd->flag & 1) // 無効化されている @@ -775,15 +783,14 @@ int npc_buysellsel(dumb_ptr<map_session_data> sd, int id, int type) *------------------------------------------ */ // TODO enumify return type -int npc_buylist(dumb_ptr<map_session_data> sd, int n, - const uint16_t *item_list) +int npc_buylist(dumb_ptr<map_session_data> sd, + const std::vector<Packet_Repeat<0x00c8>>& item_list) { dumb_ptr<npc_data> nd; double z; int i, j, w, itemamount = 0, new_stacks = 0; nullpo_retr(3, sd); - nullpo_retr(3, item_list); if (npc_checknear(sd, sd->npc_shopid)) return 3; @@ -792,26 +799,29 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n, if (nd->npc_subtype != NpcSubtype::SHOP) return 3; - for (i = 0, w = 0, z = 0; i < n; i++) + for (i = 0, w = 0, z = 0; i < item_list.size(); i++) { + const uint16_t& item_l_count = item_list[i].count; + const ItemNameId& item_l_id = item_list[i].name_id; + for (j = 0; j < nd->is_shop()->shop_items.size(); j++) { - if (nd->is_shop()->shop_items[j].nameid == item_list[i * 2 + 1]) + if (nd->is_shop()->shop_items[j].nameid == item_l_id) break; } if (j == nd->is_shop()->shop_items.size()) return 3; - z += static_cast<double>(nd->is_shop()->shop_items[j].value) * item_list[i * 2]; - itemamount += item_list[i * 2]; + z += static_cast<double>(nd->is_shop()->shop_items[j].value) * item_l_count; + itemamount += item_l_count; - switch (pc_checkadditem(sd, item_list[i * 2 + 1], item_list[i * 2])) + switch (pc_checkadditem(sd, item_l_id, item_l_count)) { case ADDITEM::EXIST: break; case ADDITEM::NEW: - if (itemdb_isequip(item_list[i * 2 + 1])) - new_stacks += item_list[i * 2]; + if (itemdb_isequip(item_l_id)) + new_stacks += item_l_count; else new_stacks++; break; @@ -819,7 +829,7 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n, return 2; } - w += itemdb_weight(item_list[i * 2 + 1]) * item_list[i * 2]; + w += itemdb_weight(item_l_id) * item_l_count; } if (z > static_cast<double>(sd->status.zeny)) @@ -828,18 +838,21 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n, return 2; // 重量超過 if (pc_inventoryblank(sd) < new_stacks) return 3; // 種類数超過 - if (sd->trade_partner != 0) + if (sd->trade_partner) return 4; // cant buy while trading pc_payzeny(sd, static_cast<int>(z)); - for (i = 0; i < n; i++) + for (i = 0; i < item_list.size(); i++) { + const uint16_t& item_l_count = item_list[i].count; + const ItemNameId& item_l_id = item_list[i].name_id; + struct item_data *item_data; - if ((item_data = itemdb_exists(item_list[i * 2 + 1])) != NULL) + if ((item_data = itemdb_exists(item_l_id)) != nullptr) { - int amount = item_list[i * 2]; - struct item item_tmp {}; + int amount = item_l_count; + Item item_tmp {}; item_tmp.nameid = item_data->nameid; @@ -868,39 +881,37 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n, * *------------------------------------------ */ -int npc_selllist(dumb_ptr<map_session_data> sd, int n, - const uint16_t *item_list) +int npc_selllist(dumb_ptr<map_session_data> sd, + const std::vector<Packet_Repeat<0x00c9>>& item_list) { double z; int i, itemamount = 0; nullpo_retr(1, sd); - nullpo_retr(1, item_list); if (npc_checknear(sd, sd->npc_shopid)) return 1; - for (i = 0, z = 0; i < n; i++) + for (i = 0, z = 0; i < item_list.size(); i++) { - int nameid; - if (item_list[i * 2] - 2 < 0 || item_list[i * 2] - 2 >= MAX_INVENTORY) + if (!item_list[i].ioff2.ok()) return 1; - nameid = sd->status.inventory[item_list[i * 2] - 2].nameid; - if (nameid == 0 || - sd->status.inventory[item_list[i * 2] - 2].amount < item_list[i * 2 + 1]) + ItemNameId nameid = sd->status.inventory[item_list[i].ioff2.unshift()].nameid; + if (!nameid || + sd->status.inventory[item_list[i].ioff2.unshift()].amount < item_list[i].count) return 1; - if (sd->trade_partner != 0) + if (sd->trade_partner) return 2; // cant sell while trading - z += static_cast<double>(itemdb_value_sell(nameid)) * item_list[i * 2 + 1]; - itemamount += item_list[i * 2 + 1]; + z += static_cast<double>(itemdb_value_sell(nameid)) * item_list[i].count; + itemamount += item_list[i].count; } if (z > MAX_ZENY) z = MAX_ZENY; pc_getzeny(sd, static_cast<int>(z)); - for (i = 0; i < n; i++) + for (i = 0; i < item_list.size(); i++) { - int item_id = item_list[i * 2] - 2; - pc_delitem(sd, item_id, item_list[i * 2 + 1], 0); + IOff0 item_id = item_list[i].ioff2.unshift(); + pc_delitem(sd, item_id, item_list[i].count, 0); } return 0; @@ -927,7 +938,7 @@ void npc_clearsrcfile(void) */ void npc_addsrcfile(AString name) { - if (name == "clear") + if (name == "clear"_s) { npc_clearsrcfile(); return; @@ -942,7 +953,7 @@ void npc_addsrcfile(AString name) */ void npc_delsrcfile(XString name) { - if (name == "all") + if (name == "all"_s) { npc_clearsrcfile(); return; @@ -961,19 +972,19 @@ void npc_delsrcfile(XString name) static void register_npc_name(dumb_ptr<npc_data> nd) { - ZString types[4] = - { - {"WARP"}, - {"SHOP"}, - {"SCRIPT"}, - {"MESSAGE"}, - }; + earray<LString, NpcSubtype, NpcSubtype::COUNT> types //= + {{ + "WARP"_s, + "SHOP"_s, + "SCRIPT"_s, + "MESSAGE"_s, + }}; if (!nd->name) { if (nd->npc_subtype == NpcSubtype::MESSAGE) return; - PRINTF("WARNING: npc with no name:\n%s @ %s,%d,%d\n", - types[static_cast<int>(nd->npc_subtype)], + PRINTF("WARNING: npc with no name:\n%s @ %s,%d,%d\n"_fmt, + types[nd->npc_subtype], nd->bl_m->name_, nd->bl_x, nd->bl_y); return; } @@ -982,12 +993,12 @@ void register_npc_name(dumb_ptr<npc_data> nd) if (nd->npc_subtype != NpcSubtype::WARP || nd_old->npc_subtype != NpcSubtype::WARP) { - PRINTF("WARNING: replacing npc with name: %s\n", nd->name); - PRINTF("old: %s @ %s,%d,%d\n", - types[static_cast<int>(nd_old->npc_subtype)], + PRINTF("WARNING: replacing npc with name: %s\n"_fmt, nd->name); + PRINTF("old: %s @ %s,%d,%d\n"_fmt, + types[nd_old->npc_subtype], nd_old->bl_m->name_, nd_old->bl_x, nd_old->bl_y); - PRINTF("new: %s @ %s,%d,%d\n", - types[static_cast<int>(nd->npc_subtype)], + PRINTF("new: %s @ %s,%d,%d\n"_fmt, + types[nd->npc_subtype], nd->bl_m->name_, nd->bl_x, nd->bl_y); } } @@ -1009,7 +1020,7 @@ int npc_parse_warp(XString w1, XString, NpcName w3, XString w4) if (!extract(w1, record<','>(&mapname, &x, &y)) || !extract(w4, record<','>(&xs, &ys, &to_mapname, &to_x, &to_y))) { - PRINTF("bad warp line : %s\n", w3); + PRINTF("bad warp line : %s\n"_fmt, w3); return 1; } @@ -1019,7 +1030,7 @@ int npc_parse_warp(XString w1, XString, NpcName w3, XString w4) nd->bl_id = npc_get_new_npc_id(); nd->n = map_addnpc(m, nd); - nd->bl_prev = nd->bl_next = NULL; + nd->bl_prev = nd->bl_next = nullptr; nd->bl_m = m; nd->bl_x = x; nd->bl_y = y; @@ -1031,7 +1042,7 @@ int npc_parse_warp(XString w1, XString, NpcName w3, XString w4) nd->npc_class = WARP_CLASS; else nd->npc_class = WARP_DEBUG_CLASS; - nd->speed = std::chrono::milliseconds(200); + nd->speed = 200_ms; nd->option = Option::ZERO; nd->opt1 = Opt1::ZERO; nd->opt2 = Opt2::ZERO; @@ -1059,7 +1070,6 @@ int npc_parse_warp(XString w1, XString, NpcName w3, XString w4) } } -// PRINTF("warp npc %s %d read done\n",mapname,nd->bl_id); npc_warp++; nd->bl_type = BL::NPC; nd->npc_subtype = NpcSubtype::WARP; @@ -1077,11 +1087,11 @@ bool extract(XString xs, npc_item_list *itv) if (!extract(xs, record<':'>(&name_or_id, &itv->value))) return false; struct item_data *id = nullptr; - if (extract(name_or_id, &itv->nameid) && itv->nameid > 0) + if (extract(name_or_id, &itv->nameid) && itv->nameid) goto return_true; id = itemdb_searchname(name_or_id.rstrip()); - if (id == NULL) + if (id == nullptr) return false; itv->nameid = id->nameid; goto return_true; @@ -1089,7 +1099,7 @@ bool extract(XString xs, npc_item_list *itv) return_true: if (itv->value < 0) { - if (id == NULL) + if (id == nullptr) id = itemdb_search(itv->nameid); itv->value = id->value_buy * abs(itv->value); } @@ -1108,7 +1118,7 @@ int npc_parse_shop(XString w1, XString, NpcName w3, ZString w4a) MapName mapname; dumb_ptr<npc_data_shop> nd; ZString::iterator w4comma; - int npc_class; + Species npc_class; int dir_; // TODO use enum directly in extract if (!extract(w1, record<','>(&mapname, &x, &y, &dir_)) @@ -1116,7 +1126,7 @@ int npc_parse_shop(XString w1, XString, NpcName w3, ZString w4a) || (w4comma = std::find(w4a.begin(), w4a.end(), ',')) == w4a.end() || !extract(w4a.xislice_h(w4comma), &npc_class)) { - PRINTF("bad shop line : %s\n", w3); + PRINTF("bad shop line : %s\n"_fmt, w3); return 1; } dir = static_cast<DIR>(dir_); @@ -1127,8 +1137,8 @@ int npc_parse_shop(XString w1, XString, NpcName w3, ZString w4a) if (!extract(w4b, vrec<','>(&nd->shop_items))) { - PRINTF("bad shop items : %s\n", w3); - PRINTF(" somewhere --> %s\n", w4b); + PRINTF("bad shop items : %s\n"_fmt, w3); + PRINTF(" somewhere --> %s\n"_fmt, w4b); nd->shop_items.clear(); } @@ -1138,7 +1148,7 @@ int npc_parse_shop(XString w1, XString, NpcName w3, ZString w4a) return 1; } - nd->bl_prev = nd->bl_next = NULL; + nd->bl_prev = nd->bl_next = nullptr; nd->bl_m = m; nd->bl_x = x; nd->bl_y = y; @@ -1147,7 +1157,7 @@ int npc_parse_shop(XString w1, XString, NpcName w3, ZString w4a) nd->flag = 0; nd->name = w3; nd->npc_class = npc_class; - nd->speed = std::chrono::milliseconds(200); + nd->speed = 200_ms; nd->option = Option::ZERO; nd->opt1 = Opt1::ZERO; nd->opt2 = Opt2::ZERO; @@ -1190,13 +1200,14 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4, int x, y; DIR dir = DIR::S; map_local *m; - int xs = 0, ys = 0, npc_class = 0; // [Valaris] thanks to fov + int xs = 0, ys = 0; // [Valaris] thanks to fov + Species npc_class; MapName mapname; - std::unique_ptr<const ScriptBuffer> script = NULL; + std::unique_ptr<const ScriptBuffer> script = nullptr; dumb_ptr<npc_data_script> nd; int evflag = 0; - if (w1 == "-") + if (w1 == "-"_s) { x = 0; y = 0; @@ -1207,16 +1218,16 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4, int dir_; // TODO use enum directly in extract if (!extract(w1, record<','>(&mapname, &x, &y, &dir_)) || dir_ < 0 || dir_ >= 8 - || (w2 == "script" && !w4.contains(','))) + || (w2 == "script"_s && !w4.contains(','))) { - PRINTF("bad script line : %s\n", w3); + PRINTF("bad script line : %s\n"_fmt, w3); return 1; } dir = static_cast<DIR>(dir_); m = map_mapname2mapid(mapname); } - if (w2 == "script") + if (w2 == "script"_s) { // may be empty MString srcbuf; @@ -1249,13 +1260,13 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4, srcbuf += '\n'; } script = parse_script(AString(srcbuf), startline, false); - if (script == NULL) + if (script == nullptr) // script parse error? return 1; } else { - assert(0 && "duplicate() is no longer supported!\n"); + assert(0 && "duplicate() is no longer supported!\n"_s); return 0; } @@ -1271,7 +1282,7 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4, if (ys >= 0) ys = ys * 2 + 1; - if (npc_class >= 0) + if (npc_class != NEGATIVE_SPECIES) { for (int i = 0; i < ys; i++) @@ -1295,26 +1306,31 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4, } else { - npc_class = atoi(w4.c_str()); + XString w4x = w4; + if (w4x.endswith(',')) + w4x = w4x.xrslice_h(1); + if (!extract(w4x, &npc_class)) + abort(); nd->scr.xs = 0; nd->scr.ys = 0; } - if (npc_class < 0 && m != nullptr) + if (npc_class == NEGATIVE_SPECIES && m != nullptr) { evflag = 1; } if (w3.contains(':')) { - assert(false && "feature removed"); + assert(false && "feature removed"_s); abort(); } + { nd->name = w3; } - nd->bl_prev = nd->bl_next = NULL; + nd->bl_prev = nd->bl_next = nullptr; nd->bl_m = m; nd->bl_x = x; nd->bl_y = y; @@ -1322,14 +1338,13 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4, nd->dir = dir; nd->flag = 0; nd->npc_class = npc_class; - nd->speed = std::chrono::milliseconds(200); + nd->speed = 200_ms; nd->scr.script = std::move(script); nd->option = Option::ZERO; nd->opt1 = Opt1::ZERO; nd->opt2 = Opt2::ZERO; nd->opt3 = Opt3::ZERO; - //PRINTF("script npc %s %d %d read done\n",mapname,nd->bl_id,nd->class); npc_script++; nd->bl_type = BL::NPC; nd->npc_subtype = NpcSubtype::SCRIPT; @@ -1361,7 +1376,7 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4, ScriptLabel lname = el.name; int pos = el.pos; - if (lname.startswith("On")) + if (lname.startswith("On"_s)) { struct event_data ev {}; ev.nd = nd; @@ -1380,7 +1395,7 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4, int t_ = 0; ScriptLabel lname = el.name; int pos = el.pos; - if (lname.startswith("OnTimer") && extract(lname.xslice_t(7), &t_) && t_ > 0) + if (lname.startswith("OnTimer"_s) && extract(lname.xslice_t(7), &t_) && t_ > 0) { interval_t t = static_cast<interval_t>(t_); @@ -1440,7 +1455,7 @@ int npc_parse_function(XString, XString, XString w3, ZString, srcbuf += '\n'; } std::unique_ptr<const ScriptBuffer> script = parse_script(AString(srcbuf), startline, false); - if (script == NULL) + if (script == nullptr) { // script parse error? return 1; @@ -1458,7 +1473,8 @@ int npc_parse_function(XString, XString, XString w3, ZString, static int npc_parse_mob(XString w1, XString, MobName w3, ZString w4) { - int x, y, xs, ys, mob_class, num; + int x, y, xs, ys, num; + Species mob_class; int i; MapName mapname; NpcEvent eventname; @@ -1469,7 +1485,7 @@ int npc_parse_mob(XString w1, XString, MobName w3, ZString w4) if (!extract(w1, record<',', 3>(&mapname, &x, &y, &xs, &ys)) || !extract(w4, record<',', 2>(&mob_class, &num, &delay1_, &delay2_, &eventname))) { - PRINTF("bad monster line : %s\n", w3); + PRINTF("bad monster line : %s\n"_fmt, w3); return 1; } interval_t delay1 = std::chrono::milliseconds(delay1_); @@ -1487,15 +1503,15 @@ int npc_parse_mob(XString w1, XString, MobName w3, ZString w4) { md.new_(); - md->bl_prev = NULL; - md->bl_next = NULL; + md->bl_prev = nullptr; + md->bl_next = nullptr; md->bl_m = m; md->bl_x = x; md->bl_y = y; if (w3 == ENGLISH_NAME) - md->name = mob_db[mob_class].name; + md->name = get_mob_db(mob_class).name; else if (w3 == JAPANESE_NAME) - md->name = mob_db[mob_class].jname; + md->name = get_mob_db(mob_class).jname; else md->name = w3; @@ -1512,8 +1528,8 @@ int npc_parse_mob(XString w1, XString, MobName w3, ZString w4) really_memzero_this(&md->state); // md->timer = nullptr; - md->target_id = 0; - md->attacked_id = 0; + md->target_id = BlockId(); + md->attacked_id = BlockId(); md->lootitemv.clear(); @@ -1525,7 +1541,6 @@ int npc_parse_mob(XString w1, XString, MobName w3, ZString w4) npc_mob++; } - //PRINTF("warp npc %s %d read done\n",mapname,nd->bl_id); return 0; } @@ -1561,9 +1576,9 @@ int npc_parse_mapflag(XString w1, XString, XString w3, ZString w4) if (mf == MapFlag::NOSAVE) { - if (w4 == "SavePoint") + if (w4 == "SavePoint"_s) { - m->save.map_ = stringish<MapName>("SavePoint"); + m->save.map_ = stringish<MapName>("SavePoint"_s); m->save.x = -1; m->save.y = -1; } @@ -1589,7 +1604,7 @@ int npc_parse_mapflag(XString w1, XString, XString w3, ZString w4) } dumb_ptr<npc_data> npc_spawn_text(map_local *m, int x, int y, - int npc_class, NpcName name, AString message) + Species npc_class, NpcName name, AString message) { dumb_ptr<npc_data_message> retval; retval.new_(); @@ -1605,7 +1620,7 @@ dumb_ptr<npc_data> npc_spawn_text(map_local *m, int x, int y, retval->message = message; retval->npc_class = npc_class; - retval->speed = std::chrono::milliseconds(200); + retval->speed = 200_ms; clif_spawnnpc(retval); map_addblock(retval); @@ -1679,11 +1694,11 @@ bool do_init_npc(void) io::ReadFile fp(nsl); if (!fp.is_open()) { - PRINTF("file not found : %s\n", nsl); + PRINTF("file not found : %s\n"_fmt, nsl); rv = false; continue; } - PRINTF("\rLoading NPCs [%d]: %-54s", npc_id - START_NPC_NUM, + PRINTF("\rLoading NPCs [%d]: %-54s"_fmt, unwrap<BlockId>(npc_id) - unwrap<BlockId>(START_NPC_NUM), nsl); int lines = 0; AString zline; @@ -1698,7 +1713,7 @@ bool do_init_npc(void) if (!extract(zline, record<'|', 3>(&w1, &w2, &w3, &w4x)) || !w1 || !w2 || !w3) { - FPRINTF(stderr, "%s:%d: Broken script line: %s\n", nsl, lines, zline); + FPRINTF(stderr, "%s:%d: Broken script line: %s\n"_fmt, nsl, lines, zline); rv = false; continue; } @@ -1708,7 +1723,7 @@ bool do_init_npc(void) } assert(bool(w4x) == bool(w4z)); - if (w1 != "-" && w1 != "function") + if (w1 != "-"_s && w1 != "function"_s) { auto comma = std::find(w1.begin(), w1.end(), ','); MapName mapname = stringish<MapName>(w1.xislice_h(comma)); @@ -1716,24 +1731,24 @@ bool do_init_npc(void) if (m == nullptr) { // "mapname" is not assigned to this server - FPRINTF(stderr, "%s:%d: Map not found: %s\n", nsl, lines, mapname); + FPRINTF(stderr, "%s:%d: Map not found: %s\n"_fmt, nsl, lines, mapname); rv = false; continue; } } - if (w2 == "warp") + if (w2 == "warp"_s) { NpcName npcname = stringish<NpcName>(w3); npc_parse_warp(w1, w2, npcname, w4z); } - else if (w2 == "shop") + else if (w2 == "shop"_s) { NpcName npcname = stringish<NpcName>(w3); npc_parse_shop(w1, w2, npcname, w4z); } - else if (w2 == "script") + else if (w2 == "script"_s) { - if (w1 == "function") + if (w1 == "function"_s) { npc_parse_function(w1, w2, w3, w4z, w4x, fp, &lines); @@ -1745,30 +1760,31 @@ bool do_init_npc(void) w4x, fp, &lines); } } - else if (w2 == "monster") + else if (w2 == "monster"_s) { MobName mobname = stringish<MobName>(w3); npc_parse_mob(w1, w2, mobname, w4z); } - else if (w2 == "mapflag") + else if (w2 == "mapflag"_s) { npc_parse_mapflag(w1, w2, w3, w4z); } else { - PRINTF("odd script line: %s\n", zline); + PRINTF("odd script line: %s\n"_fmt, zline); script_errors++; } } fflush(stdout); } - PRINTF("\rNPCs Loaded: %d [Warps:%d Shops:%d Scripts:%d Mobs:%d] %20s\n", - npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, ""); + PRINTF("\rNPCs Loaded: %d [Warps:%d Shops:%d Scripts:%d Mobs:%d] %20s\n"_fmt, + unwrap<BlockId>(npc_id) - unwrap<BlockId>(START_NPC_NUM), npc_warp, npc_shop, npc_script, npc_mob, ""_s); if (script_errors) { - PRINTF("Cowardly refusing to continue after %d errors\n", script_errors); + PRINTF("Cowardly refusing to continue after %d errors\n"_fmt, script_errors); rv = false; } return rv; } +} // namespace tmwa diff --git a/src/map/npc.hpp b/src/map/npc.hpp index eb9a5eb..33dd378 100644 --- a/src/map/npc.hpp +++ b/src/map/npc.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_NPC_HPP -#define TMWA_MAP_NPC_HPP +#pragma once // npc.hpp - Noncombatants. // // Copyright © ????-2004 Athena Dev Teams @@ -21,47 +20,55 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstddef> -# include <cstdint> +#include <cstdint> -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "../mmo/timer.t.hpp" +#include "../generic/fwd.hpp" -# include "map.hpp" +#include "../net/timer.t.hpp" -constexpr int START_NPC_NUM = 110000000; +#include "../proto2/fwd.hpp" -constexpr int WARP_CLASS = 45; -constexpr int WARP_DEBUG_CLASS = 722; -constexpr int INVISIBLE_CLASS = 32767; +#include "map.hpp" + + +namespace tmwa +{ +constexpr BlockId START_NPC_NUM = wrap<BlockId>(110000000); + +// TODO make these species, see npc_class in npc_data +constexpr Species WARP_CLASS = wrap<Species>(45); +constexpr Species FAKE_NPC_CLASS = wrap<Species>(127); +constexpr Species WARP_DEBUG_CLASS = wrap<Species>(722); +constexpr Species INVISIBLE_CLASS = wrap<Species>(32767); int npc_event_dequeue(dumb_ptr<map_session_data> sd); int npc_event(dumb_ptr<map_session_data> sd, NpcEvent npcname, int); void npc_timer_event(NpcEvent eventname); // Added by RoVeRT int npc_command(dumb_ptr<map_session_data> sd, NpcName npcname, XString command); int npc_touch_areanpc(dumb_ptr<map_session_data>, map_local *, int, int); -int npc_click(dumb_ptr<map_session_data>, int); -int npc_scriptcont(dumb_ptr<map_session_data>, int); -int npc_buysellsel(dumb_ptr<map_session_data>, int, int); -int npc_buylist(dumb_ptr<map_session_data>, int, const uint16_t *); -int npc_selllist(dumb_ptr<map_session_data>, int, const uint16_t *); +int npc_click(dumb_ptr<map_session_data>, BlockId); +int npc_scriptcont(dumb_ptr<map_session_data>, BlockId); +int npc_buysellsel(dumb_ptr<map_session_data>, BlockId, int); +int npc_buylist(dumb_ptr<map_session_data>, const std::vector<Packet_Repeat<0x00c8>>&); +int npc_selllist(dumb_ptr<map_session_data>, const std::vector<Packet_Repeat<0x00c9>>&); int npc_parse_warp(XString w1, XString, NpcName w3, XString w4); int npc_enable(NpcName name, bool flag); dumb_ptr<npc_data> npc_name2id(NpcName name); -int npc_get_new_npc_id(void); +BlockId npc_get_new_npc_id(void); /** * Spawns and installs a talk-only NPC * - * \param message The message to speak. If message is NULL, the NPC will not do anything at all. + * \param message The message to speak. If message is nullptr, the NPC will not do anything at all. */ dumb_ptr<npc_data> npc_spawn_text(map_local *m, int x, int y, - int class_, NpcName name, AString message); + Species class_, NpcName name, AString message); /** * Uninstalls and frees an NPC @@ -73,17 +80,17 @@ void npc_delsrcfile(XString); bool do_init_npc(void); int npc_event_do_oninit(void); -int npc_event_doall_l(ScriptLabel name, int rid, Slice<argrec_t> argv); -int npc_event_do_l(NpcEvent name, int rid, Slice<argrec_t> argv); +int npc_event_doall_l(ScriptLabel name, BlockId rid, Slice<argrec_t> argv); +int npc_event_do_l(NpcEvent name, BlockId rid, Slice<argrec_t> argv); inline int npc_event_doall(ScriptLabel name) { - return npc_event_doall_l(name, 0, nullptr); + return npc_event_doall_l(name, BlockId(), nullptr); } inline int npc_event_do(NpcEvent name) { - return npc_event_do_l(name, 0, nullptr); + return npc_event_do_l(name, BlockId(), nullptr); } void npc_timerevent_start(dumb_ptr<npc_data_script> nd); @@ -91,5 +98,4 @@ void npc_timerevent_stop(dumb_ptr<npc_data_script> nd); interval_t npc_gettimerevent_tick(dumb_ptr<npc_data_script> nd); void npc_settimerevent_tick(dumb_ptr<npc_data_script> nd, interval_t newtimer); int npc_delete(dumb_ptr<npc_data> nd); - -#endif // TMWA_MAP_NPC_HPP +} // namespace tmwa diff --git a/src/map/party.cpp b/src/map/party.cpp index 75c54cf..8713c60 100644 --- a/src/map/party.cpp +++ b/src/map/party.cpp @@ -21,8 +21,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <cstring> - #include "../compat/nullpo.hpp" #include "../strings/xstring.hpp" @@ -31,23 +29,27 @@ #include "../io/cxxstdio.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" +#include "../net/timer.hpp" + +#include "../mmo/ids.hpp" +#include "../mmo/mmo.hpp" #include "battle.hpp" #include "clif.hpp" #include "intif.hpp" #include "map.hpp" #include "pc.hpp" -#include "tmw.hpp" #include "../poison.hpp" + +namespace tmwa +{ // 座標やHP送信の間隔 -constexpr interval_t PARTY_SEND_XYHP_INVERVAL = std::chrono::seconds(1); +constexpr interval_t PARTY_SEND_XYHP_INVERVAL = 1_s; static -Map<int, struct party> party_db; +Map<PartyId, PartyMost> party_db; static void party_check_conflict(dumb_ptr<map_session_data> sd); @@ -64,31 +66,40 @@ void do_init_party(void) } // 検索 -struct party *party_search(int party_id) +PartyPair party_search(PartyId party_id) { - return party_db.search(party_id); + PartyPair p; + p.party_most = party_db.search(party_id); + if (p) + p.party_id = party_id; + return p; } static -void party_searchname_sub(struct party *p, PartyName str, struct party **dst) +void party_searchname_sub(PartyPair p, PartyName str, PartyPair *dst) { if (p->name == str) *dst = p; } // パーティ名検索 -struct party *party_searchname(PartyName str) +PartyPair party_searchname(PartyName str) { - struct party *p = NULL; + PartyPair p; for (auto& pair : party_db) - party_searchname_sub(&pair.second, str, &p); + { + PartyPair tmp; + tmp.party_id = pair.first; + tmp.party_most = &pair.second; + party_searchname_sub(tmp, str, &p); + } return p; } /* Process a party creation request. */ int party_create(dumb_ptr<map_session_data> sd, PartyName name) { - nullpo_ret(sd); + nullpo_retz(sd); name = stringish<PartyName>(name.strip()); @@ -97,7 +108,7 @@ int party_create(dumb_ptr<map_session_data> sd, PartyName name) clif_party_created(sd, 1); /* Make sure the character isn't already in a party. */ - if (sd->status.party_id == 0) + if (!sd->status.party_id) intif_create_party(sd, name); else clif_party_created(sd, 2); @@ -106,10 +117,10 @@ int party_create(dumb_ptr<map_session_data> sd, PartyName name) } /* Relay the result of a party creation request. */ -void party_created(int account_id, int fail, int party_id, PartyName name) +void party_created(AccountId account_id, int fail, PartyId party_id, PartyName name) { dumb_ptr<map_session_data> sd; - sd = map_id2sd(account_id); + sd = map_id2sd(account_to_block(account_id)); nullpo_retv(sd); @@ -118,15 +129,15 @@ void party_created(int account_id, int fail, int party_id, PartyName name) { sd->status.party_id = party_id; - struct party *p = party_db.search(party_id); - if (p != NULL) + PartyPair p = party_search(party_id); + if (p) { - PRINTF("party_created(): ID already exists!\n"); + PRINTF("party_created(): ID already exists!\n"_fmt); exit(1); } - p = party_db.init(party_id); - p->party_id = party_id; + p.party_most = party_db.init(party_id); + p.party_id = party_id; p->name = name; /* The party was created successfully. */ @@ -138,16 +149,16 @@ void party_created(int account_id, int fail, int party_id, PartyName name) } // 情報要求 -void party_request_info(int party_id) +void party_request_info(PartyId party_id) { intif_request_partyinfo(party_id); } // 所属キャラの確認 static -int party_check_member(struct party *p) +int party_check_member(PartyPair p) { - nullpo_ret(p); + nullpo_retz(p); for (io::FD i : iter_fds()) { @@ -157,7 +168,7 @@ int party_check_member(struct party *p) map_session_data *sd = static_cast<map_session_data *>(s->session_data.get()); if (sd && sd->state.auth) { - if (sd->status.party_id == p->party_id) + if (sd->status.party_id == p.party_id) { int j, f = 1; for (j = 0; j < MAX_PARTY; j++) @@ -169,15 +180,15 @@ int party_check_member(struct party *p) else { // I can prove it was already zeroed - // p->member[j].sd = NULL; // 同垢別キャラだった + // p->member[j].sd = nullptr; // 同垢別キャラだった } } } if (f) { - sd->status.party_id = 0; + sd->status.party_id = PartyId(); if (battle_config.error_log) - PRINTF("party: check_member %d[%s] is not member\n", + PRINTF("party: check_member %d[%s] is not member\n"_fmt, sd->status_key.account_id, sd->status_key.name); } } @@ -187,7 +198,7 @@ int party_check_member(struct party *p) } // 情報所得失敗(そのIDのキャラを全部未所属にする) -int party_recv_noinfo(int party_id) +int party_recv_noinfo(PartyId party_id) { for (io::FD i : iter_fds()) { @@ -198,36 +209,36 @@ int party_recv_noinfo(int party_id) if (sd && sd->state.auth) { if (sd->status.party_id == party_id) - sd->status.party_id = 0; + sd->status.party_id = PartyId(); } } return 0; } // 情報所得 -int party_recv_info(const struct party *sp) +int party_recv_info(const PartyPair sp) { int i; - nullpo_ret(sp); + nullpo_retz(sp); - struct party *p = party_db.search(sp->party_id); - if (p == NULL) + PartyPair p = party_search(sp.party_id); + if (!p) { - p = party_db.init(sp->party_id); + p.party_most = party_db.init(sp.party_id); // 最初のロードなのでユーザーのチェックを行う - *p = *sp; + *p.party_most = *sp.party_most; party_check_member(p); } else - *p = *sp; + *p.party_most = *sp.party_most; for (i = 0; i < MAX_PARTY; i++) { // sdの設定 - dumb_ptr<map_session_data> sd = map_id2sd(p->member[i].account_id); - p->member[i].sd = (sd != NULL - && sd->status.party_id == p->party_id) ? sd.operator->() : NULL; + dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(p->member[i].account_id)); + p->member[i].sd = (sd != nullptr + && sd->status.party_id == p.party_id) ? sd.operator->() : nullptr; } clif_party_info(p, nullptr); @@ -236,7 +247,7 @@ int party_recv_info(const struct party *sp) { // 設定情報の送信 // dumb_ptr<map_session_data> sd = map_id2sd(p->member[i].account_id); dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(p->member[i].sd); - if (sd != NULL && sd->party_sended == 0) + if (sd != nullptr && sd->party_sended == 0) { clif_party_option(p, sd, 0x100); sd->party_sended = 1; @@ -247,14 +258,14 @@ int party_recv_info(const struct party *sp) } /* Process party invitation from sd to account_id. */ -int party_invite(dumb_ptr<map_session_data> sd, int account_id) +int party_invite(dumb_ptr<map_session_data> sd, AccountId account_id) { - dumb_ptr<map_session_data> tsd = map_id2sd(account_id); - struct party *p = party_search(sd->status.party_id); + dumb_ptr<map_session_data> tsd = map_id2sd(account_to_block(account_id)); + PartyPair p = party_search(sd->status.party_id); int i; int full = 1; /* Indicates whether or not there's room for one more. */ - nullpo_ret(sd); + nullpo_retz(sd); if (!tsd || !p || !tsd->sess) return 0; @@ -271,7 +282,7 @@ int party_invite(dumb_ptr<map_session_data> sd, int account_id) } /* The target player is already in a party, or has a pending invitation. */ - if (tsd->status.party_id > 0 || tsd->party_invite > 0) + if (tsd->status.party_id || tsd->party_invite) { clif_party_inviteack(sd, tsd->status_key.name, 0); return 0; @@ -311,9 +322,9 @@ int party_invite(dumb_ptr<map_session_data> sd, int account_id) } /* Process response to party invitation. */ -int party_reply_invite(dumb_ptr<map_session_data> sd, int account_id, int flag) +int party_reply_invite(dumb_ptr<map_session_data> sd, AccountId account_id, int flag) { - nullpo_ret(sd); + nullpo_retz(sd); /* There is no pending invitation. */ if (!sd->party_invite || !sd->party_invite_account) @@ -333,48 +344,48 @@ int party_reply_invite(dumb_ptr<map_session_data> sd, int account_id, int flag) else { /* This is the player who sent the invitation. */ - dumb_ptr<map_session_data> tsd = NULL; + dumb_ptr<map_session_data> tsd = nullptr; - sd->party_invite = 0; - sd->party_invite_account = 0; + sd->party_invite = PartyId(); + sd->party_invite_account = AccountId(); - if ((tsd = map_id2sd(account_id))) + if ((tsd = map_id2sd(account_to_block(account_id)))) clif_party_inviteack(tsd, sd->status_key.name, 1); } return 0; } // パーティが追加された -int party_member_added(int party_id, int account_id, int flag) +int party_member_added(PartyId party_id, AccountId account_id, int flag) { - dumb_ptr<map_session_data> sd = map_id2sd(account_id), sd2; - struct party *p = party_search(party_id); + dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id)), sd2; + PartyPair p = party_search(party_id); - if (sd == NULL) + if (sd == nullptr) { if (flag == 0) { if (battle_config.error_log) - PRINTF("party: member added error %d is not online\n", + PRINTF("party: member added error %d is not online\n"_fmt, account_id); intif_party_leave(party_id, account_id); // キャラ側に登録できなかったため脱退要求を出す } return 0; } - sd2 = map_id2sd(sd->party_invite_account); - sd->party_invite = 0; - sd->party_invite_account = 0; + sd2 = map_id2sd(account_to_block(sd->party_invite_account)); + sd->party_invite = PartyId(); + sd->party_invite_account = AccountId(); - if (p == NULL) + if (!p) { - PRINTF("party_member_added: party %d not found.\n", party_id); + PRINTF("party_member_added: party %d not found.\n"_fmt, party_id); intif_party_leave(party_id, account_id); return 0; } if (flag == 1) { // 失敗 - if (sd2 != NULL) + if (sd2 != nullptr) clif_party_inviteack(sd2, sd->status_key.name, 0); return 0; } @@ -383,7 +394,7 @@ int party_member_added(int party_id, int account_id, int flag) sd->party_sended = 0; sd->status.party_id = party_id; - if (sd2 != NULL) + if (sd2 != nullptr) clif_party_inviteack(sd2, sd->status_key.name, 2); // いちおう競合確認 @@ -395,28 +406,30 @@ int party_member_added(int party_id, int account_id, int flag) } // パーティ除名要求 -int party_removemember(dumb_ptr<map_session_data> sd, int account_id) +int party_removemember(dumb_ptr<map_session_data> sd, AccountId account_id) { - struct party *p; + PartyPair p; int i; - nullpo_ret(sd); + nullpo_retz(sd); - if ((p = party_search(sd->status.party_id)) == NULL) + if (!(p = party_search(sd->status.party_id))) return 0; for (i = 0; i < MAX_PARTY; i++) { // リーダーかどうかチェック if (p->member[i].account_id == sd->status_key.account_id) + { if (p->member[i].leader == 0) return 0; + } } for (i = 0; i < MAX_PARTY; i++) { // 所属しているか調べる if (p->member[i].account_id == account_id) { - intif_party_leave(p->party_id, account_id); + intif_party_leave(p.party_id, account_id); return 0; } } @@ -426,19 +439,19 @@ int party_removemember(dumb_ptr<map_session_data> sd, int account_id) // パーティ脱退要求 int party_leave(dumb_ptr<map_session_data> sd) { - struct party *p; + PartyPair p; int i; - nullpo_ret(sd); + nullpo_retz(sd); - if ((p = party_search(sd->status.party_id)) == NULL) + if (!(p = party_search(sd->status.party_id))) return 0; for (i = 0; i < MAX_PARTY; i++) { // 所属しているか if (p->member[i].account_id == sd->status_key.account_id) { - intif_party_leave(p->party_id, sd->status_key.account_id); + intif_party_leave(p.party_id, sd->status_key.account_id); return 0; } } @@ -446,45 +459,45 @@ int party_leave(dumb_ptr<map_session_data> sd) } // パーティメンバが脱退した -int party_member_leaved(int party_id, int account_id, CharName name) +int party_member_leaved(PartyId party_id, AccountId account_id, CharName name) { - dumb_ptr<map_session_data> sd = map_id2sd(account_id); - struct party *p = party_search(party_id); - if (p != NULL) + dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id)); + PartyPair p = party_search(party_id); + if (p) { int i; for (i = 0; i < MAX_PARTY; i++) if (p->member[i].account_id == account_id) { clif_party_leaved(p, sd, account_id, name, 0x00); - p->member[i].account_id = 0; - p->member[i].sd = NULL; + p->member[i].account_id = AccountId(); + p->member[i].sd = nullptr; } } - if (sd != NULL && sd->status.party_id == party_id) + if (sd != nullptr && sd->status.party_id == party_id) { - sd->status.party_id = 0; + sd->status.party_id = PartyId(); sd->party_sended = 0; } return 0; } // パーティ解散通知 -int party_broken(int party_id) +int party_broken(PartyId party_id) { - struct party *p; + PartyPair p; int i; - if ((p = party_search(party_id)) == NULL) + if (!(p = party_search(party_id))) return 0; for (i = 0; i < MAX_PARTY; i++) { - if (p->member[i].sd != NULL) + if (p->member[i].sd != nullptr) { clif_party_leaved(p, dumb_ptr<map_session_data>(p->member[i].sd), p->member[i].account_id, p->member[i].name, 0x10); - p->member[i].sd->status.party_id = 0; + p->member[i].sd->status.party_id = PartyId(); p->member[i].sd->party_sended = 0; } } @@ -495,12 +508,12 @@ int party_broken(int party_id) // パーティの設定変更要求 int party_changeoption(dumb_ptr<map_session_data> sd, int exp, int item) { - struct party *p; + PartyPair p; - nullpo_ret(sd); + nullpo_retz(sd); - if (sd->status.party_id == 0 - || (p = party_search(sd->status.party_id)) == NULL) + if (!sd->status.party_id + || !(p = party_search(sd->status.party_id))) return 0; intif_party_changeoption(sd->status.party_id, sd->status_key.account_id, exp, item); @@ -508,12 +521,12 @@ int party_changeoption(dumb_ptr<map_session_data> sd, int exp, int item) } // パーティの設定変更通知 -int party_optionchanged(int party_id, int account_id, int exp, int item, +int party_optionchanged(PartyId party_id, AccountId account_id, int exp, int item, int flag) { - struct party *p; - dumb_ptr<map_session_data> sd = map_id2sd(account_id); - if ((p = party_search(party_id)) == NULL) + PartyPair p; + dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id)); + if (!(p = party_search(party_id))) return 0; if (!(flag & 0x01)) @@ -525,19 +538,19 @@ int party_optionchanged(int party_id, int account_id, int exp, int item, } // パーティメンバの移動通知 -void party_recv_movemap(int party_id, int account_id, MapName mapname, +void party_recv_movemap(PartyId party_id, AccountId account_id, MapName mapname, int online, int lv) { - struct party *p; + PartyPair p; int i; - if ((p = party_search(party_id)) == NULL) + if (!(p = party_search(party_id))) return; for (i = 0; i < MAX_PARTY; i++) { - struct party_member *m = &p->member[i]; - if (m == NULL) + PartyMember *m = &p->member[i]; + if (m == nullptr) { - PRINTF("party_recv_movemap nullpo?\n"); + PRINTF("party_recv_movemap nullpo?\n"_fmt); return; } if (m->account_id == account_id) @@ -551,16 +564,16 @@ void party_recv_movemap(int party_id, int account_id, MapName mapname, if (i == MAX_PARTY) { if (battle_config.error_log) - PRINTF("party: not found member %d on %d[%s]", account_id, + PRINTF("party: not found member %d on %d[%s]"_fmt, account_id, party_id, p->name); return; } for (i = 0; i < MAX_PARTY; i++) { // sd再設定 - dumb_ptr<map_session_data> sd = map_id2sd(p->member[i].account_id); - p->member[i].sd = (sd != NULL - && sd->status.party_id == p->party_id) ? sd.operator->() : NULL; + dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(p->member[i].account_id)); + p->member[i].sd = (sd != nullptr + && sd->status.party_id == p.party_id) ? sd.operator->() : nullptr; } party_send_xy_clear(p); // 座標再通知要請 @@ -571,11 +584,11 @@ void party_recv_movemap(int party_id, int account_id, MapName mapname, // パーティメンバの移動 int party_send_movemap(dumb_ptr<map_session_data> sd) { - struct party *p; + PartyPair p; - nullpo_ret(sd); + nullpo_retz(sd); - if (sd->status.party_id == 0) + if (!sd->status.party_id) return 0; intif_party_changemap(sd, 1); @@ -586,10 +599,10 @@ int party_send_movemap(dumb_ptr<map_session_data> sd) party_check_conflict(sd); // あるならパーティ情報送信 - if ((p = party_search(sd->status.party_id)) != NULL) + if ((p = party_search(sd->status.party_id))) { party_check_member(p); // 所属を確認する - if (sd->status.party_id == p->party_id) + if (sd->status.party_id == p.party_id) { clif_party_info(p, sd->sess); clif_party_option(p, sd, 0x100); @@ -603,20 +616,20 @@ int party_send_movemap(dumb_ptr<map_session_data> sd) // パーティメンバのログアウト int party_send_logout(dumb_ptr<map_session_data> sd) { - struct party *p; + PartyPair p; - nullpo_ret(sd); + nullpo_retz(sd); - if (sd->status.party_id > 0) + if (sd->status.party_id) intif_party_changemap(sd, 0); // sdが無効になるのでパーティ情報から削除 - if ((p = party_search(sd->status.party_id)) != NULL) + if ((p = party_search(sd->status.party_id))) { int i; for (i = 0; i < MAX_PARTY; i++) if (dumb_ptr<map_session_data>(p->member[i].sd) == sd) - p->member[i].sd = NULL; + p->member[i].sd = nullptr; } return 0; @@ -625,16 +638,16 @@ int party_send_logout(dumb_ptr<map_session_data> sd) // パーティメッセージ送信 void party_send_message(dumb_ptr<map_session_data> sd, XString mes) { - if (sd->status.party_id == 0) + if (!sd->status.party_id) return; intif_party_message(sd->status.party_id, sd->status_key.account_id, mes); } // パーティメッセージ受信 -void party_recv_message(int party_id, int account_id, XString mes) +void party_recv_message(PartyId party_id, AccountId account_id, XString mes) { - struct party *p; - if ((p = party_search(party_id)) == NULL) + PartyPair p; + if (!(p = party_search(party_id))) return; clif_party_message(p, account_id, mes); } @@ -650,7 +663,7 @@ void party_check_conflict(dumb_ptr<map_session_data> sd) // 位置やHP通知用 static -void party_send_xyhp_timer_sub(struct party *p) +void party_send_xyhp_timer_sub(PartyPair p) { int i; @@ -659,7 +672,7 @@ void party_send_xyhp_timer_sub(struct party *p) for (i = 0; i < MAX_PARTY; i++) { dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(p->member[i].sd); - if (sd != NULL) + if (sd != nullptr) { // 座標通知 if (sd->party_x != sd->bl_x || sd->party_y != sd->bl_y) @@ -683,11 +696,16 @@ void party_send_xyhp_timer_sub(struct party *p) void party_send_xyhp_timer(TimerData *, tick_t) { for (auto& pair : party_db) - party_send_xyhp_timer_sub(&pair.second); + { + PartyPair tmp; + tmp.party_id = pair.first; + tmp.party_most = &pair.second; + party_send_xyhp_timer_sub(tmp); + } } // 位置通知クリア -void party_send_xy_clear(struct party *p) +void party_send_xy_clear(PartyPair p) { int i; @@ -696,7 +714,7 @@ void party_send_xy_clear(struct party *p) for (i = 0; i < MAX_PARTY; i++) { dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(p->member[i].sd); - if (sd != NULL) + if (sd != nullptr) { sd->party_x = -1; sd->party_y = -1; @@ -706,7 +724,7 @@ void party_send_xy_clear(struct party *p) } // HP通知の必要性検査用(map_foreachinmoveareaから呼ばれる) -void party_send_hp_check(dumb_ptr<block_list> bl, int party_id, int *flag) +void party_send_hp_check(dumb_ptr<block_list> bl, PartyId party_id, int *flag) { dumb_ptr<map_session_data> sd; @@ -721,17 +739,17 @@ void party_send_hp_check(dumb_ptr<block_list> bl, int party_id, int *flag) } // 経験値公平分配 -int party_exp_share(struct party *p, map_local *mapid, int base_exp, int job_exp) +int party_exp_share(PartyPair p, map_local *mapid, int base_exp, int job_exp) { dumb_ptr<map_session_data> sd; int i, c; - nullpo_ret(p); + nullpo_retz(p); for (i = c = 0; i < MAX_PARTY; i++) { sd = dumb_ptr<map_session_data>(p->member[i].sd); - if (sd != NULL && sd->bl_m == mapid) + if (sd != nullptr && sd->bl_m == mapid) c++; } if (c == 0) @@ -739,7 +757,7 @@ int party_exp_share(struct party *p, map_local *mapid, int base_exp, int job_exp for (i = 0; i < MAX_PARTY; i++) { sd = dumb_ptr<map_session_data>(p->member[i].sd); - if (sd != NULL && sd->bl_m == mapid) + if (sd != nullptr && sd->bl_m == mapid) pc_gainexp_reason(sd, base_exp / c + 1, job_exp / c + 1, PC_GAINEXP_REASON::SHARING); } @@ -752,7 +770,7 @@ int party_exp_share(struct party *p, map_local *mapid, int base_exp, int job_exp void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func, dumb_ptr<map_session_data> sd, int type) { - struct party *p; + PartyPair p; int i; int x0, y0, x1, y1; dumb_ptr<map_session_data> list[MAX_PARTY]; @@ -760,7 +778,7 @@ void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func, nullpo_retv(sd); - if ((p = party_search(sd->status.party_id)) == NULL) + if (!(p = party_search(sd->status.party_id))) return; x0 = sd->bl_x - AREA_SIZE; @@ -770,8 +788,8 @@ void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func, for (i = 0; i < MAX_PARTY; i++) { - struct party_member *m = &p->member[i]; - if (m->sd != NULL) + PartyMember *m = &p->member[i]; + if (m->sd != nullptr) { if (sd->bl_m != m->sd->bl_m) continue; @@ -789,3 +807,4 @@ void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func, if (list[i]->bl_prev) // 有効かどうかチェック func(list[i]); } +} // namespace tmwa diff --git a/src/map/party.hpp b/src/map/party.hpp index 007de6b..01a8125 100644 --- a/src/map/party.hpp +++ b/src/map/party.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_PARTY_HPP -#define TMWA_MAP_PARTY_HPP +#pragma once // party.hpp - Small groups of temporary allies. // // Copyright © ????-2004 Athena Dev Teams @@ -21,38 +20,39 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <functional> +#include <functional> -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "map.hpp" +#include "../generic/fwd.hpp" -struct party; -struct map_session_data; -struct block_list; +#include "../mmo/fwd.hpp" + +namespace tmwa +{ void do_init_party(void); -struct party *party_search(int party_id); -struct party *party_searchname(PartyName str); +PartyPair party_search(PartyId party_id); +PartyPair party_searchname(PartyName str); int party_create(dumb_ptr<map_session_data> sd, PartyName name); -void party_created(int account_id, int fail, int party_id, PartyName name); -void party_request_info(int party_id); -int party_invite(dumb_ptr<map_session_data> sd, int account_id); -int party_member_added(int party_id, int account_id, int flag); +void party_created(AccountId account_id, int fail, PartyId party_id, PartyName name); +void party_request_info(PartyId party_id); +int party_invite(dumb_ptr<map_session_data> sd, AccountId account_id); +int party_member_added(PartyId party_id, AccountId account_id, int flag); int party_leave(dumb_ptr<map_session_data> sd); -int party_removemember(dumb_ptr<map_session_data> sd, int account_id); -int party_member_leaved(int party_id, int account_id, CharName name); -int party_reply_invite(dumb_ptr<map_session_data> sd, int account_id, +int party_removemember(dumb_ptr<map_session_data> sd, AccountId account_id); +int party_member_leaved(PartyId party_id, AccountId account_id, CharName name); +int party_reply_invite(dumb_ptr<map_session_data> sd, AccountId account_id, int flag); -int party_recv_noinfo(int party_id); -int party_recv_info(const struct party *sp); -void party_recv_movemap(int party_id, int account_id, MapName map, +int party_recv_noinfo(PartyId party_id); +int party_recv_info(const PartyPair sp); +void party_recv_movemap(PartyId party_id, AccountId account_id, MapName map, int online, int lv); -int party_broken(int party_id); -int party_optionchanged(int party_id, int account_id, int exp, int item, +int party_broken(PartyId party_id); +int party_optionchanged(PartyId party_id, AccountId account_id, int exp, int item, int flag); int party_changeoption(dumb_ptr<map_session_data> sd, int exp, int item); @@ -60,14 +60,13 @@ int party_send_movemap(dumb_ptr<map_session_data> sd); int party_send_logout(dumb_ptr<map_session_data> sd); void party_send_message(dumb_ptr<map_session_data> sd, XString mes); -void party_recv_message(int party_id, int account_id, XString mes); +void party_recv_message(PartyId party_id, AccountId account_id, XString mes); -void party_send_xy_clear(struct party *p); -void party_send_hp_check(dumb_ptr<block_list> bl, int party_id, int *flag); +void party_send_xy_clear(PartyPair p); +void party_send_hp_check(dumb_ptr<block_list> bl, PartyId party_id, int *flag); -int party_exp_share(struct party *p, map_local *map, int base_exp, int job_exp); +int party_exp_share(PartyPair p, map_local *map, int base_exp, int job_exp); void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func, dumb_ptr<map_session_data> sd, int type); - -#endif // TMWA_MAP_PARTY_HPP +} // namespace tmwa diff --git a/src/map/path.cpp b/src/map/path.cpp index f0204a4..6950797 100644 --- a/src/map/path.cpp +++ b/src/map/path.cpp @@ -22,19 +22,23 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include <cassert> +#include <cstddef> +#include <cstdlib> #include "../compat/nullpo.hpp" -#include "../generic/random.hpp" +#include "../strings/literal.hpp" #include "../io/cxxstdio.hpp" -#include "battle.hpp" +#include "clif.t.hpp" +#include "map.hpp" #include "../poison.hpp" -//#define PATH_STANDALONETEST +namespace tmwa +{ constexpr int MAX_HEAP = 150; struct tmp_path { @@ -58,9 +62,9 @@ void push_heap_path(int *heap, struct tmp_path *tp, int index) { int i, h; - if (heap == NULL || tp == NULL) + if (heap == nullptr || tp == nullptr) { - PRINTF("push_heap_path nullpo\n"); + PRINTF("push_heap_path nullpo\n"_fmt); return; } @@ -90,7 +94,7 @@ void update_heap_path(int *heap, struct tmp_path *tp, int index) break; if (h == heap[0]) { - FPRINTF(stderr, "update_heap_path bug\n"); + FPRINTF(stderr, "update_heap_path bug\n"_fmt); exit(1); } for (i = (h - 1) / 2; @@ -144,7 +148,7 @@ int calc_cost(struct tmp_path *p, int x1, int y1) { int xd, yd; - nullpo_ret(p); + nullpo_retz(p); xd = x1 - p->x; if (xd < 0) @@ -165,8 +169,8 @@ int add_path(int *heap, struct tmp_path *tp, int x, int y, int dist, { int i; - nullpo_ret(heap); - nullpo_ret(tp); + nullpo_retz(heap); + nullpo_retz(tp); i = calc_index(x, y); @@ -210,7 +214,7 @@ int add_path(int *heap, struct tmp_path *tp, int x, int y, int dist, static bool can_place(struct map_local *m, int x, int y) { - nullpo_ret(m); + nullpo_retz(m); return !bool(read_gatp(m, x, y) & MapCell::UNWALKABLE); } @@ -222,7 +226,7 @@ bool can_place(struct map_local *m, int x, int y) static int can_move(struct map_local *m, int x0, int y0, int x1, int y1) { - nullpo_ret(m); + nullpo_retz(m); if (x0 - x1 < -1 || x0 - x1 > 1 || y0 - y1 < -1 || y0 - y1 > 1) return 0; @@ -249,7 +253,7 @@ int path_search(struct walkpath_data *wpd, map_local *m, int x0, int y0, int x1, int i, rp, x, y; int dx, dy; - nullpo_ret(wpd); + nullpo_retz(wpd); assert (m->gat); map_local *md = m; @@ -357,3 +361,4 @@ int path_search(struct walkpath_data *wpd, map_local *m, int x0, int y0, int x1, return -1; } } +} // namespace tmwa diff --git a/src/map/path.hpp b/src/map/path.hpp index 47b9814..3619e2e 100644 --- a/src/map/path.hpp +++ b/src/map/path.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_PATH_HPP -#define TMWA_MAP_PATH_HPP +#pragma once // path.hpp - Pathfinding system. // // Copyright © ????-2004 Athena Dev Teams @@ -21,10 +20,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "map.hpp" +namespace tmwa +{ int path_search(struct walkpath_data *, map_local *, int, int, int, int, int); - -#endif // TMWA_MAP_PATH_HPP +} // namespace tmwa diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 0256eff..03e2e76 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -23,24 +23,27 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include <cassert> -#include <cstdlib> -#include <cstring> -#include "../compat/alg.hpp" +#include <algorithm> + #include "../compat/fun.hpp" #include "../compat/nullpo.hpp" #include "../strings/rstring.hpp" #include "../strings/astring.hpp" #include "../strings/zstring.hpp" +#include "../strings/literal.hpp" #include "../generic/random.hpp" #include "../io/cxxstdio.hpp" #include "../io/read.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" +#include "../net/timer.hpp" + +#include "../mmo/utils.hpp" + +#include "../proto2/char-map.hpp" #include "atcommand.hpp" #include "battle.hpp" @@ -48,9 +51,8 @@ #include "clif.hpp" #include "intif.hpp" #include "itemdb.hpp" -#include "magic.hpp" +#include "magic-stmt.hpp" #include "map.hpp" -#include "mob.hpp" #include "npc.hpp" #include "party.hpp" #include "path.hpp" @@ -61,9 +63,12 @@ #include "../poison.hpp" + +namespace tmwa +{ // PVP順位計算の間隔 constexpr std::chrono::milliseconds PVP_CALCRANK_INTERVAL = - std::chrono::seconds(1); + 1_s; //define it here, since the ifdef only occurs in this file #define USE_ASTRAL_SOUL_SKILL @@ -86,7 +91,7 @@ constexpr int MAGIC_SKILL_THRESHOLD = 200; MAP_LOG_PC(sd, "XP %d %d JOB %d %d %d ZENY %d + %d " suffix, \ sd->status.base_level, sd->status.base_exp, \ sd->status.job_level, sd->status.job_exp, sd->status.skill_point, \ - sd->status.zeny, pc_readaccountreg(sd, stringish<VarName>("BankAccount"))) + sd->status.zeny, pc_readaccountreg(sd, stringish<VarName>("BankAccount"_s))) #define MAP_LOG_MAGIC(sd, suffix) \ MAP_LOG_PC(sd, "MAGIC %d %d %d %d %d %d EXP %d %d " suffix, \ @@ -96,8 +101,8 @@ constexpr int MAGIC_SKILL_THRESHOLD = 200; sd->status.skill[SkillID::TMW_MAGIC_TRANSMUTE].lv, \ sd->status.skill[SkillID::TMW_MAGIC_NATURE].lv, \ sd->status.skill[SkillID::TMW_MAGIC_ETHER].lv, \ - pc_readglobalreg(sd, stringish<VarName>("MAGIC_EXPERIENCE")) & 0xffff, \ - (pc_readglobalreg(sd, stringish<VarName>("MAGIC_EXPERIENCE")) >> 24) & 0xff) + pc_readglobalreg(sd, stringish<VarName>("MAGIC_EXPERIENCE"_s)) & 0xffff, \ + (pc_readglobalreg(sd, stringish<VarName>("MAGIC_EXPERIENCE"_s)) >> 24) & 0xff) static //const int max_weight_base_0 = 20000; @@ -116,23 +121,23 @@ int sp_coefficient_0 = 100; static //const earray<interval_t, ItemLook, ItemLook::SINGLE_HANDED_COUNT> aspd_base_0 //= {{ -std::chrono::milliseconds(650), -std::chrono::milliseconds(700), -std::chrono::milliseconds(750), -std::chrono::milliseconds(600), -std::chrono::milliseconds(2000), -std::chrono::milliseconds(2000), -std::chrono::milliseconds(800), -std::chrono::milliseconds(2000), -std::chrono::milliseconds(700), -std::chrono::milliseconds(700), -std::chrono::milliseconds(650), -std::chrono::milliseconds(900), -std::chrono::milliseconds(2000), -std::chrono::milliseconds(2000), -std::chrono::milliseconds(2000), -std::chrono::milliseconds(2000), -std::chrono::milliseconds(2000), +650_ms, +700_ms, +750_ms, +600_ms, +2000_ms, +2000_ms, +800_ms, +2000_ms, +700_ms, +700_ms, +650_ms, +900_ms, +2000_ms, +2000_ms, +2000_ms, +2000_ms, +2000_ms, }}; static const int exp_table_0[MAX_LEVEL] = @@ -248,8 +253,9 @@ earray<EPOS, EQUIP, EQUIP::COUNT> equip_pos //= EPOS::ARROW, }}; +// TODO use DMap<> static -std::map<int, uint8_t> gm_accountm; +std::map<AccountId, GmLevel> gm_accountm; static int pc_checkoverhp(dumb_ptr<map_session_data> sd); @@ -265,20 +271,20 @@ void pc_setdead(dumb_ptr<map_session_data> sd) sd->state.dead_sit = 1; } -uint8_t pc_isGM(dumb_ptr<map_session_data> sd) +GmLevel pc_isGM(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retr(GmLevel(), sd); auto it = gm_accountm.find(sd->status_key.account_id); if (it != gm_accountm.end()) return it->second; - return 0; + return GmLevel(); } int pc_iskiller(dumb_ptr<map_session_data> src, dumb_ptr<map_session_data> target) { - nullpo_ret(src); + nullpo_retz(src); if (src->bl_type != BL::PC) return 0; @@ -293,7 +299,7 @@ int pc_iskiller(dumb_ptr<map_session_data> src, return 0; } -void pc_set_gm_level(int account_id, uint8_t level) +void pc_set_gm_level(AccountId account_id, GmLevel level) { if (level) gm_accountm[account_id] = level; @@ -312,17 +318,17 @@ int distance(int x0, int y0, int x1, int y1) } static -void pc_invincible_timer(TimerData *, tick_t, int id) +void pc_invincible_timer(TimerData *, tick_t, BlockId id) { dumb_ptr<map_session_data> sd = map_id2sd(id); - assert (sd != NULL); + assert (sd != nullptr); assert (sd->bl_type == BL::PC); } int pc_setinvincibletimer(dumb_ptr<map_session_data> sd, interval_t val) { - nullpo_ret(sd); + nullpo_retz(sd); sd->invincible_timer = Timer(gettick() + val, std::bind(pc_invincible_timer, ph::_1, ph::_2, @@ -332,7 +338,7 @@ int pc_setinvincibletimer(dumb_ptr<map_session_data> sd, interval_t val) int pc_delinvincibletimer(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); sd->invincible_timer.cancel(); return 0; @@ -340,7 +346,7 @@ int pc_delinvincibletimer(dumb_ptr<map_session_data> sd) int pc_setrestartvalue(dumb_ptr<map_session_data> sd, int type) { - nullpo_ret(sd); + nullpo_retz(sd); { if (battle_config.restart_hp_rate < 50) @@ -380,7 +386,7 @@ int pc_setrestartvalue(dumb_ptr<map_session_data> sd, int type) */ static void pc_counttargeted_sub(dumb_ptr<block_list> bl, - int id, int *c, dumb_ptr<block_list> src, ATK target_lv) + BlockId id, int *c, dumb_ptr<block_list> src, ATK target_lv) { nullpo_retv(bl); @@ -458,7 +464,7 @@ void pc_makesavestatus(dumb_ptr<map_session_data> sd) if (sd->bl_m->flag.get(MapFlag::NOSAVE)) { map_local *m = sd->bl_m; - if (m->save.map_ == "SavePoint") + if (m->save.map_ == "SavePoint"_s) sd->status.last_point = sd->status.save_point; else sd->status.last_point = m->save; @@ -469,16 +475,21 @@ void pc_makesavestatus(dumb_ptr<map_session_data> sd) * 接続時の初期化 *------------------------------------------ */ -int pc_setnewpc(dumb_ptr<map_session_data> sd, int account_id, int char_id, - int login_id1, tick_t client_tick, SEX sex) -{ - nullpo_ret(sd); - - sd->bl_id = account_id; - sd->char_id = char_id; +int pc_setnewpc(dumb_ptr<map_session_data> sd, AccountId account_id, CharId char_id, + int login_id1, uint32_t client_tick, SEX sex) +{ + nullpo_retz(sd); + + // TODO this is the primary surface + sd->bl_id = account_to_block(account_id); + sd->char_id_ = char_id; + // TODO figure out wtf is going on here. + // shouldn't these things be in the .status_key.char_id ? + // My guess is that this stuff happens even for non-auth'ed connections + // Possible fix: char send auth before client is allowed to know my IP? sd->login_id1 = login_id1; sd->login_id2 = 0; // at this point, we can not know the value :( - sd->client_tick = client_tick; + (void)client_tick; sd->sex = sex; sd->state.auth = 0; sd->bl_type = BL::PC; @@ -489,7 +500,7 @@ int pc_setnewpc(dumb_ptr<map_session_data> sd, int account_id, int char_id, return 0; } -EPOS pc_equippoint(dumb_ptr<map_session_data> sd, int n) +EPOS pc_equippoint(dumb_ptr<map_session_data> sd, IOff0 n) { nullpo_retr(EPOS::ZERO, sd); @@ -504,13 +515,11 @@ EPOS pc_equippoint(dumb_ptr<map_session_data> sd, int n) static int pc_setinventorydata(dumb_ptr<map_session_data> sd) { - int i, id; + nullpo_retz(sd); - nullpo_ret(sd); - - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { - id = sd->status.inventory[i].nameid; + ItemNameId id = sd->status.inventory[i].nameid; sd->inventory_data[i] = itemdb_search(id); } return 0; @@ -519,7 +528,7 @@ int pc_setinventorydata(dumb_ptr<map_session_data> sd) static int pc_calcweapontype(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); if (sd->weapontype1 != ItemLook::NONE && sd->weapontype2 == ItemLook::NONE) @@ -562,14 +571,14 @@ int pc_calcweapontype(dumb_ptr<map_session_data> sd) static int pc_setequipindex(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); for (EQUIP i : EQUIPs) - sd->equip_index_maybe[i] = -1; + sd->equip_index_maybe[i] = IOff0::from(-1); - for (int i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { - if (sd->status.inventory[i].nameid <= 0) + if (!sd->status.inventory[i].nameid) continue; if (bool(sd->status.inventory[i].equip)) { @@ -608,22 +617,22 @@ int pc_setequipindex(dumb_ptr<map_session_data> sd) } static -int pc_isequip(dumb_ptr<map_session_data> sd, int n) +int pc_isequip(dumb_ptr<map_session_data> sd, IOff0 n) { struct item_data *item; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; //転生や養子の場合の元の職業を算出する - nullpo_ret(sd); + nullpo_retz(sd); item = sd->inventory_data[n]; sc_data = battle_get_sc_data(sd); - if (battle_config.gm_all_equipment > 0 - && pc_isGM(sd) >= battle_config.gm_all_equipment) + GmLevel gm_all_equipment = GmLevel::from(static_cast<uint32_t>(battle_config.gm_all_equipment)); + if (gm_all_equipment && pc_isGM(sd).satisfies(gm_all_equipment)) return 1; - if (item == NULL) + if (item == nullptr) return 0; if (item->sex != SEX::NEUTRAL && sd->status.sex != item->sex) return 0; @@ -638,16 +647,16 @@ int pc_isequip(dumb_ptr<map_session_data> sd, int n) * char鯖から送られてきたステータスを設定 *------------------------------------------ */ -int pc_authok(int id, int login_id2, TimeT connect_until_time, +int pc_authok(AccountId id, int login_id2, TimeT connect_until_time, short tmw_version, const CharKey *st_key, const CharData *st_data) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; - struct party *p; + PartyPair p; tick_t tick = gettick(); - sd = map_id2sd(id); - if (sd == NULL) + sd = map_id2sd(account_to_block(id)); + if (sd == nullptr) return 1; sd->login_id2 = login_id2; @@ -662,14 +671,14 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, return 1; } - MAP_LOG_STATS(sd, "LOGIN"); - MAP_LOG_XP(sd, "LOGIN"); - MAP_LOG_MAGIC(sd, "LOGIN"); + MAP_LOG_STATS(sd, "LOGIN"_fmt); + MAP_LOG_XP(sd, "LOGIN"_fmt); + MAP_LOG_MAGIC(sd, "LOGIN"_fmt); really_memzero_this(&sd->state); // 基本的な初期化 sd->state.connect_new = 1; - sd->bl_prev = sd->bl_next = NULL; + sd->bl_prev = sd->bl_next = nullptr; sd->weapontype1 = sd->weapontype2 = ItemLook::NONE; sd->speed = DEFAULT_WALK_SPEED; @@ -682,7 +691,7 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, // sd->invincible_timer = nullptr; sd->deal_locked = 0; - sd->trade_partner = 0; + sd->trade_partner = AccountId(); sd->inchealhptick = interval_t::zero(); sd->inchealsptick = interval_t::zero(); @@ -702,7 +711,7 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, // The above is no longer accurate now that we use <chrono>, but // I'm still not reverting this. // -o11c - sd->cast_tick = tick; // + pc_readglobalreg (sd, "MAGIC_CAST_TICK"); + sd->cast_tick = tick; // + pc_readglobalreg (sd, "MAGIC_CAST_TICK"_s); // アカウント変数の送信要求 intif_request_accountreg(sd); @@ -725,17 +734,17 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, // This would leak information. // It's better to make it obvious that players can see you. if (false && bool(old_option & Option::INVISIBILITY)) - is_atcommand(sd->sess, sd, "@invisible", 0); + is_atcommand(sd->sess, sd, "@invisible"_s, GmLevel()); if (bool(old_option & Option::HIDE)) - is_atcommand(sd->sess, sd, "@hide", 0); + is_atcommand(sd->sess, sd, "@hide"_s, GmLevel()); // atcommand_hide might already send it, but also might not clif_changeoption(sd); } // パーティー関係の初期化 sd->party_sended = 0; - sd->party_invite = 0; + sd->party_invite = PartyId(); sd->party_x = -1; sd->party_y = -1; sd->party_hp = -1; @@ -748,8 +757,8 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, sd->status.last_point.y, BeingRemoveWhy::GONE); // パーティ、ギルドデータの要求 - if (sd->status.party_id > 0 - && (p = party_search(sd->status.party_id)) == NULL) + if (sd->status.party_id + && !(p = party_search(sd->status.party_id))) party_request_info(sd->status.party_id); // pvpの設定 @@ -765,19 +774,19 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, map_addchariddb(sd->status_key.char_id, sd->status_key.name); //スパノビ用死にカウンターのスクリプト変数からの読み出しとsdへのセット - sd->die_counter = pc_readglobalreg(sd, stringish<VarName>("PC_DIE_COUNTER")); + sd->die_counter = pc_readglobalreg(sd, stringish<VarName>("PC_DIE_COUNTER"_s)); // ステータス初期計算など pc_calcstatus(sd, 1); if (pc_isGM(sd)) { - PRINTF("Connection accepted: character '%s' (account: %d; GM level %d).\n", - sd->status_key.name, sd->status_key.account_id, pc_isGM(sd)); + PRINTF("Connection accepted: character '%s' (account: %d; GM level %d).\n"_fmt, + sd->status_key.name, sd->status_key.account_id, pc_isGM(sd)); clif_updatestatus(sd, SP::GM); } else - PRINTF("Connection accepted: Character '%s' (account: %d).\n", + PRINTF("Connection accepted: Character '%s' (account: %d).\n"_fmt, sd->status_key.name, sd->status_key.account_id); sd->auto_ban_info.in_progress = 0; @@ -796,11 +805,11 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time, // message of the limited time of the account if (connect_until_time) { - // don't display if it's unlimited or unknow value - char tmpstr[] = WITH_TIMESTAMP("Your account time limit is: "); - REPLACE_TIMESTAMP(tmpstr, connect_until_time); + timestamp_seconds_buffer buffer; + stamp_time(buffer, &connect_until_time); + AString tmpstr = STRPRINTF("Your account time limit is: %s"_fmt, buffer); - clif_wis_message(sd->sess, wisp_server_name, const_(tmpstr)); + clif_wis_message(sd->sess, wisp_server_name, tmpstr); } pc_calcstatus(sd, 1); @@ -817,7 +826,7 @@ void pc_show_motd(dumb_ptr<map_session_data> sd) // If you remove the sending of this message, // the license does not permit you to publicly use this software. - clif_displaymessage(sd->sess, "This server is Free Software, for details type @source in chat or use the tmwa-source tool"); + clif_displaymessage(sd->sess, "This server is Free Software, for details type @source in chat or use the tmwa-source tool"_s); sd->state.seen_motd = true; io::ReadFile in(motd_txt); @@ -835,12 +844,12 @@ void pc_show_motd(dumb_ptr<map_session_data> sd) * session idに問題ありなので後始末 *------------------------------------------ */ -int pc_authfail(int id) +int pc_authfail(AccountId id) { dumb_ptr<map_session_data> sd; - sd = map_id2sd(id); - if (sd == NULL) + sd = map_id2sd(account_to_block(id)); + if (sd == nullptr) return 1; clif_authfail_fd(sd->sess, 0); @@ -853,7 +862,7 @@ int pc_calc_skillpoint(dumb_ptr<map_session_data> sd) { int i, skill_points = 0; - nullpo_ret(sd); + nullpo_retz(sd); for (i = 0; i < skill_pool_skills_size; i++) { int lv = sd->status.skill[skill_pool_skills[i]].lv; @@ -872,7 +881,7 @@ int pc_checkweighticon(dumb_ptr<map_session_data> sd) { int flag = 0; - nullpo_ret(sd); + nullpo_retz(sd); if (sd->weight * 2 >= sd->max_weight && !sd->sc_data[StatusChange::SC_FLYING_BACKPACK].timer) @@ -907,7 +916,7 @@ void pc_set_weapon_look(dumb_ptr<map_session_data> sd) { if (sd->attack_spell_override) clif_changelook(sd, LOOK::WEAPON, - sd->attack_spell_look_override); + unwrap<ItemNameId>(sd->attack_spell_look_override)); else clif_changelook(sd, LOOK::WEAPON, static_cast<uint16_t>(sd->status.weapon)); @@ -931,7 +940,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) int aspd_rate, refinedef = 0; int str, dstr, dex; - nullpo_ret(sd); + nullpo_retz(sd); interval_t b_speed = sd->speed; b_max_hp = sd->status.max_hp; @@ -942,7 +951,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) b_max_weight = sd->max_weight; earray<int, ATTR, ATTR::COUNT> b_paramb = sd->paramb; earray<int, ATTR, ATTR::COUNT> b_parame = sd->paramc; - earray<skill_value, SkillID, MAX_SKILL> b_skill = sd->status.skill; + earray<SkillValue, SkillID, MAX_SKILL> b_skill = sd->status.skill; b_hit = sd->hit; b_flee = sd->flee; interval_t b_aspd = sd->aspd; @@ -964,10 +973,10 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) if (first & 1) { sd->weight = 0; - for (int i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { - if (sd->status.inventory[i].nameid == 0 - || sd->inventory_data[i] == NULL) + if (!sd->status.inventory[i].nameid + || sd->inventory_data[i] == nullptr) continue; sd->weight += sd->inventory_data[i]->weight * @@ -1035,8 +1044,8 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) for (EQUIP i : EQUIPs_noarrow) { - int index = sd->equip_index_maybe[i]; - if (index < 0) + IOff0 index = sd->equip_index_maybe[i]; + if (!index.ok()) continue; if (i == EQUIP::WEAPON && sd->equip_index_maybe[EQUIP::SHIELD] == index) continue; @@ -1060,7 +1069,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) if (sd->spellpower_bonus_target < 0) sd->spellpower_bonus_target = (sd->spellpower_bonus_target * 256) / - (min(128 + skill_power(sd, SkillID::TMW_ASTRAL_SOUL), 256)); + (std::min(128 + skill_power(sd, SkillID::TMW_ASTRAL_SOUL), 256)); #endif if (sd->spellpower_bonus_target < sd->spellpower_bonus_current) @@ -1071,8 +1080,8 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) // 装備品によるステータス変化はここで実行 for (EQUIP i : EQUIPs_noarrow) { - int index = sd->equip_index_maybe[i]; - if (index < 0) + IOff0 index = sd->equip_index_maybe[i]; + if (!index.ok()) continue; if (i == EQUIP::WEAPON && sd->equip_index_maybe[EQUIP::SHIELD] == index) continue; @@ -1099,11 +1108,11 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) { argrec_t arg[2] = { - {"@slotId", static_cast<int>(i)}, - {"@itemId", sd->inventory_data[index]->nameid}, + {"@slotId"_s, static_cast<int>(i)}, + {"@itemId"_s, unwrap<ItemNameId>(sd->inventory_data[index]->nameid)}, }; run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0), - sd->bl_id, 0, + sd->bl_id, BlockId(), arg); } sd->state.lr_flag = 0; @@ -1113,14 +1122,14 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) //二刀流武器以外 argrec_t arg[2] = { - {"@slotId", static_cast<int>(i)}, - {"@itemId", sd->inventory_data[index]->nameid}, + {"@slotId"_s, static_cast<int>(i)}, + {"@itemId"_s, unwrap<ItemNameId>(sd->inventory_data[index]->nameid)}, }; sd->watk += sd->inventory_data[index]->atk; sd->attackrange += sd->inventory_data[index]->range; run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0), - sd->bl_id, 0, + sd->bl_id, BlockId(), arg); } } @@ -1128,12 +1137,12 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) { argrec_t arg[2] = { - {"@slotId", static_cast<int>(i)}, - {"@itemId", sd->inventory_data[index]->nameid}, + {"@slotId"_s, static_cast<int>(i)}, + {"@itemId"_s, unwrap<ItemNameId>(sd->inventory_data[index]->nameid)}, }; sd->watk += sd->inventory_data[index]->atk; run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0), - sd->bl_id, 0, + sd->bl_id, BlockId(), arg); } } @@ -1147,20 +1156,20 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) sd->watk_2 += skill_power(sd, SkillID::TMW_BRAWLING) >> 3; // +25 for 200 } - int aidx = sd->equip_index_maybe[EQUIP::ARROW]; - if (aidx >= 0) - { // 矢 - int index = aidx; + IOff0 aidx = sd->equip_index_maybe[EQUIP::ARROW]; + if (aidx.ok()) + { + IOff0 index = aidx; if (sd->inventory_data[index]) { //まだ属性が入っていない argrec_t arg[2] = { - {"@slotId", static_cast<int>(EQUIP::ARROW)}, - {"@itemId", sd->inventory_data[index]->nameid}, + {"@slotId"_s, static_cast<int>(EQUIP::ARROW)}, + {"@itemId"_s, unwrap<ItemNameId>(sd->inventory_data[index]->nameid)}, }; sd->state.lr_flag = 2; run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0), - sd->bl_id, 0, + sd->bl_id, BlockId(), arg); sd->state.lr_flag = 0; sd->arrow_atk += sd->inventory_data[index]->atk; @@ -1189,7 +1198,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) sd->aspd_rate = 20; for (ATTR attr : ATTRs) - sd->paramc[attr] = max(0, sd->status.attrs[attr] + sd->paramb[attr] + sd->parame[attr]); + sd->paramc[attr] = std::max(0, sd->status.attrs[attr] + sd->paramb[attr] + sd->parame[attr]); if (sd->status.weapon == ItemLook::BOW || sd->status.weapon == ItemLook::_13 @@ -1206,7 +1215,6 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) } dstr = str / 10; sd->base_atk += str + dstr * dstr + dex / 5 + sd->paramc[ATTR::LUK] / 5; -//FPRINTF(stderr, "baseatk = %d = x + %d + %d + %d + %d\n", sd->base_atk, str, dstr*dstr, dex/5, sd->paramc[ATTR::LUK]/5); sd->matk1 += sd->paramc[ATTR::INT] + (sd->paramc[ATTR::INT] / 5) * (sd->paramc[ATTR::INT] / 5); sd->matk2 += sd->paramc[ATTR::INT] + (sd->paramc[ATTR::INT] / 7) * (sd->paramc[ATTR::INT] / 7); if (sd->matk1 < sd->matk2) @@ -1304,7 +1312,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) if (sd->attackrange > 2) { // [fate] ranged weapon? - sd->attackrange += min(skill_power(sd, SkillID::AC_OWL) / 60, 3); + sd->attackrange += std::min(skill_power(sd, SkillID::AC_OWL) / 60, 3); sd->hit += skill_power(sd, SkillID::AC_OWL) / 10; // 20 for 200 } @@ -1385,7 +1393,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) if (sd->speed_rate != 100) sd->speed = sd->speed * sd->speed_rate / 100; - sd->speed = std::max(sd->speed, std::chrono::milliseconds(1)); + sd->speed = std::max(sd->speed, 1_ms); if (aspd_rate != 100) sd->aspd = sd->aspd * aspd_rate / 100; @@ -1395,7 +1403,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) sd->aspd = std::max(sd->aspd, static_cast<interval_t>(battle_config.max_aspd)); sd->amotion = sd->aspd; sd->dmotion = std::chrono::milliseconds(800 - sd->paramc[ATTR::AGI] * 4); - sd->dmotion = std::max(sd->dmotion, std::chrono::milliseconds(400)); + sd->dmotion = std::max(sd->dmotion, 400_ms); if (sd->status.hp > sd->status.max_hp) sd->status.hp = sd->status.max_hp; @@ -1479,7 +1487,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) */ int pc_bonus(dumb_ptr<map_session_data> sd, SP type, int val) { - nullpo_ret(sd); + nullpo_retz(sd); switch (type) { @@ -1731,7 +1739,7 @@ int pc_bonus(dumb_ptr<map_session_data> sd, SP type, int val) break; default: if (battle_config.error_log) - PRINTF("pc_bonus: unknown type %d %d !\n", + PRINTF("pc_bonus: unknown type %d %d !\n"_fmt, type, val); break; } @@ -1744,7 +1752,7 @@ int pc_bonus(dumb_ptr<map_session_data> sd, SP type, int val) */ int pc_bonus2(dumb_ptr<map_session_data> sd, SP type, int type2, int val) { - nullpo_ret(sd); + nullpo_retz(sd); switch (type) { @@ -1776,7 +1784,7 @@ int pc_bonus2(dumb_ptr<map_session_data> sd, SP type, int type2, int val) #endif default: if (battle_config.error_log) - PRINTF("pc_bonus2: unknown type %d %d %d!\n", + PRINTF("pc_bonus2: unknown type %d %d %d!\n"_fmt, type, type2, val); break; } @@ -1789,12 +1797,12 @@ int pc_bonus2(dumb_ptr<map_session_data> sd, SP type, int type2, int val) */ int pc_skill(dumb_ptr<map_session_data> sd, SkillID id, int level, int flag) { - nullpo_ret(sd); + nullpo_retz(sd); if (level > MAX_SKILL_LEVEL) { if (battle_config.error_log) - PRINTF("support card skill only!\n"); + PRINTF("support card skill only!\n"_fmt); return 0; } if (!flag && (sd->status.skill[id].lv || level == 0)) @@ -1817,16 +1825,14 @@ int pc_skill(dumb_ptr<map_session_data> sd, SkillID id, int level, int flag) * 3万個制限にかかるか確認 *------------------------------------------ */ -ADDITEM pc_checkadditem(dumb_ptr<map_session_data> sd, int nameid, int amount) +ADDITEM pc_checkadditem(dumb_ptr<map_session_data> sd, ItemNameId nameid, int amount) { - int i; - nullpo_retr(ADDITEM::ZERO, sd); if (itemdb_isequip(nameid)) return ADDITEM::NEW; - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (sd->status.inventory[i].nameid == nameid) { @@ -1847,13 +1853,13 @@ ADDITEM pc_checkadditem(dumb_ptr<map_session_data> sd, int nameid, int amount) */ int pc_inventoryblank(dumb_ptr<map_session_data> sd) { - int i, b; + int b = 0; - nullpo_ret(sd); + nullpo_retz(sd); - for (i = 0, b = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { - if (sd->status.inventory[i].nameid == 0) + if (!sd->status.inventory[i].nameid) b++; } @@ -1866,7 +1872,7 @@ int pc_inventoryblank(dumb_ptr<map_session_data> sd) */ int pc_payzeny(dumb_ptr<map_session_data> sd, int zeny) { - nullpo_ret(sd); + nullpo_retz(sd); double z = sd->status.zeny; if (sd->status.zeny < zeny || z - zeny > MAX_ZENY) @@ -1883,7 +1889,7 @@ int pc_payzeny(dumb_ptr<map_session_data> sd, int zeny) */ int pc_getzeny(dumb_ptr<map_session_data> sd, int zeny) { - nullpo_ret(sd); + nullpo_retz(sd); double z = sd->status.zeny; if (z + zeny > MAX_ZENY) @@ -1901,30 +1907,27 @@ int pc_getzeny(dumb_ptr<map_session_data> sd, int zeny) * アイテムを探して、インデックスを返す *------------------------------------------ */ -int pc_search_inventory(dumb_ptr<map_session_data> sd, int item_id) +IOff0 pc_search_inventory(dumb_ptr<map_session_data> sd, ItemNameId item_id) { - int i; + nullpo_retr(IOff0::from(-1), sd); - nullpo_retr(-1, sd); - - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (sd->status.inventory[i].nameid == item_id && - (sd->status.inventory[i].amount > 0 || item_id == 0)) + (sd->status.inventory[i].amount > 0 || !item_id)) return i; } - return -1; + return IOff0::from(-1); } -int pc_count_all_items(dumb_ptr<map_session_data> player, int item_id) +int pc_count_all_items(dumb_ptr<map_session_data> player, ItemNameId item_id) { - int i; int count = 0; - nullpo_ret(player); + nullpo_retz(player); - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (player->status.inventory[i].nameid == item_id) count += player->status.inventory[i].amount; @@ -1933,14 +1936,14 @@ int pc_count_all_items(dumb_ptr<map_session_data> player, int item_id) return count; } -int pc_remove_items(dumb_ptr<map_session_data> player, int item_id, int count) +int pc_remove_items(dumb_ptr<map_session_data> player, ItemNameId item_id, int count) { - int i; - - nullpo_ret(player); + nullpo_retz(player); - for (i = 0; i < MAX_INVENTORY && count; i++) + for (IOff0 i : IOff0::iter()) { + if (!count) + break; if (player->status.inventory[i].nameid == item_id) { int to_delete = count; @@ -1964,29 +1967,30 @@ int pc_remove_items(dumb_ptr<map_session_data> player, int item_id, int count) * アイテム追加。個数のみitem構造体の数字を無視 *------------------------------------------ */ -PickupFail pc_additem(dumb_ptr<map_session_data> sd, struct item *item_data, +PickupFail pc_additem(dumb_ptr<map_session_data> sd, Item *item_data, int amount) { struct item_data *data; - int i, w; + int w; - MAP_LOG_PC(sd, "PICKUP %d %d", item_data->nameid, amount); + MAP_LOG_PC(sd, "PICKUP %d %d"_fmt, item_data->nameid, amount); nullpo_retr(PickupFail::BAD_ITEM, sd); nullpo_retr(PickupFail::BAD_ITEM, item_data); - if (item_data->nameid <= 0 || amount <= 0) + if (!item_data->nameid || amount <= 0) return PickupFail::BAD_ITEM; data = itemdb_search(item_data->nameid); if ((w = data->weight * amount) + sd->weight > sd->max_weight) return PickupFail::TOO_HEAVY; - i = MAX_INVENTORY; + IOff0 i = IOff0::from(MAX_INVENTORY); if (!itemdb_isequip2(data)) { - // 装 備品ではないので、既所有品なら個数のみ変化させる - for (i = 0; i < MAX_INVENTORY; i++) + // TODO see if there's any nicer way to preserve the foreach var + for (i = IOff0::from(0); i != IOff0::from(MAX_INVENTORY); ++i) + { if (sd->status.inventory[i].nameid == item_data->nameid) { if (sd->status.inventory[i].amount + amount > MAX_AMOUNT) @@ -1995,12 +1999,12 @@ PickupFail pc_additem(dumb_ptr<map_session_data> sd, struct item *item_data, clif_additem(sd, i, amount, PickupFail::OKAY); break; } + } } - if (i >= MAX_INVENTORY) + if (!i.ok()) { - // 装 備品か未所有品だったので空き欄へ追加 - i = pc_search_inventory(sd, 0); - if (i >= 0) + i = pc_search_inventory(sd, ItemNameId()); + if (i.ok()) { sd->status.inventory[i] = *item_data; @@ -2024,16 +2028,16 @@ PickupFail pc_additem(dumb_ptr<map_session_data> sd, struct item *item_data, * アイテムを減らす *------------------------------------------ */ -int pc_delitem(dumb_ptr<map_session_data> sd, int n, int amount, int type) +int pc_delitem(dumb_ptr<map_session_data> sd, IOff0 n, int amount, int type) { nullpo_retr(1, sd); - if (sd->trade_partner != 0) + if (sd->trade_partner) trade_tradecancel(sd); - if (sd->status.inventory[n].nameid == 0 || amount <= 0 + if (!sd->status.inventory[n].nameid || amount <= 0 || sd->status.inventory[n].amount < amount - || sd->inventory_data[n] == NULL) + || sd->inventory_data[n] == nullptr) return 1; sd->status.inventory[n].amount -= amount; @@ -2042,8 +2046,8 @@ int pc_delitem(dumb_ptr<map_session_data> sd, int n, int amount, int type) { if (bool(sd->status.inventory[n].equip)) pc_unequipitem(sd, n, CalcStatus::NOW); - sd->status.inventory[n] = item{}; - sd->inventory_data[n] = NULL; + sd->status.inventory[n] = Item{}; + sd->inventory_data[n] = nullptr; } if (!(type & 1)) clif_delitem(sd, n, amount); @@ -2057,14 +2061,14 @@ int pc_delitem(dumb_ptr<map_session_data> sd, int n, int amount, int type) * アイテムを落す *------------------------------------------ */ -int pc_dropitem(dumb_ptr<map_session_data> sd, int n, int amount) +int pc_dropitem(dumb_ptr<map_session_data> sd, IOff0 n, int amount) { nullpo_retr(1, sd); - if (sd->trade_partner != 0 || sd->npc_id != 0 || sd->state.storage_open) + if (sd->trade_partner || sd->npc_id || sd->state.storage_open) return 0; // no dropping while trading/npc/storage - if (n < 0 || n >= MAX_INVENTORY) + if (!n.ok()) return 0; if (amount <= 0) @@ -2072,13 +2076,13 @@ int pc_dropitem(dumb_ptr<map_session_data> sd, int n, int amount) pc_unequipinvyitem(sd, n, CalcStatus::NOW); - if (sd->status.inventory[n].nameid <= 0 || + if (!sd->status.inventory[n].nameid || sd->status.inventory[n].amount < amount || - sd->trade_partner != 0 || sd->status.inventory[n].amount <= 0) + sd->trade_partner || sd->status.inventory[n].amount <= 0) return 1; map_addflooritem(&sd->status.inventory[n], amount, sd->bl_m, sd->bl_x, sd->bl_y, - NULL, NULL, NULL); + nullptr, nullptr, nullptr); pc_delitem(sd, n, amount, 0); return 0; @@ -2090,9 +2094,9 @@ int pc_dropitem(dumb_ptr<map_session_data> sd, int n, int amount) */ static -int can_pick_item_up_from(dumb_ptr<map_session_data> self, int other_id) +int can_pick_item_up_from(dumb_ptr<map_session_data> self, BlockId other_id) { - struct party *p = party_search(self->status.party_id); + PartyPair p = party_search(self->status.party_id); /* From ourselves or from no-one? */ if (!self || self->bl_id == other_id || !other_id) @@ -2133,19 +2137,19 @@ int pc_takeitem(dumb_ptr<map_session_data> sd, dumb_ptr<flooritem_data> fitem) tick_t tick = gettick(); int can_take; - nullpo_ret(sd); - nullpo_ret(fitem); + nullpo_retz(sd); + nullpo_retz(fitem); /* Sometimes the owners reported to us are buggy: */ if (fitem->first_get_id == fitem->third_get_id || fitem->second_get_id == fitem->third_get_id) - fitem->third_get_id = 0; + fitem->third_get_id = BlockId(); if (fitem->first_get_id == fitem->second_get_id) { fitem->second_get_id = fitem->third_get_id; - fitem->third_get_id = 0; + fitem->third_get_id = BlockId(); } can_take = can_pick_item_up_from(sd, fitem->first_get_id); @@ -2167,7 +2171,7 @@ int pc_takeitem(dumb_ptr<map_session_data> sd, dumb_ptr<flooritem_data> fitem) PickupFail flag = pc_additem(sd, &fitem->item_data, fitem->item_data.amount); if (flag != PickupFail::OKAY) // 重量overで取得失敗 - clif_additem(sd, 0, 0, flag); + clif_additem(sd, IOff0::from(0), 0, flag); else { // 取得成功 @@ -2180,22 +2184,22 @@ int pc_takeitem(dumb_ptr<map_session_data> sd, dumb_ptr<flooritem_data> fitem) } /* Otherwise, we can't pick up */ - clif_additem(sd, 0, 0, PickupFail::DROP_STEAL); + clif_additem(sd, IOff0::from(0), 0, PickupFail::DROP_STEAL); return 0; } static -int pc_isUseitem(dumb_ptr<map_session_data> sd, int n) +int pc_isUseitem(dumb_ptr<map_session_data> sd, IOff0 n) { struct item_data *item; - int nameid; + ItemNameId nameid; - nullpo_ret(sd); + nullpo_retz(sd); item = sd->inventory_data[n]; nameid = sd->status.inventory[n].nameid; - if (item == NULL) + if (item == nullptr) return 0; if (itemdb_type(nameid) != ItemType::USE) return 0; @@ -2212,16 +2216,16 @@ int pc_isUseitem(dumb_ptr<map_session_data> sd, int n) * アイテムを使う *------------------------------------------ */ -int pc_useitem(dumb_ptr<map_session_data> sd, int n) +int pc_useitem(dumb_ptr<map_session_data> sd, IOff0 n) { int amount; nullpo_retr(1, sd); - if (n >= 0 && n < MAX_INVENTORY && sd->inventory_data[n]) + if (n.ok() && sd->inventory_data[n]) { amount = sd->status.inventory[n].amount; - if (sd->status.inventory[n].nameid <= 0 + if (!sd->status.inventory[n].nameid || sd->status.inventory[n].amount <= 0 || !pc_isUseitem(sd, n)) { @@ -2233,7 +2237,7 @@ int pc_useitem(dumb_ptr<map_session_data> sd, int n) clif_useitemack(sd, n, amount - 1, 1); pc_delitem(sd, n, 1, 1); - run_script(ScriptPointer(script, 0), sd->bl_id, 0); + run_script(ScriptPointer(script, 0), sd->bl_id, BlockId()); } return 0; @@ -2251,14 +2255,14 @@ int pc_setpos(dumb_ptr<map_session_data> sd, { MapName mapname_; - nullpo_ret(sd); + nullpo_retz(sd); if (sd->trade_partner) // 取引を中断する trade_tradecancel(sd); if (sd->state.storage_open) storage_storage_quit(sd); // 倉庫を開いてるなら保存する - if (sd->party_invite > 0) // パーティ勧誘を拒否する + if (sd->party_invite) // パーティ勧誘を拒否する party_reply_invite(sd, sd->party_invite_account, 0); skill_castcancel(sd, 0); // 詠唱中断 @@ -2314,7 +2318,7 @@ int pc_setpos(dumb_ptr<map_session_data> sd, if (x || y) { if (battle_config.error_log) - PRINTF("stacked (%d,%d)\n", x, y); + PRINTF("stacked (%d,%d)\n"_fmt, x, y); } do { @@ -2324,7 +2328,7 @@ int pc_setpos(dumb_ptr<map_session_data> sd, while (bool(read_gatp(m, x, y) & MapCell::UNWALKABLE)); } - if (sd->mapname_ && sd->bl_prev != NULL) + if (sd->mapname_ && sd->bl_prev != nullptr) { clif_clearchar(sd, clrtype); map_delblock(sd); @@ -2355,7 +2359,7 @@ int pc_randomwarp(dumb_ptr<map_session_data> sd, BeingRemoveWhy type) { int x, y, i = 0; - nullpo_ret(sd); + nullpo_retz(sd); map_local *m = sd->bl_m; @@ -2385,7 +2389,7 @@ int pc_can_reach(dumb_ptr<map_session_data> sd, int x, int y) { struct walkpath_data wpd; - nullpo_ret(sd); + nullpo_retz(sd); if (sd->bl_x == x && sd->bl_y == y) // 同じマス return 1; @@ -2422,14 +2426,14 @@ interval_t calc_next_walk_step(dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -void pc_walk(TimerData *, tick_t tick, int id, unsigned char data) +void pc_walk(TimerData *, tick_t tick, BlockId id, unsigned char data) { dumb_ptr<map_session_data> sd; int moveblock; int x, y, dx, dy; sd = map_id2sd(id); - if (sd == NULL) + if (sd == nullptr) return; if (sd->walkpath.path_pos >= sd->walkpath.path_len @@ -2497,10 +2501,10 @@ void pc_walk(TimerData *, tick_t tick, int id, unsigned char data) BL::NUL); // sd->walktimer = nullptr; - if (sd->status.party_id > 0) + if (sd->status.party_id) { // パーティのHP情報通知検査 - struct party *p = party_search(sd->status.party_id); - if (p != NULL) + PartyPair p = party_search(sd->status.party_id); + if (p) { int p_flag = 0; map_foreachinmovearea(std::bind(party_send_hp_check, ph::_1, sd->status.party_id, &p_flag), @@ -2517,14 +2521,14 @@ void pc_walk(TimerData *, tick_t tick, int id, unsigned char data) if (bool(map_getcell(sd->bl_m, x, y) & MapCell::NPC_NEAR)) npc_touch_areanpc(sd, sd->bl_m, x, y); else - sd->areanpc_id = 0; + sd->areanpc_id = BlockId(); } interval_t i = calc_next_walk_step(sd); if (i > interval_t::zero()) { i = i / 2; if (sd->walkpath.path_half == 0) - i = std::max(i, std::chrono::milliseconds(1)); + i = std::max(i, 1_ms); sd->walktimer = Timer(tick + i, std::bind(pc_walk, ph::_1, ph::_2, @@ -2570,7 +2574,7 @@ int pc_walktoxy_sub(dumb_ptr<map_session_data> sd) int pc_walktoxy(dumb_ptr<map_session_data> sd, int x, int y) { - nullpo_ret(sd); + nullpo_retz(sd); sd->to_x = x; sd->to_y = y; @@ -2598,7 +2602,7 @@ int pc_walktoxy(dumb_ptr<map_session_data> sd, int x, int y) */ int pc_stop_walking(dumb_ptr<map_session_data> sd, int type) { - nullpo_ret(sd); + nullpo_retz(sd); sd->walktimer.cancel(); @@ -2623,7 +2627,7 @@ void pc_touch_all_relevant_npcs(dumb_ptr<map_session_data> sd) if (bool(map_getcell(sd->bl_m, sd->bl_x, sd->bl_y) & MapCell::NPC_NEAR)) npc_touch_areanpc(sd, sd->bl_m, sd->bl_x, sd->bl_y); else - sd->areanpc_id = 0; + sd->areanpc_id = BlockId(); } /*========================================== @@ -2637,7 +2641,7 @@ int pc_movepos(dumb_ptr<map_session_data> sd, int dst_x, int dst_y) struct walkpath_data wpd; - nullpo_ret(sd); + nullpo_retz(sd); if (path_search(&wpd, sd->bl_m, sd->bl_x, sd->bl_y, dst_x, dst_y, 0)) return 1; @@ -2671,10 +2675,10 @@ int pc_movepos(dumb_ptr<map_session_data> sd, int dst_x, int dst_y) -dx, -dy, BL::NUL); - if (sd->status.party_id > 0) + if (sd->status.party_id) { // パーティのHP情報通知検査 - struct party *p = party_search(sd->status.party_id); - if (p != NULL) + PartyPair p = party_search(sd->status.party_id); + if (p) { int flag = 0; map_foreachinmovearea(std::bind(party_send_hp_check, ph::_1, sd->status.party_id, &flag), @@ -2701,7 +2705,7 @@ int pc_movepos(dumb_ptr<map_session_data> sd, int dst_x, int dst_y) */ int pc_checkskill(dumb_ptr<map_session_data> sd, SkillID skill_id) { - if (sd == NULL) + if (sd == nullptr) return 0; return sd->status.skill[skill_id].lv; @@ -2711,9 +2715,9 @@ int pc_checkskill(dumb_ptr<map_session_data> sd, SkillID skill_id) * 装 備品のチェック *------------------------------------------ */ -int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos) +IOff0 pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos) { - nullpo_retr(-1, sd); + nullpo_retr(IOff0::from(-1), sd); for (EQUIP i : EQUIPs) { @@ -2721,7 +2725,7 @@ int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos) return sd->equip_index_maybe[i]; } - return -1; + return IOff0::from(-1); } /*========================================== @@ -2729,7 +2733,7 @@ int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos) *------------------------------------------ */ static -void pc_attack_timer(TimerData *, tick_t tick, int id) +void pc_attack_timer(TimerData *, tick_t tick, BlockId id) { dumb_ptr<map_session_data> sd; dumb_ptr<block_list> bl; @@ -2737,14 +2741,14 @@ void pc_attack_timer(TimerData *, tick_t tick, int id) int dist, range; sd = map_id2sd(id); - if (sd == NULL) + if (sd == nullptr) return; - if (sd->bl_prev == NULL) + if (sd->bl_prev == nullptr) return; bl = map_id2bl(sd->attacktarget); - if (bl == NULL || bl->bl_prev == NULL) + if (bl == nullptr || bl->bl_prev == nullptr) return; if (bl->bl_type == BL::PC && pc_isdead(bl->is_player())) @@ -2760,7 +2764,7 @@ void pc_attack_timer(TimerData *, tick_t tick, int id) return; Option *opt = battle_get_option(bl); - if (opt != NULL && bool(*opt & Option::REAL_ANY_HIDE)) + if (opt != nullptr && bool(*opt & Option::REAL_ANY_HIDE)) return; if (!battle_config.skill_delay_attack_enable) @@ -2836,19 +2840,19 @@ void pc_attack_timer(TimerData *, tick_t tick, int id) * typeが1なら継続攻撃 *------------------------------------------ */ -int pc_attack(dumb_ptr<map_session_data> sd, int target_id, int type) +int pc_attack(dumb_ptr<map_session_data> sd, BlockId target_id, int type) { dumb_ptr<block_list> bl; - nullpo_ret(sd); + nullpo_retz(sd); bl = map_id2bl(target_id); - if (bl == NULL) + if (bl == nullptr) return 1; if (bl->bl_type == BL::NPC) { // monster npcs [Valaris] - npc_click(sd, RFIFOL(sd->sess, 2)); + npc_click(sd, target_id); return 0; } @@ -2860,7 +2864,7 @@ int pc_attack(dumb_ptr<map_session_data> sd, int target_id, int type) sd->state.attack_continue = type; interval_t d = sd->attackabletime - gettick(); - if (d > interval_t::zero() && d < std::chrono::seconds(2)) + if (d > interval_t::zero() && d < 2_s) { // 攻撃delay中 sd->attacktimer = Timer(sd->attackabletime, std::bind(pc_attack_timer, ph::_1, ph::_2, @@ -2881,11 +2885,11 @@ int pc_attack(dumb_ptr<map_session_data> sd, int target_id, int type) */ int pc_stopattack(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); sd->attacktimer.cancel(); - sd->attacktarget = 0; + sd->attacktarget = BlockId(); sd->state.attack_continue = 0; return 0; @@ -2896,7 +2900,7 @@ int pc_checkbaselevelup(dumb_ptr<map_session_data> sd) { int next = pc_nextbaseexp(sd); - nullpo_ret(sd); + nullpo_retz(sd); if (sd->status.base_exp >= next && next > 0) { @@ -2915,7 +2919,7 @@ int pc_checkbaselevelup(dumb_ptr<map_session_data> sd) //レベルアップしたのでパーティー情報を更新する //(公平範囲チェック) party_send_movemap(sd); - MAP_LOG_XP(sd, "LEVELUP"); + MAP_LOG_XP(sd, "LEVELUP"_fmt); return 1; } @@ -2937,8 +2941,7 @@ int pc_skillpt_potential(dumb_ptr<map_session_data> sd) { int potential = 0; - for (SkillID skill_id = SkillID(); skill_id < MAX_SKILL; - skill_id = SkillID(uint16_t(skill_id) + 1)) + for (SkillID skill_id : erange(SkillID(), MAX_SKILL)) if (sd->status.skill[skill_id].lv && sd->status.skill[skill_id].lv < skill_db[skill_id].max_raise) potential += RAISE_COST(skill_db[skill_id].max_raise) @@ -2952,7 +2955,7 @@ int pc_checkjoblevelup(dumb_ptr<map_session_data> sd) { int next = pc_nextjobexp(sd); - nullpo_ret(sd); + nullpo_retz(sd); if (sd->status.job_exp >= next && next > 0) { @@ -2971,7 +2974,7 @@ int pc_checkjoblevelup(dumb_ptr<map_session_data> sd) clif_updatestatus(sd, SP::SKILLPOINT); pc_calcstatus(sd, 0); - MAP_LOG_PC(sd, "SKILLPOINTS-UP %d", sd->status.skill_point); + MAP_LOG_PC(sd, "SKILLPOINTS-UP %d"_fmt, sd->status.skill_point); if (sd->status.job_level < 250 && sd->status.job_level < sd->status.base_level * 2) @@ -2987,21 +2990,21 @@ int pc_checkjoblevelup(dumb_ptr<map_session_data> sd) int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp, PC_GAINEXP_REASON reason) { - nullpo_ret(sd); + nullpo_retz(sd); - if (sd->bl_prev == NULL || pc_isdead(sd)) + if (sd->bl_prev == nullptr || pc_isdead(sd)) return 0; - earray<const char *, PC_GAINEXP_REASON, PC_GAINEXP_REASON::COUNT> reasons //= + earray<LString, PC_GAINEXP_REASON, PC_GAINEXP_REASON::COUNT> reasons //= {{ - "KILLXP", - "HEALXP", - "SCRIPTXP", - "SHAREXP", + "KILLXP"_s, + "HEALXP"_s, + "SCRIPTXP"_s, + "SHAREXP"_s, /* Insert new types here */ - "UNKNOWNXP" + "UNKNOWNXP"_s }}; - MAP_LOG_PC(sd, "GAINXP %d %d %s", base_exp, job_exp, reasons[reason]); + MAP_LOG_PC(sd, "GAINXP %d %d %s"_fmt, base_exp, job_exp, reasons[reason]); if (!battle_config.multi_level_up && pc_nextbaseafter(sd)) { @@ -3029,7 +3032,8 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp, if (sd->status.base_exp < 0) sd->status.base_exp = 0; - while (pc_checkbaselevelup(sd)); + while (pc_checkbaselevelup(sd)) + {} clif_updatestatus(sd, SP::BASEEXP); if (!battle_config.multi_level_up && pc_nextjobafter(sd)) @@ -3046,14 +3050,15 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp, if (sd->status.job_exp < 0) sd->status.job_exp = 0; - while (pc_checkjoblevelup(sd)); + while (pc_checkjoblevelup(sd)) + {} clif_updatestatus(sd, SP::JOBEXP); if (battle_config.disp_experience) { AString output = STRPRINTF( - "Experienced Gained Base:%d Job:%d", + "Experienced Gained Base:%d Job:%d"_fmt, base_exp, job_exp); clif_displaymessage(sd->sess, output); } @@ -3064,7 +3069,7 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp, int pc_extract_healer_exp(dumb_ptr<map_session_data> sd, int max) { int amount; - nullpo_ret(sd); + nullpo_retz(sd); amount = sd->heal_xp; if (max < amount) @@ -3080,7 +3085,7 @@ int pc_extract_healer_exp(dumb_ptr<map_session_data> sd, int max) */ int pc_nextbaseexp(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); if (sd->status.base_level >= MAX_LEVEL || sd->status.base_level <= 0) return 0; @@ -3108,7 +3113,7 @@ int pc_nextjobexp(dumb_ptr<map_session_data> sd) */ int pc_nextbaseafter(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); if (sd->status.base_level >= MAX_LEVEL || sd->status.base_level <= 0) return 0; @@ -3122,7 +3127,7 @@ int pc_nextbaseafter(dumb_ptr<map_session_data> sd) */ int pc_nextjobafter(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); if (sd->status.job_level >= MAX_LEVEL || sd->status.job_level <= 0) return 0; @@ -3156,7 +3161,7 @@ int pc_statusup(dumb_ptr<map_session_data> sd, SP type) { int need, val = 0; - nullpo_ret(sd); + nullpo_retz(sd); if (SP::STR <= type && type <= SP::LUK) val = sd->status.attrs[sp_to_attr(type)]; @@ -3181,7 +3186,7 @@ int pc_statusup(dumb_ptr<map_session_data> sd, SP type) pc_calcstatus(sd, 0); clif_statusupack(sd, type, 1, val); - MAP_LOG_STATS(sd, "STATUP"); + MAP_LOG_STATS(sd, "STATUP"_fmt); return 0; } @@ -3192,7 +3197,7 @@ int pc_statusup(dumb_ptr<map_session_data> sd, SP type) */ int pc_statusup2(dumb_ptr<map_session_data> sd, SP type, int val) { - nullpo_ret(sd); + nullpo_retz(sd); if (type < SP::STR || type > SP::LUK) { @@ -3208,7 +3213,7 @@ int pc_statusup2(dumb_ptr<map_session_data> sd, SP type, int val) clif_updatestatus(sd, type); pc_calcstatus(sd, 0); clif_statusupack(sd, type, 1, val); - MAP_LOG_STATS(sd, "STATUP2"); + MAP_LOG_STATS(sd, "STATUP2"_fmt); return 0; } @@ -3219,7 +3224,7 @@ int pc_statusup2(dumb_ptr<map_session_data> sd, SP type, int val) */ int pc_skillup(dumb_ptr<map_session_data> sd, SkillID skill_num) { - nullpo_ret(sd); + nullpo_retz(sd); if (sd->status.skill[skill_num].lv && sd->status.skill_point >= sd->status.skill[skill_num].lv @@ -3232,7 +3237,7 @@ int pc_skillup(dumb_ptr<map_session_data> sd, SkillID skill_num) clif_skillup(sd, skill_num); clif_updatestatus(sd, SP::SKILLPOINT); clif_skillinfoblock(sd); - MAP_LOG_PC(sd, "SKILLUP %d %d %d", + MAP_LOG_PC(sd, "SKILLUP %d %d %d"_fmt, skill_num, sd->status.skill[skill_num].lv, skill_power(sd, skill_num)); } @@ -3246,7 +3251,7 @@ int pc_skillup(dumb_ptr<map_session_data> sd, SkillID skill_num) */ int pc_resetlvl(dumb_ptr<map_session_data> sd, int type) { - nullpo_ret(sd); + nullpo_retz(sd); for (SkillID i : erange(SkillID(1), MAX_SKILL)) { @@ -3309,13 +3314,13 @@ int pc_resetlvl(dumb_ptr<map_session_data> sd, int type) for (EQUIP i : EQUIPs) { // unequip items that can't be equipped by base 1 [Valaris] - short *idx = &sd->equip_index_maybe[i]; - if (*idx >= 0) + IOff0 *idx = &sd->equip_index_maybe[i]; + if ((*idx).ok()) { if (!pc_isequip(sd, *idx)) { pc_unequipitem(sd, *idx, CalcStatus::LATER); - *idx = -1; + *idx = IOff0::from(-1); } } } @@ -3323,7 +3328,7 @@ int pc_resetlvl(dumb_ptr<map_session_data> sd, int type) clif_skillinfoblock(sd); pc_calcstatus(sd, 0); - MAP_LOG_STATS(sd, "STATRESET"); + MAP_LOG_STATS(sd, "STATRESET"_fmt); return 0; } @@ -3335,7 +3340,7 @@ int pc_resetlvl(dumb_ptr<map_session_data> sd, int type) int pc_resetstate(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); sd->status.status_point = stat_p[sd->status.base_level - 1]; @@ -3361,7 +3366,7 @@ int pc_resetskill(dumb_ptr<map_session_data> sd) { int skill; - nullpo_ret(sd); + nullpo_retz(sd); sd->status.skill_point += pc_calc_skillpoint(sd); @@ -3386,7 +3391,7 @@ int pc_resetskill(dumb_ptr<map_session_data> sd) int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd, int damage) { - nullpo_ret(sd); + nullpo_retz(sd); // 既に死んでいたら無効 if (pc_isdead(sd)) @@ -3401,17 +3406,17 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd, { if (src->bl_type == BL::PC) { - MAP_LOG_PC(sd, "INJURED-BY PC%d FOR %d", - src->is_player()->status_key.char_id, - damage); + MAP_LOG_PC(sd, "INJURED-BY PC%d FOR %d"_fmt, + src->is_player()->status_key.char_id, + damage); } else { - MAP_LOG_PC(sd, "INJURED-BY MOB%d FOR %d", src->bl_id, damage); + MAP_LOG_PC(sd, "INJURED-BY MOB%d FOR %d"_fmt, src->bl_id, damage); } } else - MAP_LOG_PC(sd, "INJURED-BY null FOR %d", damage); + MAP_LOG_PC(sd, "INJURED-BY null FOR %d"_fmt, damage); pc_stop_walking(sd, 3); // 演奏/ダンスの中断 @@ -3427,17 +3432,17 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd, sd->canlog_tick = gettick(); - if (sd->status.party_id > 0) + if (sd->status.party_id) { // on-the-fly party hp updates [Valaris] - struct party *p = party_search(sd->status.party_id); - if (p != NULL) + PartyPair p = party_search(sd->status.party_id); + if (p) clif_party_hp(p, sd); } // end addition [Valaris] return 0; } - MAP_LOG_PC(sd, "DEAD%s", ""); + MAP_LOG_PC(sd, "DEAD%s"_fmt, ""_s); // Character is dead! @@ -3452,7 +3457,7 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd, pc_stop_walking(sd, 0); skill_castcancel(sd, 0); // 詠唱の中止 clif_clearchar(sd, BeingRemoveWhy::DEAD); - pc_setglobalreg(sd, stringish<VarName>("PC_DIE_COUNTER"), ++sd->die_counter); //死にカウンター書き込み + pc_setglobalreg(sd, stringish<VarName>("PC_DIE_COUNTER"_s), ++sd->die_counter); //死にカウンター書き込み skill_status_change_clear(sd, 0); // ステータス異常を解除する clif_updatestatus(sd, SP::HP); pc_calcstatus(sd, 0); @@ -3544,14 +3549,14 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd, // [Fate] PK death, trigger scripts argrec_t arg[3] = { - {"@killerrid", src->bl_id}, - {"@victimrid", sd->bl_id}, - {"@victimlvl", sd->status.base_level}, + {"@killerrid"_s, static_cast<int32_t>(unwrap<BlockId>(src->bl_id))}, + {"@victimrid"_s, static_cast<int32_t>(unwrap<BlockId>(sd->bl_id))}, + {"@victimlvl"_s, sd->status.base_level}, }; - npc_event_doall_l(stringish<ScriptLabel>("OnPCKilledEvent"), sd->bl_id, arg); - npc_event_doall_l(stringish<ScriptLabel>("OnPCKillEvent"), src->bl_id, arg); + npc_event_doall_l(stringish<ScriptLabel>("OnPCKilledEvent"_s), sd->bl_id, arg); + npc_event_doall_l(stringish<ScriptLabel>("OnPCKillEvent"_s), src->bl_id, arg); } - npc_event_doall_l(stringish<ScriptLabel>("OnPCDieEvent"), sd->bl_id, nullptr); + npc_event_doall_l(stringish<ScriptLabel>("OnPCDieEvent"_s), sd->bl_id, nullptr); return 0; } @@ -3567,7 +3572,7 @@ int pc_readparam(dumb_ptr<map_session_data> sd, SP type) { int val = 0; - nullpo_ret(sd); + nullpo_retz(sd); switch (type) { @@ -3587,7 +3592,7 @@ int pc_readparam(dumb_ptr<map_session_data> sd, SP type) val = sd->status.job_level; break; case SP::CLASS: - val = sd->status.species; + val = unwrap<Species>(sd->status.species); break; case SP::SEX: val = static_cast<uint8_t>(sd->sex); @@ -3643,7 +3648,7 @@ int pc_setparam(dumb_ptr<map_session_data> sd, SP type, int val) { int i = 0, up_level = 50; - nullpo_ret(sd); + nullpo_retz(sd); switch (type) { @@ -3691,7 +3696,7 @@ int pc_setparam(dumb_ptr<map_session_data> sd, SP type, int val) clif_updatestatus(sd, type); break; case SP::CLASS: - sd->status.species = val; + sd->status.species = wrap<Species>(val); break; case SP::SKILLPOINT: sd->status.skill_point = val; @@ -3762,10 +3767,7 @@ int pc_setparam(dumb_ptr<map_session_data> sd, SP type, int val) */ int pc_heal(dumb_ptr<map_session_data> sd, int hp, int sp) { -// if(battle_config.battle_log) -// PRINTF("heal %d %d\n",hp,sp); - - nullpo_ret(sd); + nullpo_retz(sd); if (pc_checkoverhp(sd)) { @@ -3786,7 +3788,7 @@ int pc_heal(dumb_ptr<map_session_data> sd, int hp, int sp) if (sd->status.hp <= 0) { sd->status.hp = 0; - pc_damage(NULL, sd, 1); + pc_damage(nullptr, sd, 1); hp = 0; } sd->status.sp += sp; @@ -3797,10 +3799,10 @@ int pc_heal(dumb_ptr<map_session_data> sd, int hp, int sp) if (sp) clif_updatestatus(sd, SP::SP); - if (sd->status.party_id > 0) + if (sd->status.party_id) { // on-the-fly party hp updates [Valaris] - struct party *p = party_search(sd->status.party_id); - if (p != NULL) + PartyPair p = party_search(sd->status.party_id); + if (p) clif_party_hp(p, sd); } // end addition [Valaris] @@ -3847,9 +3849,9 @@ void pc_heal_quick_accumulate(int new_amount, int average_speed = ((new_speed * new_amount) + (current_speed * current_amount)) / (current_amount + new_amount); // new_amount > 0, current_amount >= 0 quick_regen->speed = average_speed; - quick_regen->amount = min(current_amount + new_amount, max); + quick_regen->amount = std::min(current_amount + new_amount, max); - quick_regen->tickdelay = min(quick_regen->speed, quick_regen->tickdelay); + quick_regen->tickdelay = std::min(quick_regen->speed, quick_regen->tickdelay); } int pc_itemheal(dumb_ptr<map_session_data> sd, int hp, int sp) @@ -3884,7 +3886,7 @@ int pc_itemheal(dumb_ptr<map_session_data> sd, int hp, int sp) static int pc_itemheal_effect(dumb_ptr<map_session_data> sd, int hp, int sp) { - nullpo_ret(sd); + nullpo_retz(sd); if (pc_checkoverhp(sd)) { @@ -3914,7 +3916,7 @@ int pc_itemheal_effect(dumb_ptr<map_session_data> sd, int hp, int sp) if (sd->status.hp <= 0) { sd->status.hp = 0; - pc_damage(NULL, sd, 1); + pc_damage(nullptr, sd, 1); hp = 0; } sd->status.sp += sp; @@ -3934,7 +3936,7 @@ int pc_itemheal_effect(dumb_ptr<map_session_data> sd, int hp, int sp) */ int pc_percentheal(dumb_ptr<map_session_data> sd, int hp, int sp) { - nullpo_ret(sd); + nullpo_retz(sd); if (pc_checkoverhp(sd)) { @@ -3955,7 +3957,7 @@ int pc_percentheal(dumb_ptr<map_session_data> sd, int hp, int sp) else if (hp <= -100) { sd->status.hp = 0; - pc_damage(NULL, sd, 1); + pc_damage(nullptr, sd, 1); } else { @@ -3965,7 +3967,7 @@ int pc_percentheal(dumb_ptr<map_session_data> sd, int hp, int sp) if (sd->status.hp <= 0) { sd->status.hp = 0; - pc_damage(NULL, sd, 1); + pc_damage(nullptr, sd, 1); hp = 0; } } @@ -4003,7 +4005,7 @@ int pc_percentheal(dumb_ptr<map_session_data> sd, int hp, int sp) */ int pc_changelook(dumb_ptr<map_session_data> sd, LOOK type, int val) { - nullpo_ret(sd); + nullpo_retz(sd); switch (type) { @@ -4014,13 +4016,13 @@ int pc_changelook(dumb_ptr<map_session_data> sd, LOOK type, int val) sd->status.weapon = static_cast<ItemLook>(static_cast<uint16_t>(val)); break; case LOOK::HEAD_BOTTOM: - sd->status.head_bottom = val; + sd->status.head_bottom = wrap<ItemNameId>(val); break; case LOOK::HEAD_TOP: - sd->status.head_top = val; + sd->status.head_top = wrap<ItemNameId>(val); break; case LOOK::HEAD_MID: - sd->status.head_mid = val; + sd->status.head_mid = wrap<ItemNameId>(val); break; case LOOK::HAIR_COLOR: sd->status.hair_color = val; @@ -4029,7 +4031,7 @@ int pc_changelook(dumb_ptr<map_session_data> sd, LOOK type, int val) sd->status.clothes_color = val; break; case LOOK::SHIELD: - sd->status.shield = val; + sd->status.shield = wrap<ItemNameId>(val); break; case LOOK::SHOES: break; @@ -4045,7 +4047,7 @@ int pc_changelook(dumb_ptr<map_session_data> sd, LOOK type, int val) */ int pc_setoption(dumb_ptr<map_session_data> sd, Option type) { - nullpo_ret(sd); + nullpo_retz(sd); sd->status.option = type; clif_changeoption(sd); @@ -4060,7 +4062,7 @@ int pc_setoption(dumb_ptr<map_session_data> sd, Option type) */ int pc_readreg(dumb_ptr<map_session_data> sd, SIR reg) { - nullpo_ret(sd); + nullpo_retz(sd); return sd->regm.get(reg); } @@ -4116,7 +4118,7 @@ int pc_readglobalreg(dumb_ptr<map_session_data> sd, VarName reg) { int i; - nullpo_ret(sd); + nullpo_retz(sd); assert (sd->status.global_reg_num < GLOBAL_REG_NUM); for (i = 0; i < sd->status.global_reg_num; i++) @@ -4136,10 +4138,10 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, VarName reg, int val) { int i; - nullpo_ret(sd); + nullpo_retz(sd); //PC_DIE_COUNTERがスクリプトなどで変更された時の処理 - if (reg == stringish<VarName>("PC_DIE_COUNTER") && sd->die_counter != val) + if (reg == stringish<VarName>("PC_DIE_COUNTER"_s) && sd->die_counter != val) { sd->die_counter = val; pc_calcstatus(sd, 0); @@ -4175,7 +4177,7 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, VarName reg, int val) return 0; } if (battle_config.error_log) - PRINTF("pc_setglobalreg : couldn't set %s (GLOBAL_REG_NUM = %d)\n", + PRINTF("pc_setglobalreg : couldn't set %s (GLOBAL_REG_NUM = %d)\n"_fmt, reg, GLOBAL_REG_NUM); return 1; @@ -4189,7 +4191,7 @@ int pc_readaccountreg(dumb_ptr<map_session_data> sd, VarName reg) { int i; - nullpo_ret(sd); + nullpo_retz(sd); assert (sd->status.account_reg_num < ACCOUNT_REG_NUM); for (i = 0; i < sd->status.account_reg_num; i++) @@ -4209,7 +4211,7 @@ int pc_setaccountreg(dumb_ptr<map_session_data> sd, VarName reg, int val) { int i; - nullpo_ret(sd); + nullpo_retz(sd); if (val == 0) { @@ -4244,7 +4246,7 @@ int pc_setaccountreg(dumb_ptr<map_session_data> sd, VarName reg, int val) return 0; } if (battle_config.error_log) - PRINTF("pc_setaccountreg : couldn't set %s (ACCOUNT_REG_NUM = %d)\n", + PRINTF("pc_setaccountreg : couldn't set %s (ACCOUNT_REG_NUM = %zu)\n"_fmt, reg, ACCOUNT_REG_NUM); return 1; @@ -4258,7 +4260,7 @@ int pc_readaccountreg2(dumb_ptr<map_session_data> sd, VarName reg) { int i; - nullpo_ret(sd); + nullpo_retz(sd); for (i = 0; i < sd->status.account_reg2_num; i++) { @@ -4312,8 +4314,8 @@ int pc_setaccountreg2(dumb_ptr<map_session_data> sd, VarName reg, int val) return 0; } if (battle_config.error_log) - PRINTF("pc_setaccountreg2 : couldn't set %s (ACCOUNT_REG2_NUM = %d)\n", - reg, ACCOUNT_REG2_NUM); + PRINTF("pc_setaccountreg2 : couldn't set %s (ACCOUNT_REG2_NUM = %zu)\n"_fmt, + reg, ACCOUNT_REG2_NUM); return 1; } @@ -4323,10 +4325,10 @@ int pc_setaccountreg2(dumb_ptr<map_session_data> sd, VarName reg, int val) *------------------------------------------ */ static -void pc_eventtimer(TimerData *, tick_t, int id, NpcEvent data) +void pc_eventtimer(TimerData *, tick_t, BlockId id, NpcEvent data) { dumb_ptr<map_session_data> sd = map_id2sd(id); - assert (sd != NULL); + assert (sd != nullptr); npc_event(sd, data, 0); } @@ -4339,7 +4341,7 @@ int pc_addeventtimer(dumb_ptr<map_session_data> sd, interval_t tick, NpcEvent na { int i; - nullpo_ret(sd); + nullpo_retz(sd); for (i = 0; i < MAX_EVENTTIMER; i++) if (!sd->eventtimer[i]) @@ -4362,7 +4364,7 @@ int pc_addeventtimer(dumb_ptr<map_session_data> sd, interval_t tick, NpcEvent na */ int pc_cleareventtimer(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); for (int i = 0; i < MAX_EVENTTIMER; i++) sd->eventtimer[i].cancel(); @@ -4378,7 +4380,7 @@ int pc_cleareventtimer(dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -int pc_signal_advanced_equipment_change(dumb_ptr<map_session_data> sd, int n) +int pc_signal_advanced_equipment_change(dumb_ptr<map_session_data> sd, IOff0 n) { if (bool(sd->status.inventory[n].equip & EPOS::SHOES)) clif_changelook(sd, LOOK::SHOES, 0); @@ -4393,17 +4395,17 @@ int pc_signal_advanced_equipment_change(dumb_ptr<map_session_data> sd, int n) return 0; } -int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS) +int pc_equipitem(dumb_ptr<map_session_data> sd, IOff0 n, EPOS) { - int nameid; + ItemNameId nameid; struct item_data *id; //ソス]ソスソスソスソスソス{ソスqソスフ場合ソスフ鯉ソスソスフ職ソスニゑソスソスZソスoソスソスソスソス - nullpo_ret(sd); + nullpo_retz(sd); - if (n < 0 || n >= MAX_INVENTORY) + if (!n.ok()) { - clif_equipitemack(sd, 0, EPOS::ZERO, 0); + clif_equipitemack(sd, IOff0::from(0), EPOS::ZERO, 0); return 0; } @@ -4414,7 +4416,7 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS) EPOS pos = pc_equippoint(sd, n); if (battle_config.battle_log) - PRINTF("equip %d (%d) %x:%x\n", + PRINTF("equip %d (%d) %x:%x\n"_fmt, nameid, n, id->equip, pos); if (!pc_isequip(sd, n) || pos == EPOS::ZERO) { @@ -4428,11 +4430,11 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS) { // アクセサリ用例外処理 EPOS epor = EPOS::ZERO; - int midx = sd->equip_index_maybe[EQUIP::MISC2]; - int cidx = sd->equip_index_maybe[EQUIP::CAPE]; - if (midx >= 0) + IOff0 midx = sd->equip_index_maybe[EQUIP::MISC2]; + IOff0 cidx = sd->equip_index_maybe[EQUIP::CAPE]; + if (midx.ok()) epor |= sd->status.inventory[midx].equip; - if (cidx >= 0) + if (cidx.ok()) epor |= sd->status.inventory[cidx].equip; epor &= (EPOS::MISC2 | EPOS::CAPE); pos = (epor == EPOS::CAPE ? EPOS::MISC2 : EPOS::CAPE); @@ -4442,8 +4444,8 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS) { if (bool(pos & equip_pos[i])) { - short *idx = &sd->equip_index_maybe[i]; - if (*idx >= 0) //Slot taken, remove item from there. + IOff0 *idx = &sd->equip_index_maybe[i]; + if ((*idx).ok()) //Slot taken, remove item from there. pc_unequipitem(sd, *idx, CalcStatus::LATER); *idx = n; } @@ -4468,7 +4470,7 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS) } sd->status.inventory[n].equip = pos; - int view_i = 0; + ItemNameId view_i; ItemLook view_l = ItemLook::NONE; // TODO: This is ugly. if (sd->inventory_data[n]) @@ -4495,7 +4497,7 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS) { if (sd->inventory_data[n]->type == ItemType::WEAPON) { - sd->status.shield = 0; + sd->status.shield = ItemNameId(); if (sd->status.inventory[n].equip == EPOS::SHIELD) sd->weapontype2 = view_l; } @@ -4507,26 +4509,26 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS) } else { - sd->status.shield = 0; + sd->status.shield = ItemNameId(); sd->weapontype2 = ItemLook::NONE; } pc_calcweapontype(sd); - clif_changelook(sd, LOOK::SHIELD, sd->status.shield); + clif_changelook(sd, LOOK::SHIELD, unwrap<ItemNameId>(sd->status.shield)); } if (bool(sd->status.inventory[n].equip & EPOS::LEGS)) { sd->status.head_bottom = view_i; - clif_changelook(sd, LOOK::HEAD_BOTTOM, sd->status.head_bottom); + clif_changelook(sd, LOOK::HEAD_BOTTOM, unwrap<ItemNameId>(sd->status.head_bottom)); } if (bool(sd->status.inventory[n].equip & EPOS::HAT)) { sd->status.head_top = view_i; - clif_changelook(sd, LOOK::HEAD_TOP, sd->status.head_top); + clif_changelook(sd, LOOK::HEAD_TOP, unwrap<ItemNameId>(sd->status.head_top)); } if (bool(sd->status.inventory[n].equip & EPOS::TORSO)) { sd->status.head_mid = view_i; - clif_changelook(sd, LOOK::HEAD_MID, sd->status.head_mid); + clif_changelook(sd, LOOK::HEAD_MID, unwrap<ItemNameId>(sd->status.head_mid)); } pc_signal_advanced_equipment_change(sd, n); @@ -4539,14 +4541,14 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS) * 装 備した物を外す *------------------------------------------ */ -int pc_unequipitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type) +int pc_unequipitem(dumb_ptr<map_session_data> sd, IOff0 n, CalcStatus type) { - nullpo_ret(sd); + nullpo_retz(sd); // -- moonsoul (if player is berserk then cannot unequip) // if (battle_config.battle_log) - PRINTF("unequip %d %x:%x\n", + PRINTF("unequip %d %x:%x\n"_fmt, n, pc_equippoint(sd, n), sd->status.inventory[n].equip); if (bool(sd->status.inventory[n].equip)) @@ -4554,7 +4556,7 @@ int pc_unequipitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type) for (EQUIP i : EQUIPs) { if (bool(sd->status.inventory[n].equip & equip_pos[i])) - sd->equip_index_maybe[i] = -1; + sd->equip_index_maybe[i] = IOff0::from(-1); } if (bool(sd->status.inventory[n].equip & EPOS::WEAPON)) { @@ -4565,26 +4567,25 @@ int pc_unequipitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type) } if (bool(sd->status.inventory[n].equip & EPOS::SHIELD)) { - sd->status.shield = 0; + sd->status.shield = ItemNameId(); sd->weapontype2 = ItemLook::NONE; pc_calcweapontype(sd); - clif_changelook(sd, LOOK::SHIELD, sd->status.shield); + clif_changelook(sd, LOOK::SHIELD, unwrap<ItemNameId>(sd->status.shield)); } if (bool(sd->status.inventory[n].equip & EPOS::LEGS)) { - sd->status.head_bottom = 0; - clif_changelook(sd, LOOK::HEAD_BOTTOM, - sd->status.head_bottom); + sd->status.head_bottom = ItemNameId(); + clif_changelook(sd, LOOK::HEAD_BOTTOM, unwrap<ItemNameId>(sd->status.head_bottom)); } if (bool(sd->status.inventory[n].equip & EPOS::HAT)) { - sd->status.head_top = 0; - clif_changelook(sd, LOOK::HEAD_TOP, sd->status.head_top); + sd->status.head_top = ItemNameId(); + clif_changelook(sd, LOOK::HEAD_TOP, unwrap<ItemNameId>(sd->status.head_top)); } if (bool(sd->status.inventory[n].equip & EPOS::TORSO)) { - sd->status.head_mid = 0; - clif_changelook(sd, LOOK::HEAD_MID, sd->status.head_mid); + sd->status.head_mid = ItemNameId(); + clif_changelook(sd, LOOK::HEAD_MID, unwrap<ItemNameId>(sd->status.head_mid)); } pc_signal_advanced_equipment_change(sd, n); @@ -4603,7 +4604,7 @@ int pc_unequipitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type) return 0; } -int pc_unequipinvyitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type) +int pc_unequipinvyitem(dumb_ptr<map_session_data> sd, IOff0 n, CalcStatus type) { nullpo_retr(1, sd); @@ -4615,7 +4616,7 @@ int pc_unequipinvyitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type) { //Slot taken, remove item from there. pc_unequipitem(sd, sd->equip_index_maybe[i], type); - sd->equip_index_maybe[i] = -1; + sd->equip_index_maybe[i] = IOff0::from(-1); } } @@ -4629,30 +4630,31 @@ int pc_unequipinvyitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type) */ int pc_checkitem(dumb_ptr<map_session_data> sd) { - int i, j, k, id, calc_flag = 0; + int calc_flag = 0; - nullpo_ret(sd); + nullpo_retz(sd); - // 所持品空き詰め - for (i = j = 0; i < MAX_INVENTORY; i++) + IOff0 j = IOff0::from(0); + for (IOff0 i : IOff0::iter()) { - if ((id = sd->status.inventory[i].nameid) == 0) + if (!(sd->status.inventory[i].nameid)) continue; - if (i > j) + if (i != j) { sd->status.inventory[j] = sd->status.inventory[i]; sd->inventory_data[j] = sd->inventory_data[i]; } - j++; + ++j; + } + for (IOff0 k = j; k != IOff0::from(MAX_INVENTORY); ++k) + { + sd->status.inventory[k] = Item{}; + sd->inventory_data[k] = nullptr; } - for (k = j; k < MAX_INVENTORY; ++k) - sd->status.inventory[k] = item{}; - for (k = j; k < MAX_INVENTORY; k++) - sd->inventory_data[k] = NULL; - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { - if (sd->status.inventory[i].nameid == 0) + if (!sd->status.inventory[i].nameid) continue; if (bool(sd->status.inventory[i].equip & ~pc_equippoint(sd, i))) { @@ -4670,7 +4672,7 @@ int pc_checkitem(dumb_ptr<map_session_data> sd) int pc_checkoverhp(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); if (sd->status.hp == sd->status.max_hp) return 1; @@ -4686,7 +4688,7 @@ int pc_checkoverhp(dumb_ptr<map_session_data> sd) int pc_checkoversp(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); if (sd->status.sp == sd->status.max_sp) return 1; @@ -4723,9 +4725,9 @@ void pc_calc_pvprank_sub(dumb_ptr<block_list> bl, dumb_ptr<map_session_data> sd2 */ int pc_calc_pvprank(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); map_local *m = sd->bl_m; - nullpo_ret(m); + nullpo_retz(m); if (!(m->flag.get(MapFlag::PVP))) return 0; @@ -4742,20 +4744,22 @@ int pc_calc_pvprank(dumb_ptr<map_session_data> sd) * PVP順位計算(timer) *------------------------------------------ */ -void pc_calc_pvprank_timer(TimerData *, tick_t, int id) +void pc_calc_pvprank_timer(TimerData *, tick_t, BlockId id) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; if (battle_config.pk_mode) // disable pvp ranking if pk_mode on [Valaris] return; sd = map_id2sd(id); - if (sd == NULL) + if (sd == nullptr) return; sd->pvp_timer.cancel(); if (pc_calc_pvprank(sd) > 0) + { sd->pvp_timer = Timer(gettick() + PVP_CALCRANK_INTERVAL, std::bind(pc_calc_pvprank_timer, ph::_1, ph::_2, id)); + } } /*========================================== @@ -4763,14 +4767,14 @@ void pc_calc_pvprank_timer(TimerData *, tick_t, int id) *------------------------------------------ */ static -int pc_ismarried(dumb_ptr<map_session_data> sd) +CharId pc_ismarried(dumb_ptr<map_session_data> sd) { - if (sd == NULL) - return -1; - if (sd->status.partner_id > 0) + if (sd == nullptr) + return CharId(); + if (sd->status.partner_id) return sd->status.partner_id; else - return 0; + return CharId(); } /*========================================== @@ -4779,8 +4783,8 @@ int pc_ismarried(dumb_ptr<map_session_data> sd) */ int pc_marriage(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> dstsd) { - if (sd == NULL || dstsd == NULL || sd->status.partner_id > 0 - || dstsd->status.partner_id > 0) + if (sd == nullptr || dstsd == nullptr || sd->status.partner_id + || dstsd->status.partner_id) return -1; sd->status.partner_id = dstsd->status_key.char_id; dstsd->status.partner_id = sd->status_key.char_id; @@ -4793,23 +4797,23 @@ int pc_marriage(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> dstsd) */ int pc_divorce(dumb_ptr<map_session_data> sd) { - dumb_ptr<map_session_data> p_sd = NULL; - if (sd == NULL || !pc_ismarried(sd)) + dumb_ptr<map_session_data> p_sd = nullptr; + if (sd == nullptr || !pc_ismarried(sd)) return -1; // If both are on map server we don't need to bother the char server if ((p_sd = - map_nick2sd(map_charid2nick(sd->status.partner_id))) != NULL) + map_nick2sd(map_charid2nick(sd->status.partner_id))) != nullptr) { if (p_sd->status.partner_id != sd->status_key.char_id || sd->status.partner_id != p_sd->status_key.char_id) { - PRINTF("pc_divorce: Illegal partner_id sd=%d p_sd=%d\n", + PRINTF("pc_divorce: Illegal partner_id sd=%d p_sd=%d\n"_fmt, sd->status.partner_id, p_sd->status.partner_id); return -1; } - p_sd->status.partner_id = 0; - sd->status.partner_id = 0; + p_sd->status.partner_id = CharId(); + sd->status.partner_id = CharId(); if (sd->npc_flags.divorce) { @@ -4829,17 +4833,17 @@ int pc_divorce(dumb_ptr<map_session_data> sd) */ dumb_ptr<map_session_data> pc_get_partner(dumb_ptr<map_session_data> sd) { - dumb_ptr<map_session_data> p_sd = NULL; - if (sd == NULL || !pc_ismarried(sd)) - return NULL; + dumb_ptr<map_session_data> p_sd = nullptr; + if (sd == nullptr || !pc_ismarried(sd)) + return nullptr; CharName nick = map_charid2nick(sd->status.partner_id); if (!nick.to__actual()) - return NULL; + return nullptr; - if ((p_sd = map_nick2sd(nick)) == NULL) - return NULL; + if ((p_sd = map_nick2sd(nick)) == nullptr) + return nullptr; return p_sd; } @@ -4890,7 +4894,7 @@ int pc_natural_heal_hp(dumb_ptr<map_session_data> sd) int bhp; int bonus; - nullpo_ret(sd); + nullpo_retz(sd); if (pc_checkoverhp(sd)) { @@ -4962,7 +4966,7 @@ int pc_natural_heal_sp(dumb_ptr<map_session_data> sd) int bsp; int bonus; - nullpo_ret(sd); + nullpo_retz(sd); if (pc_checkoversp(sd)) { @@ -5035,7 +5039,7 @@ int pc_quickregenerate_effect(struct quick_regeneration *quick_regen, if (!(quick_regen->tickdelay--)) { int bonus = - min(heal_speed * battle_config.itemheal_regeneration_factor, + std::min(heal_speed * battle_config.itemheal_regeneration_factor, quick_regen->amount); quick_regen->amount -= bonus; @@ -5171,21 +5175,20 @@ void pc_autosave(TimerData *, tick_t) interval_t interval = autosave_time / (clif_countusers() + 1); if (interval <= interval_t::zero()) - interval = std::chrono::milliseconds(1); + interval = 1_ms; Timer(gettick() + interval, pc_autosave ).detach(); } -int pc_read_gm_account(Session *s) +int pc_read_gm_account(Session *, const std::vector<Packet_Repeat<0x2b15>>& repeat) { gm_accountm.clear(); - // (RFIFOW(fd, 2) - 4) / 5 - for (int i = 4; i < RFIFOW(s, 2); i += 5) + for (const auto& i : repeat) { - int account_id = RFIFOL(s, i); - uint8_t level = RFIFOB(s, i + 4); + AccountId account_id = i.account_id; + GmLevel level = i.gm_level; gm_accountm[account_id] = level; } return gm_accountm.size(); @@ -5265,13 +5268,14 @@ int pc_logout(dumb_ptr<map_session_data> sd) // [fate] Player logs out // Removed because it's buggy, see above. if (sd->cast_tick > tick) { - if (pc_setglobalreg(sd, "MAGIC_CAST_TICK", sd->cast_tick - tick)) + if (pc_setglobalreg(sd, "MAGIC_CAST_TICK"_s, sd->cast_tick - tick)) sd->status.sp = 1; } else #endif - pc_setglobalreg(sd, stringish<VarName>("MAGIC_CAST_TICK"), 0); + pc_setglobalreg(sd, stringish<VarName>("MAGIC_CAST_TICK"_s), 0); - MAP_LOG_STATS(sd, "LOGOUT"); + MAP_LOG_STATS(sd, "LOGOUT"_fmt); return 0; } +} // namespace tmwa diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 35d9c70..3187cd9 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_PC_HPP -#define TMWA_MAP_PC_HPP +#pragma once // pc.hpp - Player state changes. // // Copyright © ????-2004 Athena Dev Teams @@ -21,15 +20,24 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "pc.t.hpp" +#include "pc.t.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "clif.t.hpp" -# include "map.hpp" +#include "../generic/dumb_ptr.hpp" +#include "../mmo/utils.hpp" + +#include "../proto2/fwd.hpp" + +#include "clif.t.hpp" +#include "map.hpp" + + +namespace tmwa +{ inline void pc_setsit(dumb_ptr<map_session_data> sd) { @@ -66,7 +74,7 @@ bool pc_is90overweight(dumb_ptr<map_session_data> sd) // should do something with the specified player. void pc_touch_all_relevant_npcs(dumb_ptr<map_session_data> sd); -uint8_t pc_isGM(dumb_ptr<map_session_data> sd); +GmLevel pc_isGM(dumb_ptr<map_session_data> sd); int pc_iskiller(dumb_ptr<map_session_data> src, dumb_ptr<map_session_data> target); // [MouseJstr] void pc_invisibility(dumb_ptr<map_session_data> sd, int enabled); // [Fate] @@ -74,14 +82,14 @@ int pc_counttargeted(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> src, ATK target_lv); int pc_setrestartvalue(dumb_ptr<map_session_data> sd, int type); void pc_makesavestatus(dumb_ptr<map_session_data>); -int pc_setnewpc(dumb_ptr<map_session_data>, int, int, int, tick_t, SEX); -int pc_authok(int, int, TimeT, short tmw_version, const CharKey *, const CharData *); -int pc_authfail(int accid); +int pc_setnewpc(dumb_ptr<map_session_data>, AccountId, CharId, int, uint32_t /*tick_t*/, SEX); +int pc_authok(AccountId, int, TimeT, short tmw_version, const CharKey *, const CharData *); +int pc_authfail(AccountId accid); -EPOS pc_equippoint(dumb_ptr<map_session_data> sd, int n); +EPOS pc_equippoint(dumb_ptr<map_session_data> sd, IOff0 n); int pc_checkskill(dumb_ptr<map_session_data> sd, SkillID skill_id); -int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos); +IOff0 pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos); int pc_walktoxy(dumb_ptr<map_session_data>, int, int); int pc_stop_walking(dumb_ptr<map_session_data>, int); @@ -90,20 +98,20 @@ int pc_setpos(dumb_ptr<map_session_data>, MapName, int, int, BeingRemoveWhy); void pc_setsavepoint(dumb_ptr<map_session_data>, MapName, int, int); int pc_randomwarp(dumb_ptr<map_session_data> sd, BeingRemoveWhy type); -ADDITEM pc_checkadditem(dumb_ptr<map_session_data>, int, int); +ADDITEM pc_checkadditem(dumb_ptr<map_session_data>, ItemNameId, int); int pc_inventoryblank(dumb_ptr<map_session_data>); -int pc_search_inventory(dumb_ptr<map_session_data> sd, int item_id); +IOff0 pc_search_inventory(dumb_ptr<map_session_data> sd, ItemNameId item_id); int pc_payzeny(dumb_ptr<map_session_data>, int); -PickupFail pc_additem(dumb_ptr<map_session_data>, struct item *, int); +PickupFail pc_additem(dumb_ptr<map_session_data>, Item *, int); int pc_getzeny(dumb_ptr<map_session_data>, int); -int pc_delitem(dumb_ptr<map_session_data>, int, int, int); +int pc_delitem(dumb_ptr<map_session_data>, IOff0, int, int); int pc_checkitem(dumb_ptr<map_session_data>); -int pc_count_all_items(dumb_ptr<map_session_data> player, int item_id); +int pc_count_all_items(dumb_ptr<map_session_data> player, ItemNameId item_id); int pc_remove_items(dumb_ptr<map_session_data> player, - int item_id, int count); + ItemNameId item_id, int count); int pc_takeitem(dumb_ptr<map_session_data>, dumb_ptr<flooritem_data>); -int pc_dropitem(dumb_ptr<map_session_data>, int, int); +int pc_dropitem(dumb_ptr<map_session_data>, IOff0, int); int pc_checkweighticon(dumb_ptr<map_session_data> sd); @@ -112,7 +120,7 @@ int pc_bonus(dumb_ptr<map_session_data>, SP, int); int pc_bonus2(dumb_ptr<map_session_data> sd, SP, int, int); int pc_skill(dumb_ptr<map_session_data>, SkillID, int, int); -int pc_attack(dumb_ptr<map_session_data>, int, int); +int pc_attack(dumb_ptr<map_session_data>, BlockId, int); int pc_stopattack(dumb_ptr<map_session_data>); int pc_gainexp_reason(dumb_ptr<map_session_data>, int, int, @@ -128,10 +136,10 @@ int pc_skillup(dumb_ptr<map_session_data>, SkillID); int pc_resetlvl(dumb_ptr<map_session_data>, int type); int pc_resetstate(dumb_ptr<map_session_data>); int pc_resetskill(dumb_ptr<map_session_data>); -int pc_equipitem(dumb_ptr<map_session_data>, int, EPOS); -int pc_unequipitem(dumb_ptr<map_session_data>, int, CalcStatus); -int pc_unequipinvyitem(dumb_ptr<map_session_data>, int, CalcStatus); -int pc_useitem(dumb_ptr<map_session_data>, int); +int pc_equipitem(dumb_ptr<map_session_data>, IOff0, EPOS); +int pc_unequipitem(dumb_ptr<map_session_data>, IOff0, CalcStatus); +int pc_unequipinvyitem(dumb_ptr<map_session_data>, IOff0, CalcStatus); +int pc_useitem(dumb_ptr<map_session_data>, IOff0); int pc_damage(dumb_ptr<block_list>, dumb_ptr<map_session_data>, int); int pc_heal(dumb_ptr<map_session_data>, int, int); @@ -158,17 +166,17 @@ int pc_addeventtimer(dumb_ptr<map_session_data> sd, interval_t tick, int pc_cleareventtimer(dumb_ptr<map_session_data> sd); int pc_calc_pvprank(dumb_ptr<map_session_data> sd); -void pc_calc_pvprank_timer(TimerData *, tick_t, int); +void pc_calc_pvprank_timer(TimerData *, tick_t, BlockId); int pc_marriage(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> dstsd); int pc_divorce(dumb_ptr<map_session_data> sd); dumb_ptr<map_session_data> pc_get_partner(dumb_ptr<map_session_data> sd); -void pc_set_gm_level(int account_id, uint8_t level); +void pc_set_gm_level(AccountId account_id, GmLevel level); void pc_setstand(dumb_ptr<map_session_data> sd); void pc_cleanup(dumb_ptr<map_session_data> sd); // [Fate] Clean up after a logged-out PC -int pc_read_gm_account(Session *); +int pc_read_gm_account(Session *, const std::vector<Packet_Repeat<0x2b15>>&); int pc_setinvincibletimer(dumb_ptr<map_session_data> sd, interval_t); int pc_delinvincibletimer(dumb_ptr<map_session_data> sd); int pc_logout(dumb_ptr<map_session_data> sd); // [fate] Player logs out @@ -176,5 +184,4 @@ int pc_logout(dumb_ptr<map_session_data> sd); // [fate] Player logs out void pc_show_motd(dumb_ptr<map_session_data> sd); void do_init_pc(void); - -#endif // TMWA_MAP_PC_HPP +} // namespace tmwa diff --git a/src/map/pc.t.hpp b/src/map/pc.t.hpp index 65e1046..427e8c3 100644 --- a/src/map/pc.t.hpp +++ b/src/map/pc.t.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_PC_T_HPP -#define TMWA_MAP_PC_T_HPP +#pragma once // pc.t.hpp - Player state changes. // // Copyright © ????-2004 Athena Dev Teams @@ -22,10 +21,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdint> +#include <cstdint> + +namespace tmwa +{ enum class PC_GAINEXP_REASON { KILLING = 0, @@ -50,18 +52,6 @@ enum class ADDITEM enum class CalcStatus { NOW, - LATER , -}; - -enum class PickupFail : uint8_t -{ - OKAY = 0, - BAD_ITEM = 1, - TOO_HEAVY = 2, - TOO_FAR = 3, - INV_FULL = 4, - STACK_FULL = 5, - DROP_STEAL = 6, + LATER, }; - -#endif // TMWA_MAP_PC_T_HPP +} // namespace tmwa diff --git a/src/map/script.cpp b/src/map/script.cpp index 93f9d31..0b2d05e 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -23,12 +23,11 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include <cassert> -#include <cctype> #include <cmath> #include <cstdlib> -#include <cstring> #include <ctime> +#include <algorithm> #include <set> #include "../compat/fun.hpp" @@ -38,6 +37,7 @@ #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" +#include "../strings/literal.hpp" #include "../generic/db.hpp" #include "../generic/intern-pool.hpp" @@ -46,13 +46,15 @@ #include "../io/cxxstdio.hpp" #include "../io/lock.hpp" #include "../io/read.hpp" +#include "../io/write.hpp" + +#include "../net/socket.hpp" +#include "../net/timer.hpp" -#include "../mmo/config_parse.hpp" #include "../mmo/core.hpp" #include "../mmo/extract.hpp" -#include "../mmo/socket.hpp" +#include "../mmo/human_time_diff.hpp" #include "../mmo/utils.hpp" -#include "../mmo/timer.hpp" #include "atcommand.hpp" #include "battle.hpp" @@ -60,7 +62,7 @@ #include "clif.hpp" #include "intif.hpp" #include "itemdb.hpp" -#include "magic.hpp" +#include "magic-interpreter-base.hpp" #include "map.hpp" #include "mob.hpp" #include "npc.hpp" @@ -71,6 +73,9 @@ #include "../poison.hpp" + +namespace tmwa +{ constexpr bool DEBUG_DISP = false; constexpr bool DEBUG_RUN = false; @@ -93,8 +98,8 @@ static Map<SIR, RString> mapregstr_db; static int mapreg_dirty = -1; -AString mapreg_txt = "save/mapreg.txt"; -constexpr std::chrono::milliseconds MAPREG_AUTOSAVE_INTERVAL = std::chrono::seconds(10); +AString mapreg_txt = "save/mapreg.txt"_s; +constexpr std::chrono::milliseconds MAPREG_AUTOSAVE_INTERVAL = 10_s; Map<ScriptLabel, int> scriptlabel_db; static @@ -102,19 +107,19 @@ std::set<ScriptLabel> probable_labels; UPMap<RString, const ScriptBuffer> userfunc_db; static -Array<ZString, 11> pos_str //= +Array<LString, 11> pos_str //= {{ - ZString("Head"), - ZString("Body"), - ZString("Left hand"), - ZString("Right hand"), - ZString("Robe"), - ZString("Shoes"), - ZString("Accessory 1"), - ZString("Accessory 2"), - ZString("Head 2"), - ZString("Head 3"), - ZString("Not Equipped"), + "Head"_s, + "Body"_s, + "Left hand"_s, + "Right hand"_s, + "Robe"_s, + "Shoes"_s, + "Accessory 1"_s, + "Accessory 2"_s, + "Head 2"_s, + "Head 3"_s, + "Not Equipped"_s, }}; static @@ -150,8 +155,9 @@ void mapreg_setregstr(SIR num, XString str); struct BuiltinFunction { void (*func)(ScriptState *); - ZString name; - ZString arg; + LString name; + LString arg; + char ret; }; // defined later extern BuiltinFunction builtin_functions[]; @@ -382,15 +388,15 @@ void disp_error_message(ZString mes, ZString::iterator pos_) ZString::iterator lineend = std::find(p, startptr.end(), '\n'); if (pos_ < lineend) { - PRINTF("\n%s\nline %d : ", mes, line); + PRINTF("\n%s\nline %d : "_fmt, mes, line); for (int i = 0; linestart + i != lineend; i++) { if (linestart + i != pos_) - PRINTF("%c", linestart[i]); + PRINTF("%c"_fmt, linestart[i]); else - PRINTF("\'%c\'", linestart[i]); + PRINTF("\'%c\'"_fmt, linestart[i]); } - PRINTF("\a\n"); + PRINTF("\a\n"_fmt); return; } p = lineend + 1; @@ -407,7 +413,7 @@ ZString::iterator ScriptBuffer::parse_simpleexpr(ZString::iterator p) if (*p == ';' || *p == ',') { - disp_error_message("unexpected expr end", p); + disp_error_message("unexpected expr end"_s, p); exit(1); } if (*p == '(') @@ -417,7 +423,7 @@ ZString::iterator ScriptBuffer::parse_simpleexpr(ZString::iterator p) p = skip_space(p); if ((*p++) != ')') { - disp_error_message("unmatch ')'", p); + disp_error_message("unmatch ')'"_s, p); exit(1); } } @@ -438,14 +444,14 @@ ZString::iterator ScriptBuffer::parse_simpleexpr(ZString::iterator p) p++; else if (*p == '\n') { - disp_error_message("unexpected newline @ string", p); + disp_error_message("unexpected newline @ string"_s, p); exit(1); } add_scriptb(*p++); } if (!*p) { - disp_error_message("unexpected eof @ string", p); + disp_error_message("unexpected eof @ string"_s, p); exit(1); } add_scriptb(0); @@ -457,35 +463,35 @@ ZString::iterator ScriptBuffer::parse_simpleexpr(ZString::iterator p) ZString::iterator p2 = skip_word(p); if (p2 == p) { - disp_error_message("unexpected character", p); + disp_error_message("unexpected character"_s, p); exit(1); } XString word(&*p, &*p2, nullptr); - if (word.startswith("On") || word.startswith("L_") || word.startswith("S_")) + if (word.startswith("On"_s) || word.startswith("L_"_s) || word.startswith("S_"_s)) probable_labels.insert(stringish<ScriptLabel>(word)); - if (parse_cmd_if && (word == "callsub" || word == "callfunc" || word == "return")) + if (parse_cmd_if && (word == "callsub"_s || word == "callfunc"_s || word == "return"_s)) { - disp_error_message("Sorry, callsub/callfunc/return have never worked properly in an if statement.", p); + disp_error_message("Sorry, callsub/callfunc/return have never worked properly in an if statement."_s, p); } str_data_t *ld = add_strp(word); parse_cmdp = ld; // warn_*_mismatch_paramnumのために必要 - // why not just check l->str == "if" or std::string(p, p2) == "if"? - if (ld == search_strp("if")) // warn_cmd_no_commaのために必要 + // why not just check l->str == "if"_s or std::string(p, p2) == "if"_s? + if (ld == search_strp("if"_s)) // warn_cmd_no_commaのために必要 parse_cmd_if++; p = p2; if (ld->type != ByteCode::FUNC_ && *p == '[') { // array(name[i] => getelementofarray(name,i) ) - add_scriptl(search_strp("getelementofarray")); + add_scriptl(search_strp("getelementofarray"_s)); add_scriptc(ByteCode::ARG); add_scriptl(ld); p = parse_subexpr(p + 1, -1); p = skip_space(p); if (*p != ']') { - disp_error_message("unmatch ']'", p); + disp_error_message("unmatch ']'"_s, p); exit(1); } p++; @@ -515,7 +521,7 @@ ZString::iterator ScriptBuffer::parse_subexpr(ZString::iterator p, int limit) ZString::iterator tmpp = skip_space(p + 1); if (*tmpp == ';' || *tmpp == ',') { - --script_errors; disp_error_message("deprecated: implicit 'next statement' label", p); + --script_errors; disp_error_message("deprecated: implicit 'next statement' label"_s, p); add_scriptl(&LABEL_NEXTLINE_); p++; return p; @@ -560,7 +566,7 @@ ZString::iterator ScriptBuffer::parse_subexpr(ZString::iterator p, int limit) if (funcp->type != ByteCode::FUNC_) { - disp_error_message("expect function", tmpp); + disp_error_message("expect function"_s, tmpp); exit(0); } @@ -574,7 +580,7 @@ ZString::iterator ScriptBuffer::parse_subexpr(ZString::iterator p, int limit) p++; else if (*p != ')' && script_config.warn_func_no_comma) { - disp_error_message("expect ',' or ')' at func params", + disp_error_message("expect ',' or ')' at func params"_s, p); } p = skip_space(p); @@ -583,7 +589,7 @@ ZString::iterator ScriptBuffer::parse_subexpr(ZString::iterator p, int limit) plist[i] = p; if (*p != ')') { - disp_error_message("func request '(' ')'", p); + disp_error_message("func request '(' ')'"_s, p); exit(1); } p++; @@ -593,14 +599,19 @@ ZString::iterator ScriptBuffer::parse_subexpr(ZString::iterator p, int limit) { ZString arg = builtin_functions[funcp->val].arg; int j = 0; + // TODO handle ? and multiple * correctly for (j = 0; arg[j]; j++) - if (arg[j] == '*') + if (arg[j] == '*' || arg[j] == '?') break; - if ((arg[j] == 0 && i != j) || (arg[j] == '*' && i < j)) + if ((arg[j] == 0 && i != j) || ((arg[j] == '*' || arg[j] == '?') && i < j)) { - disp_error_message("illegal number of parameters", + disp_error_message("illegal number of parameters"_s, plist[std::min(i, j)]); } + if (!builtin_functions[funcp->val].ret) + { + disp_error_message("statement in function context"_s, tmpp); + } } } else // not op == ByteCode::FUNC @@ -627,7 +638,7 @@ ZString::iterator ScriptBuffer::parse_expr(ZString::iterator p) case '[': case ']': case '}': - disp_error_message("unexpected char", p); + disp_error_message("unexpected char"_s, p); exit(1); } p = parse_subexpr(p, -1); @@ -657,21 +668,22 @@ ZString::iterator ScriptBuffer::parse_line(ZString::iterator p, bool *can_step) str_data_t *cmd = parse_cmdp; if (cmd->type != ByteCode::FUNC_) { - disp_error_message("expect command", p2); + disp_error_message("expect command"_s, p2); // exit(0); } { + // TODO should be LString, but no heterogenous lookup yet static std::set<ZString> terminators = { - "goto", - "return", - "close", - "menu", - "end", - "mapexit", - "shop", + "goto"_s, + "return"_s, + "close"_s, + "menu"_s, + "end"_s, + "mapexit"_s, + "shop"_s, }; *can_step = terminators.count(cmd->strs) == 0; } @@ -689,7 +701,7 @@ ZString::iterator ScriptBuffer::parse_line(ZString::iterator p, bool *can_step) else if (*p != ';' && script_config.warn_cmd_no_comma && parse_cmd_if * 2 <= i) { - disp_error_message("expect ',' or ';' at cmd params", p); + disp_error_message("expect ',' or ';' at cmd params"_s, p); } p = skip_space(p); i++; @@ -697,7 +709,7 @@ ZString::iterator ScriptBuffer::parse_line(ZString::iterator p, bool *can_step) plist[i] = p; if (*(p++) != ';') { - disp_error_message("need ';'", p); + disp_error_message("need ';'"_s, p); exit(1); } add_scriptc(ByteCode::FUNC_); @@ -707,14 +719,19 @@ ZString::iterator ScriptBuffer::parse_line(ZString::iterator p, bool *can_step) { ZString arg = builtin_functions[cmd->val].arg; int j = 0; + // TODO see above for (j = 0; arg[j]; j++) - if (arg[j] == '*') + if (arg[j] == '*' || arg[j] == '?') break; - if ((arg[j] == 0 && i != j) || (arg[j] == '*' && i < j)) + if ((arg[j] == 0 && i != j) || ((arg[j] == '*' || arg[j] == '?') && i < j)) { - disp_error_message("illegal number of parameters", + disp_error_message("illegal number of parameters"_s, plist[std::min(i, j)]); } + if (builtin_functions[cmd->val].ret) + { + disp_error_message("function in statement context"_s, p2); + } } return p; @@ -740,24 +757,50 @@ bool read_constdb(ZString filename) io::ReadFile in(filename); if (!in.is_open()) { - PRINTF("can't read %s\n", filename); + PRINTF("can't read %s\n"_fmt, filename); return false; } bool rv = true; - AString line; - while (in.getline(line)) - { - if (is_comment(line)) + AString line_; + while (in.getline(line_)) + { + // is_comment only works for whole-line comments + // that could change once the Z dependency is dropped ... + LString comment = "//"_s; + XString line = line_.xislice_h(std::search(line_.begin(), line_.end(), comment.begin(), comment.end())).rstrip(); + if (!line) continue; + // "%m[A-Za-z0-9_] %i %i" + + // TODO promote either qsplit() or asplit() + auto _it = std::find(line.begin(), line.end(), ' '); + auto name = line.xislice_h(_it); + auto _rest = line.xislice_t(_it); + while (_rest.startswith(' ')) + _rest = _rest.xslice_t(1); + auto _it2 = std::find(_rest.begin(), _rest.end(), ' '); + auto val_ = _rest.xislice_h(_it2); + auto type_ = _rest.xislice_t(_it2); + while (type_.startswith(' ')) + type_ = type_.xslice_t(1); + // yes, the above actually DTRT even for underlength input - AString name; int val; - int type = 0; // if not provided - // TODO get rid of SSCANF - this is the last serious use - if (SSCANF(line, "%m[A-Za-z0-9_] %i %i", &name, &val, &type) < 2) + int type = 0; + // Note for future archeaologists: this code is indented correctly + if (std::find_if_not(name.begin(), name.end(), + [](char c) + { + return ('0' <= c && c <= '9') + || ('A' <= c && c <= 'Z') + || ('a' <= c && c <= 'z') + || (c == '_'); + }) != name.end() + || !extract(val_, &val) + || (!extract(type_, &type) && type_)) { - PRINTF("Bad const line: %s\n", line); + PRINTF("Bad const line: %s\n"_fmt, line_); rv = false; continue; } @@ -815,7 +858,7 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end) p = skip_space(p); if (*p != '{') { - disp_error_message("not found '{'", p); + disp_error_message("not found '{'"_s, p); abort(); } for (p++; *p && *p != '}';) @@ -825,7 +868,7 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end) { if (can_step) { - --script_errors; disp_error_message("deprecated: implicit fallthrough", p); + --script_errors; disp_error_message("deprecated: implicit fallthrough"_s, p); } can_step = true; @@ -838,7 +881,7 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end) assert (e1 == e2 && e2 == e3); if (e3) { - disp_error_message("dup label ", p); + disp_error_message("dup label "_s, p); exit(1); } set_label(ld, script_buf.size()); @@ -849,7 +892,7 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end) if (!can_step) { - --script_errors; disp_error_message("deprecated: unreachable statement", p); + --script_errors; disp_error_message("deprecated: unreachable statement"_s, p); } // 他は全部一緒くた p = parse_line(p, &can_step); @@ -864,7 +907,7 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end) if (can_step && !implicit_end) { - --script_errors; disp_error_message("deprecated: implicit end", p); + --script_errors; disp_error_message("deprecated: implicit end"_s, p); } add_scriptc(ByteCode::NOP); @@ -893,17 +936,17 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end) for (const auto& pair : scriptlabel_db) { ScriptLabel key = pair.first; - if (key.startswith("On")) + if (key.startswith("On"_s)) continue; - if (!(key.startswith("L_") || key.startswith("S_"))) - PRINTF("Warning: ugly label: %s\n", key); + if (!(key.startswith("L_"_s) || key.startswith("S_"_s))) + PRINTF("Warning: ugly label: %s\n"_fmt, key); else if (!probable_labels.count(key)) - PRINTF("Warning: unused label: %s\n", key); + PRINTF("Warning: unused label: %s\n"_fmt, key); } for (ScriptLabel used : probable_labels) { if (!scriptlabel_db.search(used)) - PRINTF("Warning: no such label: %s\n", used); + PRINTF("Warning: no such label: %s\n"_fmt, used); } probable_labels.clear(); @@ -912,12 +955,12 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end) for (size_t i = 0; i < script_buf.size(); i++) { if ((i & 15) == 0) - PRINTF("%04zx : ", i); - PRINTF("%02x ", script_buf[i]); + PRINTF("%04zx : "_fmt, i); + PRINTF("%02x "_fmt, script_buf[i]); if ((i & 15) == 15) - PRINTF("\n"); + PRINTF("\n"_fmt); } - PRINTF("\n"); + PRINTF("\n"_fmt); } // @@ -943,7 +986,7 @@ dumb_ptr<map_session_data> script_rid2sd(ScriptState *st) dumb_ptr<map_session_data> sd = map_id2sd(st->rid); if (!sd) { - PRINTF("script_rid2sd: fatal error ! player not attached!\n"); + PRINTF("script_rid2sd: fatal error ! player not attached!\n"_fmt); } return sd; } @@ -957,8 +1000,8 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data) { if (data->type == ByteCode::PARAM_) { - if (sd == NULL) - PRINTF("get_val error param SP::%d\n", data->u.reg.sp()); + if (sd == nullptr) + PRINTF("get_val error param SP::%d\n"_fmt, data->u.reg.sp()); data->type = ByteCode::INT; if (sd) data->u.numi = pc_readparam(sd, data->u.reg.sp()); @@ -972,8 +1015,8 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data) if (prefix != '$') { - if (sd == NULL) - PRINTF("get_val error name?:%s\n", name); + if (sd == nullptr) + PRINTF("get_val error name?:%s\n"_fmt, name); } if (postfix == '$') { @@ -990,11 +1033,11 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data) } else { - PRINTF("script: get_val: illegal scope string variable.\n"); - data->u.str = dumb_string::fake("!!ERROR!!"); + PRINTF("script: get_val: illegal scope string variable.\n"_fmt); + data->u.str = dumb_string::fake("!!ERROR!!"_s); } if (!data->u.str) - data->u.str = dumb_string::fake(""); + data->u.str = dumb_string::fake(""_s); } else { @@ -1085,7 +1128,7 @@ void set_reg(dumb_ptr<map_session_data> sd, ByteCode type, SIR reg, struct scrip } else { - PRINTF("script: set_reg: illegal scope string variable !"); + PRINTF("script: set_reg: illegal scope string variable !"_fmt); } } else @@ -1143,7 +1186,7 @@ dumb_string conv_str(ScriptState *st, struct script_data *data) assert (data->type != ByteCode::RETINFO); if (data->type == ByteCode::INT) { - AString buf = STRPRINTF("%d", data->u.numi); + AString buf = STRPRINTF("%d"_fmt, data->u.numi); data->type = ByteCode::STR; data->u.str = dumb_string::copys(buf); } @@ -1285,7 +1328,7 @@ void builtin_goto(ScriptState *st) { if (AARGO2(2).type != ByteCode::POS) { - PRINTF("script: goto: not label !\n"); + PRINTF("script: goto: not label !\n"_fmt); st->state = ScriptEndState::END; return; } @@ -1324,7 +1367,7 @@ void builtin_callfunc(ScriptState *st) } else { - PRINTF("script:callfunc: function not found! [%s]\n", str); + PRINTF("script:callfunc: function not found! [%s]\n"_fmt, str); st->state = ScriptEndState::END; } } @@ -1442,7 +1485,7 @@ void builtin_menu(ScriptState *st) // not just the displayed number that ends with the "". // (Would it be better to pop the stack before rerunning?) int menu_choices = (st->end - (st->start + 2)) / 2; - pc_setreg(sd, SIR::from(variable_names.intern("@menu")), sd->npc_menu); + pc_setreg(sd, SIR::from(variable_names.intern("@menu"_s)), sd->npc_menu); sd->state.menu_or_input = 0; if (sd->npc_menu > 0 && sd->npc_menu <= menu_choices) { @@ -1481,23 +1524,6 @@ void builtin_rand(ScriptState *st) } /*========================================== - * - *------------------------------------------ - */ -static -void builtin_pow(ScriptState *st) -{ - int a, b; - - a = conv_num(st, &AARGO2(2)); - b = conv_num(st, &AARGO2(3)); - -#warning "This is silly" - push_int(st->stack, ByteCode::INT, static_cast<int>(pow(a * 0.001, b))); - -} - -/*========================================== * Check whether the PC is at the specified location *------------------------------------------ */ @@ -1532,9 +1558,9 @@ void builtin_warp(ScriptState *st) MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x = conv_num(st, &AARGO2(3)); y = conv_num(st, &AARGO2(4)); - if (str == "Random") + if (str == "Random"_s) pc_randomwarp(sd, BeingRemoveWhy::WARPED); - else if (str == "SavePoint" or str == "Save") + else if (str == "SavePoint"_s or str == "Save"_s) { if (sd->bl_m->flag.get(MapFlag::NORETURN)) return; @@ -1554,7 +1580,7 @@ static void builtin_areawarp_sub(dumb_ptr<block_list> bl, MapName mapname, int x, int y) { dumb_ptr<map_session_data> sd = bl->is_player(); - if (mapname == "Random") + if (mapname == "Random"_s) pc_randomwarp(sd, BeingRemoveWhy::WARPED); else pc_setpos(sd, mapname, x, y, BeingRemoveWhy::GONE); @@ -1635,7 +1661,7 @@ void builtin_percentheal(ScriptState *st) static void builtin_input(ScriptState *st) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; script_data& scrd = AARGO2(2); ByteCode type = scrd.type; assert (type == ByteCode::VARIABLE); @@ -1712,7 +1738,7 @@ void builtin_if (ScriptState *st) static void builtin_set(ScriptState *st) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; SIR reg = AARGO2(2).u.reg; if (AARGO2(2).type == ByteCode::PARAM_) { @@ -1753,7 +1779,7 @@ void builtin_set(ScriptState *st) static void builtin_setarray(ScriptState *st) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; assert (AARGO2(2).type == ByteCode::VARIABLE); SIR reg = AARGO2(2).u.reg; ZString name = variable_names.outtern(reg.base()); @@ -1762,7 +1788,7 @@ void builtin_setarray(ScriptState *st) if (prefix != '$' && prefix != '@') { - PRINTF("builtin_setarray: illegal scope !\n"); + PRINTF("builtin_setarray: illegal scope !\n"_fmt); return; } if (prefix != '$') @@ -1784,7 +1810,7 @@ void builtin_setarray(ScriptState *st) static void builtin_cleararray(ScriptState *st) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; assert (AARGO2(2).type == ByteCode::VARIABLE); SIR reg = AARGO2(2).u.reg; ZString name = variable_names.outtern(reg.base()); @@ -1794,7 +1820,7 @@ void builtin_cleararray(ScriptState *st) if (prefix != '$' && prefix != '@') { - PRINTF("builtin_cleararray: illegal scope !\n"); + PRINTF("builtin_cleararray: illegal scope !\n"_fmt); return; } if (prefix != '$') @@ -1839,7 +1865,7 @@ void builtin_getarraysize(ScriptState *st) if (prefix != '$' && prefix != '@') { - PRINTF("builtin_copyarray: illegal scope !\n"); + PRINTF("builtin_copyarray: illegal scope !\n"_fmt); return; } @@ -1858,8 +1884,8 @@ void builtin_getelementofarray(ScriptState *st) int i = conv_num(st, &AARGO2(3)); if (i > 255 || i < 0) { - PRINTF("script: getelementofarray (operator[]): param2 illegal number %d\n", - i); + PRINTF("script: getelementofarray (operator[]): param2 illegal number %d\n"_fmt, + i); push_int(st->stack, ByteCode::INT, 0); } else @@ -1870,7 +1896,7 @@ void builtin_getelementofarray(ScriptState *st) } else { - PRINTF("script: getelementofarray (operator[]): param1 not name !\n"); + PRINTF("script: getelementofarray (operator[]): param1 not name !\n"_fmt); push_int(st->stack, ByteCode::INT, 0); } } @@ -1896,7 +1922,8 @@ void builtin_setlook(ScriptState *st) static void builtin_countitem(ScriptState *st) { - int nameid = 0, count = 0, i; + ItemNameId nameid; + int count = 0; dumb_ptr<map_session_data> sd; struct script_data *data; @@ -1909,22 +1936,24 @@ void builtin_countitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); struct item_data *item_data = itemdb_searchname(name); - if (item_data != NULL) + if (item_data != nullptr) nameid = item_data->nameid; } else - nameid = conv_num(st, data); + nameid = wrap<ItemNameId>(conv_num(st, data)); - if (nameid >= 500) //if no such ID then skip this iteration - for (i = 0; i < MAX_INVENTORY; i++) + if (nameid) + { + for (IOff0 i : IOff0::iter()) { if (sd->status.inventory[i].nameid == nameid) count += sd->status.inventory[i].amount; } + } else { if (battle_config.error_log) - PRINTF("wrong item ID : countitem (%i)\n", nameid); + PRINTF("wrong item ID : countitem (%i)\n"_fmt, nameid); } push_int(st->stack, ByteCode::INT, count); @@ -1937,7 +1966,8 @@ void builtin_countitem(ScriptState *st) static void builtin_checkweight(ScriptState *st) { - int nameid = 0, amount; + ItemNameId nameid; + int amount; dumb_ptr<map_session_data> sd; struct script_data *data; @@ -1953,10 +1983,10 @@ void builtin_checkweight(ScriptState *st) nameid = item_data->nameid; } else - nameid = conv_num(st, data); + nameid = wrap<ItemNameId>(conv_num(st, data)); amount = conv_num(st, &AARGO2(3)); - if (amount <= 0 || nameid < 500) + if (amount <= 0 || !nameid) { //if get wrong item ID or amount<=0, don't count weight of non existing items push_int(st->stack, ByteCode::INT, 0); @@ -1981,7 +2011,8 @@ void builtin_checkweight(ScriptState *st) static void builtin_getitem(ScriptState *st) { - int nameid, amount; + ItemNameId nameid; + int amount; dumb_ptr<map_session_data> sd; struct script_data *data; @@ -1993,12 +2024,11 @@ void builtin_getitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); struct item_data *item_data = itemdb_searchname(name); - nameid = 727; //Default to iten - if (item_data != NULL) + if (item_data != nullptr) nameid = item_data->nameid; } else - nameid = conv_num(st, data); + nameid = wrap<ItemNameId>(conv_num(st, data)); if ((amount = conv_num(st, &AARGO2(3))) <= 0) @@ -2006,21 +2036,21 @@ void builtin_getitem(ScriptState *st) return; //return if amount <=0, skip the useles iteration } - if (nameid > 0) + if (nameid) { - struct item item_tmp {}; + Item item_tmp {}; item_tmp.nameid = nameid; if (HARGO2(5)) //アイテムを指定したIDに渡す - sd = map_id2sd(conv_num(st, &AARGO2(5))); - if (sd == NULL) //アイテムを渡す相手がいなかったらお帰り + sd = map_id2sd(wrap<BlockId>(conv_num(st, &AARGO2(5)))); + if (sd == nullptr) //アイテムを渡す相手がいなかったらお帰り return; PickupFail flag; if ((flag = pc_additem(sd, &item_tmp, amount)) != PickupFail::OKAY) { - clif_additem(sd, 0, 0, flag); + clif_additem(sd, IOff0::from(0), 0, flag); map_addflooritem(&item_tmp, amount, sd->bl_m, sd->bl_x, sd->bl_y, - NULL, NULL, NULL); + nullptr, nullptr, nullptr); } } @@ -2033,7 +2063,8 @@ void builtin_getitem(ScriptState *st) static void builtin_makeitem(ScriptState *st) { - int nameid, amount; + ItemNameId nameid; + int amount; int x, y; dumb_ptr<map_session_data> sd; struct script_data *data; @@ -2046,12 +2077,11 @@ void builtin_makeitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); struct item_data *item_data = itemdb_searchname(name); - nameid = 512; //Apple Item ID if (item_data) nameid = item_data->nameid; } else - nameid = conv_num(st, data); + nameid = wrap<ItemNameId>(conv_num(st, data)); amount = conv_num(st, &AARGO2(3)); MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(4)))); @@ -2064,12 +2094,12 @@ void builtin_makeitem(ScriptState *st) else m = map_mapname2mapid(mapname); - if (nameid > 0) + if (nameid) { - struct item item_tmp {}; + Item item_tmp {}; item_tmp.nameid = nameid; - map_addflooritem(&item_tmp, amount, m, x, y, NULL, NULL, NULL); + map_addflooritem(&item_tmp, amount, m, x, y, nullptr, nullptr, nullptr); } } @@ -2080,7 +2110,8 @@ void builtin_makeitem(ScriptState *st) static void builtin_delitem(ScriptState *st) { - int nameid = 0, amount, i; + ItemNameId nameid; + int amount; dumb_ptr<map_session_data> sd; struct script_data *data; @@ -2092,31 +2123,21 @@ void builtin_delitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); struct item_data *item_data = itemdb_searchname(name); - //nameid=512; if (item_data) nameid = item_data->nameid; } else - nameid = conv_num(st, data); + nameid = wrap<ItemNameId>(conv_num(st, data)); amount = conv_num(st, &AARGO2(3)); - if (nameid < 500 || amount <= 0) + if (!nameid || amount <= 0) { //by Lupus. Don't run FOR if u got wrong item ID or amount<=0 - //PRINTF("wrong item ID or amount<=0 : delitem %i,\n",nameid,amount); return; } - for (i = 0; i < MAX_INVENTORY; i++) - { - if (sd->status.inventory[i].nameid <= 0 - || sd->inventory_data[i] == NULL - || sd->inventory_data[i]->type != ItemType::_7 - || sd->status.inventory[i].amount <= 0) - continue; - } - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (sd->status.inventory[i].nameid == nameid) { @@ -2153,7 +2174,7 @@ void builtin_readparam(ScriptState *st) else sd = script_rid2sd(st); - if (sd == NULL) + if (sd == nullptr) { push_int(st->stack, ByteCode::INT, -1); return; @@ -2178,19 +2199,19 @@ void builtin_getcharid(ScriptState *st) sd = map_nick2sd(stringish<CharName>(ZString(conv_str(st, &AARGO2(3))))); else sd = script_rid2sd(st); - if (sd == NULL) + if (sd == nullptr) { push_int(st->stack, ByteCode::INT, -1); return; } if (num == 0) - push_int(st->stack, ByteCode::INT, sd->status_key.char_id); + push_int(st->stack, ByteCode::INT, unwrap<CharId>(sd->status_key.char_id)); if (num == 1) - push_int(st->stack, ByteCode::INT, sd->status.party_id); + push_int(st->stack, ByteCode::INT, unwrap<PartyId>(sd->status.party_id)); if (num == 2) push_int(st->stack, ByteCode::INT, 0/*guild_id*/); if (num == 3) - push_int(st->stack, ByteCode::INT, sd->status_key.account_id); + push_int(st->stack, ByteCode::INT, unwrap<AccountId>(sd->status_key.account_id)); } /*========================================== @@ -2198,9 +2219,9 @@ void builtin_getcharid(ScriptState *st) *------------------------------------------ */ static -dumb_string builtin_getpartyname_sub(int party_id) +dumb_string builtin_getpartyname_sub(PartyId party_id) { - struct party *p = party_search(party_id); + PartyPair p = party_search(party_id); if (p) return dumb_string::copys(p->name); @@ -2231,12 +2252,12 @@ void builtin_strcharinfo(ScriptState *st) if (buf) push_str(st->stack, ByteCode::STR, buf); else - push_str(st->stack, ByteCode::CONSTSTR, dumb_string::fake("")); + push_str(st->stack, ByteCode::CONSTSTR, dumb_string::fake(""_s)); } if (num == 2) { // was: guild name - push_str(st->stack, ByteCode::CONSTSTR, dumb_string::fake("")); + push_str(st->stack, ByteCode::CONSTSTR, dumb_string::fake(""_s)); } } @@ -2266,23 +2287,23 @@ Array<EPOS, 11> equip //= static void builtin_getequipid(ScriptState *st) { - int i, num; + int num; dumb_ptr<map_session_data> sd; struct item_data *item; sd = script_rid2sd(st); - if (sd == NULL) + if (sd == nullptr) { - PRINTF("getequipid: sd == NULL\n"); + PRINTF("getequipid: sd == nullptr\n"_fmt); return; } num = conv_num(st, &AARGO2(2)); - i = pc_checkequip(sd, equip[num - 1]); - if (i >= 0) + IOff0 i = pc_checkequip(sd, equip[num - 1]); + if (i.ok()) { item = sd->inventory_data[i]; if (item) - push_int(st->stack, ByteCode::INT, item->nameid); + push_int(st->stack, ByteCode::INT, unwrap<ItemNameId>(item->nameid)); else push_int(st->stack, ByteCode::INT, 0); } @@ -2299,7 +2320,7 @@ void builtin_getequipid(ScriptState *st) static void builtin_getequipname(ScriptState *st) { - int i, num; + int num; dumb_ptr<map_session_data> sd; struct item_data *item; @@ -2307,18 +2328,18 @@ void builtin_getequipname(ScriptState *st) sd = script_rid2sd(st); num = conv_num(st, &AARGO2(2)); - i = pc_checkequip(sd, equip[num - 1]); - if (i >= 0) + IOff0 i = pc_checkequip(sd, equip[num - 1]); + if (i.ok()) { item = sd->inventory_data[i]; if (item) - buf = STRPRINTF("%s-[%s]", pos_str[num - 1], item->jname); + buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], item->jname); else - buf = STRPRINTF("%s-[%s]", pos_str[num - 1], pos_str[10]); + buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], pos_str[10]); } else { - buf = STRPRINTF("%s-[%s]", pos_str[num - 1], pos_str[10]); + buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], pos_str[10]); } push_str(st->stack, ByteCode::STR, dumb_string::copys(buf)); @@ -2423,7 +2444,7 @@ void builtin_getskilllv(ScriptState *st) static void builtin_getgmlevel(ScriptState *st) { - push_int(st->stack, ByteCode::INT, pc_isGM(script_rid2sd(st))); + push_int(st->stack, ByteCode::INT, pc_isGM(script_rid2sd(st)).get_all_bits()); } /*========================================== @@ -2448,7 +2469,7 @@ void builtin_getopt2(ScriptState *st) sd = script_rid2sd(st); - push_int(st->stack, ByteCode::INT, uint16_t(sd->opt2)); + push_int(st->stack, ByteCode::INT, static_cast<uint16_t>(sd->opt2)); } @@ -2613,14 +2634,15 @@ void builtin_getexp(ScriptState *st) static void builtin_monster(ScriptState *st) { - int mob_class, amount, x, y; + Species mob_class; + int amount, x, y; NpcEvent event; MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); x = conv_num(st, &AARGO2(3)); y = conv_num(st, &AARGO2(4)); MobName str = stringish<MobName>(ZString(conv_str(st, &AARGO2(5)))); - mob_class = conv_num(st, &AARGO2(6)); + mob_class = wrap<Species>(conv_num(st, &AARGO2(6))); amount = conv_num(st, &AARGO2(7)); if (HARGO2(8)) extract(ZString(conv_str(st, &AARGO2(8))), &event); @@ -2636,7 +2658,8 @@ void builtin_monster(ScriptState *st) static void builtin_areamonster(ScriptState *st) { - int mob_class, amount, x0, y0, x1, y1; + Species mob_class; + int amount, x0, y0, x1, y1; NpcEvent event; MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); @@ -2645,7 +2668,7 @@ void builtin_areamonster(ScriptState *st) x1 = conv_num(st, &AARGO2(5)); y1 = conv_num(st, &AARGO2(6)); MobName str = stringish<MobName>(ZString(conv_str(st, &AARGO2(7)))); - mob_class = conv_num(st, &AARGO2(8)); + mob_class = wrap<Species>(conv_num(st, &AARGO2(8))); amount = conv_num(st, &AARGO2(9)); if (HARGO2(10)) extract(ZString(conv_str(st, &AARGO2(10))), &event); @@ -2683,7 +2706,7 @@ void builtin_killmonster(ScriptState *st) MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); ZString event_ = ZString(conv_str(st, &AARGO2(3))); NpcEvent event; - if (event_ != "All") + if (event_ != "All"_s) extract(event_, &event); map_local *m = map_mapname2mapid(mapname); @@ -2997,7 +3020,7 @@ void builtin_getareausers(ScriptState *st) *------------------------------------------ */ static -void builtin_getareadropitem_sub(dumb_ptr<block_list> bl, int item, int *amount) +void builtin_getareadropitem_sub(dumb_ptr<block_list> bl, ItemNameId item, int *amount) { dumb_ptr<flooritem_data> drop = bl->is_item(); @@ -3007,14 +3030,14 @@ void builtin_getareadropitem_sub(dumb_ptr<block_list> bl, int item, int *amount) } static -void builtin_getareadropitem_sub_anddelete(dumb_ptr<block_list> bl, int item, int *amount) +void builtin_getareadropitem_sub_anddelete(dumb_ptr<block_list> bl, ItemNameId item, int *amount) { dumb_ptr<flooritem_data> drop = bl->is_item(); if (drop->item_data.nameid == item) { (*amount) += drop->item_data.amount; - clif_clearflooritem(drop, 0); + clif_clearflooritem(drop, nullptr); map_delobject(drop->bl_id, drop->bl_type); } } @@ -3022,7 +3045,8 @@ void builtin_getareadropitem_sub_anddelete(dumb_ptr<block_list> bl, int item, in static void builtin_getareadropitem(ScriptState *st) { - int x0, y0, x1, y1, item, amount = 0, delitems = 0; + ItemNameId item; + int x0, y0, x1, y1, amount = 0, delitems = 0; struct script_data *data; MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2)))); @@ -3037,12 +3061,11 @@ void builtin_getareadropitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); struct item_data *item_data = itemdb_searchname(name); - item = 512; if (item_data) item = item_data->nameid; } else - item = conv_num(st, data); + item = wrap<ItemNameId>(conv_num(st, data)); if (HARGO2(8)) delitems = conv_num(st, &AARGO2(8)); @@ -3102,7 +3125,7 @@ void builtin_sc_start(ScriptState *st) int val1; StatusChange type = static_cast<StatusChange>(conv_num(st, &AARGO2(2))); interval_t tick = static_cast<interval_t>(conv_num(st, &AARGO2(3))); - if (tick < std::chrono::seconds(1)) + if (tick < 1_s) // work around old behaviour of: // speed potion // atk potion @@ -3113,7 +3136,7 @@ void builtin_sc_start(ScriptState *st) tick *= 1000; val1 = conv_num(st, &AARGO2(4)); if (HARGO2(5)) //指定したキャラを状態異常にする - bl = map_id2bl(conv_num(st, &AARGO2(5))); + bl = map_id2bl(wrap<BlockId>(conv_num(st, &AARGO2(5)))); else bl = map_id2bl(st->rid); skill_status_change_start(bl, type, val1, tick); @@ -3151,7 +3174,7 @@ static void builtin_debugmes(ScriptState *st) { dumb_string mes = conv_str(st, &AARGO2(2)); - PRINTF("script debug : %d %d : %s\n", + PRINTF("script debug : %d %d : %s\n"_fmt, st->rid, st->oid, mes); } @@ -3174,10 +3197,10 @@ void builtin_resetstatus(ScriptState *st) static void builtin_changesex(ScriptState *st) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; sd = script_rid2sd(st); - chrif_char_ask_name(-1, sd->status_key.name, 5, HumanTimeDiff()); // type: 5 - changesex + chrif_char_ask_name(AccountId(), sd->status_key.name, 5, HumanTimeDiff()); // type: 5 - changesex chrif_save(sd); } @@ -3188,8 +3211,8 @@ void builtin_changesex(ScriptState *st) static void builtin_attachrid(ScriptState *st) { - st->rid = conv_num(st, &AARGO2(2)); - push_int(st->stack, ByteCode::INT, (map_id2sd(st->rid) != NULL)); + st->rid = wrap<BlockId>(conv_num(st, &AARGO2(2))); + push_int(st->stack, ByteCode::INT, (map_id2sd(st->rid) != nullptr)); } /*========================================== @@ -3199,7 +3222,7 @@ void builtin_attachrid(ScriptState *st) static void builtin_detachrid(ScriptState *st) { - st->rid = 0; + st->rid = BlockId(); } /*========================================== @@ -3210,8 +3233,7 @@ static void builtin_isloggedin(ScriptState *st) { push_int(st->stack, ByteCode::INT, - map_id2sd(conv_num(st, - &AARGO2(2))) != NULL); + map_id2sd(wrap<BlockId>(conv_num(st, &AARGO2(2)))) != nullptr); } static @@ -3279,7 +3301,7 @@ void builtin_pvpon(ScriptState *st) { if (m == pl_sd->bl_m && !pl_sd->pvp_timer) { - pl_sd->pvp_timer = Timer(gettick() + std::chrono::milliseconds(200), + pl_sd->pvp_timer = Timer(gettick() + 200_ms, std::bind(pc_calc_pvprank_timer, ph::_1, ph::_2, pl_sd->bl_id)); pl_sd->pvp_rank = 0; @@ -3411,7 +3433,7 @@ void builtin_marriage(ScriptState *st) dumb_ptr<map_session_data> sd = script_rid2sd(st); dumb_ptr<map_session_data> p_sd = map_nick2sd(partner); - if (sd == NULL || p_sd == NULL || pc_marriage(sd, p_sd) < 0) + if (sd == nullptr || p_sd == nullptr || pc_marriage(sd, p_sd) < 0) { push_int(st->stack, ByteCode::INT, 0); return; @@ -3428,7 +3450,7 @@ void builtin_divorce(ScriptState *st) sd->npc_flags.divorce = 1; - if (sd == NULL || pc_divorce(sd) < 0) + if (sd == nullptr || pc_divorce(sd) < 0) { push_int(st->stack, ByteCode::INT, 0); return; @@ -3456,7 +3478,7 @@ void builtin_getitemname(ScriptState *st) } else { - int item_id = conv_num(st, data); + ItemNameId item_id = wrap<ItemNameId>(conv_num(st, data)); i_data = itemdb_search(item_id); } @@ -3464,7 +3486,7 @@ void builtin_getitemname(ScriptState *st) if (i_data) item_name = dumb_string::copys(i_data->jname); else - item_name = dumb_string::copys("Unknown Item"); + item_name = dumb_string::copys("Unknown Item"_s); push_str(st->stack, ByteCode::STR, item_name); } @@ -3476,7 +3498,7 @@ void builtin_getspellinvocation(ScriptState *st) AString invocation = magic_find_invocation(name.str()); if (!invocation) - invocation = "..."; + invocation = "..."_s; push_str(st->stack, ByteCode::STR, dumb_string::copys(invocation)); } @@ -3486,7 +3508,7 @@ void builtin_getpartnerid2(ScriptState *st) { dumb_ptr<map_session_data> sd = script_rid2sd(st); - push_int(st->stack, ByteCode::INT, sd->status.partner_id); + push_int(st->stack, ByteCode::INT, unwrap<CharId>(sd->status.partner_id)); } /*========================================== @@ -3497,24 +3519,24 @@ static void builtin_getinventorylist(ScriptState *st) { dumb_ptr<map_session_data> sd = script_rid2sd(st); - int i, j = 0; + int j = 0; if (!sd) return; - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { - if (sd->status.inventory[i].nameid > 0 + if (sd->status.inventory[i].nameid && sd->status.inventory[i].amount > 0) { - pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_id"), j), - sd->status.inventory[i].nameid); - pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_amount"), j), + pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_id"_s), j), + unwrap<ItemNameId>(sd->status.inventory[i].nameid)); + pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_amount"_s), j), sd->status.inventory[i].amount); - pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_equip"), j), + pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_equip"_s), j), static_cast<uint16_t>(sd->status.inventory[i].equip)); j++; } } - pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_count")), j); + pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_count"_s)), j); } static @@ -3534,18 +3556,18 @@ void builtin_getactivatedpoolskilllist(ScriptState *st) if (sd->status.skill[skill_id].lv) { - pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_id"), count), + pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_id"_s), count), static_cast<uint16_t>(skill_id)); - pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_lv"), count), + pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_lv"_s), count), sd->status.skill[skill_id].lv); - pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_flag"), count), + pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_flag"_s), count), static_cast<uint16_t>(sd->status.skill[skill_id].flags)); - pc_setregstr(sd, SIR::from(variable_names.intern("@skilllist_name$"), count), + pc_setregstr(sd, SIR::from(variable_names.intern("@skilllist_name$"_s), count), skill_name(skill_id)); ++count; } } - pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_count")), count); + pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_count"_s)), count); } @@ -3565,18 +3587,18 @@ void builtin_getunactivatedpoolskilllist(ScriptState *st) if (sd->status.skill[skill_id].lv && !bool(sd->status.skill[skill_id].flags & SkillFlags::POOL_ACTIVATED)) { - pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_id"), count), + pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_id"_s), count), static_cast<uint16_t>(skill_id)); - pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_lv"), count), + pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_lv"_s), count), sd->status.skill[skill_id].lv); - pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_flag"), count), + pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_flag"_s), count), static_cast<uint16_t>(sd->status.skill[skill_id].flags)); - pc_setregstr(sd, SIR::from(variable_names.intern("@skilllist_name$"), count), + pc_setregstr(sd, SIR::from(variable_names.intern("@skilllist_name$"_s), count), skill_name(skill_id)); ++count; } } - pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_count")), count); + pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_count"_s)), count); } static @@ -3616,9 +3638,9 @@ static void builtin_misceffect(ScriptState *st) { int type; - int id = 0; + BlockId id; CharName name; - dumb_ptr<block_list> bl = NULL; + dumb_ptr<block_list> bl = nullptr; type = conv_num(st, &AARGO2(2)); @@ -3631,7 +3653,7 @@ void builtin_misceffect(ScriptState *st) if (sdata->type == ByteCode::STR || sdata->type == ByteCode::CONSTSTR) name = stringish<CharName>(ZString(conv_str(st, sdata))); else - id = conv_num(st, sdata); + id = wrap<BlockId>(conv_num(st, sdata)); } if (name.to__actual()) @@ -3665,7 +3687,7 @@ void builtin_specialeffect(ScriptState *st) { dumb_ptr<block_list> bl = map_id2bl(st->oid); - if (bl == NULL) + if (bl == nullptr) return; clif_specialeffect(bl, @@ -3680,7 +3702,7 @@ void builtin_specialeffect2(ScriptState *st) { dumb_ptr<map_session_data> sd = script_rid2sd(st); - if (sd == NULL) + if (sd == nullptr) return; clif_specialeffect(sd, @@ -3700,13 +3722,13 @@ void builtin_nude(ScriptState *st) { dumb_ptr<map_session_data> sd = script_rid2sd(st); - if (sd == NULL) + if (sd == nullptr) return; for (EQUIP i : EQUIPs) { - int idx = sd->equip_index_maybe[i]; - if (idx >= 0) + IOff0 idx = sd->equip_index_maybe[i]; + if (idx.ok()) pc_unequipitem(sd, idx, CalcStatus::LATER); } pc_calcstatus(sd, 0); @@ -3722,15 +3744,15 @@ static void builtin_unequipbyid(ScriptState *st) { dumb_ptr<map_session_data> sd = script_rid2sd(st); - if (sd == NULL) + if (sd == nullptr) return; EQUIP slot_id = EQUIP(conv_num(st, &AARGO2(2))); if (slot_id >= EQUIP() && slot_id < EQUIP::COUNT) { - int idx = sd->equip_index_maybe[slot_id]; - if (idx >= 0) + IOff0 idx = sd->equip_index_maybe[slot_id]; + if (idx.ok()) pc_unequipitem(sd, idx, CalcStatus::LATER); } @@ -3753,7 +3775,7 @@ void builtin_gmcommand(ScriptState *st) sd = script_rid2sd(st); dumb_string cmd = conv_str(st, &AARGO2(2)); - is_atcommand(sd->sess, sd, cmd, 99); + is_atcommand(sd->sess, sd, cmd, GmLevel::from(-1U)); } @@ -3766,7 +3788,7 @@ static void builtin_npcwarp(ScriptState *st) { int x, y; - dumb_ptr<npc_data> nd = NULL; + dumb_ptr<npc_data> nd = nullptr; x = conv_num(st, &AARGO2(2)); y = conv_num(st, &AARGO2(3)); @@ -3775,7 +3797,7 @@ void builtin_npcwarp(ScriptState *st) if (!nd) { - PRINTF("builtin_npcwarp: no such npc: %s\n", npc); + PRINTF("builtin_npcwarp: no such npc: %s\n"_fmt, npc); return; } @@ -3808,7 +3830,7 @@ void builtin_message(ScriptState *st) ZString msg = ZString(conv_str(st, &AARGO2(3))); dumb_ptr<map_session_data> pl_sd = map_nick2sd(player); - if (pl_sd == NULL) + if (pl_sd == nullptr) return; clif_displaymessage(pl_sd->sess, msg); @@ -3828,11 +3850,7 @@ void builtin_npctalk(ScriptState *st) if (nd) { - MString message; - message += nd->name; - message += " : "; - message += ZString(str); - clif_message(nd, AString(message)); + clif_message(nd, XString(str)); } } @@ -3856,13 +3874,13 @@ void builtin_getlook(ScriptState *st) val = static_cast<uint16_t>(sd->status.weapon); break; case LOOK::HEAD_BOTTOM: //3 - val = sd->status.head_bottom; + val = unwrap<ItemNameId>(sd->status.head_bottom); break; case LOOK::HEAD_TOP: //4 - val = sd->status.head_top; + val = unwrap<ItemNameId>(sd->status.head_top); break; case LOOK::HEAD_MID: //5 - val = sd->status.head_mid; + val = unwrap<ItemNameId>(sd->status.head_mid); break; case LOOK::HAIR_COLOR: //6 val = sd->status.hair_color; @@ -3871,7 +3889,7 @@ void builtin_getlook(ScriptState *st) val = sd->status.clothes_color; break; case LOOK::SHIELD: //8 - val = sd->status.shield; + val = unwrap<ItemNameId>(sd->status.shield); break; case LOOK::SHOES: //9 break; @@ -3988,7 +4006,7 @@ void builtin_shop(ScriptState *st) nd = npc_name2id(name); if (!nd) { - PRINTF("builtin_shop: no such npc: %s\n", name); + PRINTF("builtin_shop: no such npc: %s\n"_fmt, name); return; } @@ -4017,11 +4035,11 @@ void builtin_fakenpcname(ScriptState *st) { NpcName name = stringish<NpcName>(ZString(conv_str(st, &AARGO2(2)))); NpcName newname = stringish<NpcName>(ZString(conv_str(st, &AARGO2(3)))); - int newsprite = conv_num(st, &AARGO2(4)); + Species newsprite = wrap<Species>(static_cast<uint16_t>(conv_num(st, &AARGO2(4)))); dumb_ptr<npc_data> nd = npc_name2id(name); if (!nd) { - PRINTF("builtin_fakenpcname: no such npc: %s\n", name); + PRINTF("builtin_fakenpcname: no such npc: %s\n"_fmt, name); return; } nd->name = newname; @@ -4205,7 +4223,7 @@ void op_2str(ScriptState *st, ByteCode op, dumb_string s1_, dumb_string s2_) a = s1 <= s2; break; default: - PRINTF("illegal string operater\n"); + PRINTF("illegal string operater\n"_fmt); break; } @@ -4308,7 +4326,7 @@ void op_2(ScriptState *st, ByteCode op) else { // si,is => error - PRINTF("script: op_2: int&str, str&int not allow.\n"); + PRINTF("script: op_2: int&str, str&int not allow.\n"_fmt); push_int(st->stack, ByteCode::INT, 0); } } @@ -4351,7 +4369,7 @@ void run_func(ScriptState *st) if (start_sp == 0) { if (battle_config.error_log) - PRINTF("function not found\n"); + PRINTF("function not found\n"_fmt); st->state = ScriptEndState::END; return; } @@ -4364,52 +4382,52 @@ void run_func(ScriptState *st) size_t func = st->stack->stack_datav[st->start].u.numi; if (st->stack->stack_datav[st->start].type != ByteCode::FUNC_REF) { - PRINTF("run_func: not function and command! \n"); + PRINTF("run_func: not function and command! \n"_fmt); st->state = ScriptEndState::END; return; } if (DEBUG_RUN && battle_config.etc_log) { - PRINTF("run_func : %s\n", + PRINTF("run_func : %s\n"_fmt, builtin_functions[func].name); - PRINTF("stack dump :"); + PRINTF("stack dump :"_fmt); for (script_data& d : st->stack->stack_datav) { switch (d.type) { case ByteCode::INT: - PRINTF(" int(%d)", d.u.numi); + PRINTF(" int(%d)"_fmt, d.u.numi); break; case ByteCode::RETINFO: - PRINTF(" retinfo(%p)", static_cast<const void *>(d.u.script)); + PRINTF(" retinfo(%p)"_fmt, static_cast<const void *>(d.u.script)); break; case ByteCode::PARAM_: - PRINTF(" param(%d)", d.u.reg.sp()); + PRINTF(" param(%d)"_fmt, d.u.reg.sp()); break; case ByteCode::VARIABLE: - PRINTF(" name(%s)[%d]", variable_names.outtern(d.u.reg.base()), d.u.reg.index()); + PRINTF(" name(%s)[%d]"_fmt, variable_names.outtern(d.u.reg.base()), d.u.reg.index()); break; case ByteCode::ARG: - PRINTF(" arg"); + PRINTF(" arg"_fmt); break; case ByteCode::POS: - PRINTF(" pos(%d)", d.u.numi); + PRINTF(" pos(%d)"_fmt, d.u.numi); break; case ByteCode::STR: - PRINTF(" str(%s)", d.u.str); + PRINTF(" str(%s)"_fmt, d.u.str); break; case ByteCode::CONSTSTR: - PRINTF(" cstr(%s)", d.u.str); + PRINTF(" cstr(%s)"_fmt, d.u.str); break; case ByteCode::FUNC_REF: - PRINTF(" func(%s)", builtin_functions[d.u.numi].name); + PRINTF(" func(%s)"_fmt, builtin_functions[d.u.numi].name); break; default: - PRINTF(" %d,%d", d.type, d.u.numi); + PRINTF(" %d,%d"_fmt, d.type, d.u.numi); } } - PRINTF("\n"); + PRINTF("\n"_fmt); } builtin_functions[func].func(st); @@ -4424,7 +4442,7 @@ void run_func(ScriptState *st) if (st->defsp < 4 || st->stack->stack_datav[st->defsp - 1].type != ByteCode::RETINFO) { - PRINTF("script:run_func (return) return without callfunc or callsub!\n"); + PRINTF("script:run_func (return) return without callfunc or callsub!\n"_fmt); st->state = ScriptEndState::END; return; } @@ -4449,15 +4467,15 @@ void dump_script(const ScriptBuffer *script) ScriptPointer scriptp(script, 0); while (scriptp.pos < reinterpret_cast<const std::vector<ByteCode> *>(script)->size()) { - PRINTF("%6zu: ", scriptp.pos); + PRINTF("%6zu: "_fmt, scriptp.pos); switch (ByteCode c = get_com(&scriptp)) { case ByteCode::EOL: - PRINTF("EOL\n"); // extra newline between functions + PRINTF("EOL\n"_fmt); // extra newline between functions break; case ByteCode::INT: // synthesized! - PRINTF("INT %d", get_num(&scriptp)); + PRINTF("INT %d"_fmt, get_num(&scriptp)); break; case ByteCode::POS: @@ -4472,103 +4490,103 @@ void dump_script(const ScriptBuffer *script) switch(c) { case ByteCode::POS: - PRINTF("POS %d", arg); + PRINTF("POS %d"_fmt, arg); break; case ByteCode::VARIABLE: - PRINTF("VARIABLE %s", variable_names.outtern(arg)); + PRINTF("VARIABLE %s"_fmt, variable_names.outtern(arg)); break; case ByteCode::FUNC_REF: - PRINTF("FUNC_REF %s", builtin_functions[arg].name); + PRINTF("FUNC_REF %s"_fmt, builtin_functions[arg].name); break; case ByteCode::PARAM_: - PRINTF("PARAM SP::#%d (sorry)", arg); + PRINTF("PARAM SP::#%d (sorry)"_fmt, arg); break; } } break; case ByteCode::ARG: - PRINTF("ARG"); + PRINTF("ARG"_fmt); break; case ByteCode::STR: - PRINTF("STR \"%s\"", scriptp.pops()); + PRINTF("STR \"%s\""_fmt, scriptp.pops()); break; case ByteCode::FUNC_: - PRINTF("FUNC_"); + PRINTF("FUNC_"_fmt); break; case ByteCode::ADD: - PRINTF("ADD"); + PRINTF("ADD"_fmt); break; case ByteCode::SUB: - PRINTF("SUB"); + PRINTF("SUB"_fmt); break; case ByteCode::MUL: - PRINTF("MUL"); + PRINTF("MUL"_fmt); break; case ByteCode::DIV: - PRINTF("DIV"); + PRINTF("DIV"_fmt); break; case ByteCode::MOD: - PRINTF("MOD"); + PRINTF("MOD"_fmt); break; case ByteCode::EQ: - PRINTF("EQ"); + PRINTF("EQ"_fmt); break; case ByteCode::NE: - PRINTF("NE"); + PRINTF("NE"_fmt); break; case ByteCode::GT: - PRINTF("GT"); + PRINTF("GT"_fmt); break; case ByteCode::GE: - PRINTF("GE"); + PRINTF("GE"_fmt); break; case ByteCode::LT: - PRINTF("LT"); + PRINTF("LT"_fmt); break; case ByteCode::LE: - PRINTF("LE"); + PRINTF("LE"_fmt); break; case ByteCode::AND: - PRINTF("AND"); + PRINTF("AND"_fmt); break; case ByteCode::OR: - PRINTF("OR"); + PRINTF("OR"_fmt); break; case ByteCode::XOR: - PRINTF("XOR"); + PRINTF("XOR"_fmt); break; case ByteCode::LAND: - PRINTF("LAND"); + PRINTF("LAND"_fmt); break; case ByteCode::LOR: - PRINTF("LOR"); + PRINTF("LOR"_fmt); break; case ByteCode::R_SHIFT: - PRINTF("R_SHIFT"); + PRINTF("R_SHIFT"_fmt); break; case ByteCode::L_SHIFT: - PRINTF("L_SHIFT"); + PRINTF("L_SHIFT"_fmt); break; case ByteCode::NEG: - PRINTF("NEG"); + PRINTF("NEG"_fmt); break; case ByteCode::NOT: - PRINTF("NOT"); + PRINTF("NOT"_fmt); break; case ByteCode::LNOT: - PRINTF("LNOT"); + PRINTF("LNOT"_fmt); break; case ByteCode::NOP: - PRINTF("NOP"); + PRINTF("NOP"_fmt); break; default: - PRINTF("??? %d", c); + PRINTF("??? %d"_fmt, c); break; } - PRINTF("\n"); + PRINTF("\n"_fmt); } } @@ -4595,7 +4613,7 @@ void run_script_main(ScriptState *st, const ScriptBuffer *rootscript) if (stack->stack_datav.size() != st->defsp) { if (battle_config.error_log) - PRINTF("stack.sp (%zu) != default (%d)\n", + PRINTF("stack.sp (%zu) != default (%d)\n"_fmt, stack->stack_datav.size(), st->defsp); stack->stack_datav.resize(st->defsp); @@ -4650,7 +4668,7 @@ void run_script_main(ScriptState *st, const ScriptBuffer *rootscript) st->state = ScriptEndState::ZERO; if (gotocount > 0 && (--gotocount) <= 0) { - PRINTF("run_script: infinity loop !\n"); + PRINTF("run_script: infinity loop !\n"_fmt); st->state = ScriptEndState::END; } } @@ -4692,14 +4710,14 @@ void run_script_main(ScriptState *st, const ScriptBuffer *rootscript) default: if (battle_config.error_log) - PRINTF("unknown command : %d @ %zu\n", + PRINTF("unknown command : %d @ %zu\n"_fmt, c, st->scriptp.pos); st->state = ScriptEndState::END; break; } if (cmdcount > 0 && (--cmdcount) <= 0) { - PRINTF("run_script: infinity loop !\n"); + PRINTF("run_script: infinity loop !\n"_fmt); st->state = ScriptEndState::END; } } @@ -4739,12 +4757,12 @@ void run_script_main(ScriptState *st, const ScriptBuffer *rootscript) * スクリプトの実行 *------------------------------------------ */ -int run_script(ScriptPointer sp, int rid, int oid) +int run_script(ScriptPointer sp, BlockId rid, BlockId oid) { return run_script_l(sp, rid, oid, nullptr); } -int run_script_l(ScriptPointer sp, int rid, int oid, +int run_script_l(ScriptPointer sp, BlockId rid, BlockId oid, Slice<argrec_t> args) { struct script_stack stack; @@ -4752,7 +4770,7 @@ int run_script_l(ScriptPointer sp, int rid, int oid, dumb_ptr<map_session_data> sd = map_id2sd(rid); const ScriptBuffer *rootscript = sp.code; int i; - if (sp.code == NULL || sp.pos >> 24) + if (sp.code == nullptr || sp.pos >> 24) return -1; if (sd && !sd->npc_stackbuf.empty() && sd->npc_scriptroot == rootscript) @@ -4846,7 +4864,7 @@ void script_load_mapreg(void) else { borken: - PRINTF("%s: %s broken data !\n", mapreg_txt, AString(buf1)); + PRINTF("%s: %s broken data !\n"_fmt, mapreg_txt, AString(buf1)); continue; } } @@ -4865,9 +4883,9 @@ void script_save_mapreg_intsub(SIR key, int data, io::WriteFile& fp) if (name[1] != '@') { if (i == 0) - FPRINTF(fp, "%s\t%d\n", name, data); + FPRINTF(fp, "%s\t%d\n"_fmt, name, data); else - FPRINTF(fp, "%s,%d\t%d\n", name, i, data); + FPRINTF(fp, "%s,%d\t%d\n"_fmt, name, i, data); } } @@ -4879,9 +4897,9 @@ void script_save_mapreg_strsub(SIR key, ZString data, io::WriteFile& fp) if (name[1] != '@') { if (i == 0) - FPRINTF(fp, "%s\t%s\n", name, data); + FPRINTF(fp, "%s\t%s\n"_fmt, name, data); else - FPRINTF(fp, "%s,%d\t%s\n", name, i, data); + FPRINTF(fp, "%s,%d\t%s\n"_fmt, name, i, data); } } @@ -4932,129 +4950,128 @@ void do_init_script(void) ).detach(); } -#define BUILTIN(func, args) \ -{builtin_##func, {#func}, {args}} +#define BUILTIN(func, args, ret) \ +{builtin_##func, #func ## _s, args, ret} BuiltinFunction builtin_functions[] = { - BUILTIN(mes, "s"), - BUILTIN(next, ""), - BUILTIN(close, ""), - BUILTIN(close2, ""), - BUILTIN(menu, "sL*"), - BUILTIN(goto, "L"), - BUILTIN(callsub, "L"), - BUILTIN(callfunc, "F"), - BUILTIN(return, ""), - BUILTIN(input, "N"), - BUILTIN(warp, "Mxy"), - BUILTIN(isat, "Mxy"), - BUILTIN(areawarp, "MxyxyMxy"), - BUILTIN(setlook, "ii"), - BUILTIN(set, "Ne"), - BUILTIN(setarray, "Ne*"), - BUILTIN(cleararray, "Nei"), - BUILTIN(getarraysize, "N"), - BUILTIN(getelementofarray, "Ni"), - BUILTIN(if, "iF*"), - BUILTIN(getitem, "Ii**"), - BUILTIN(makeitem, "IiMxy"), - BUILTIN(delitem, "Ii"), - BUILTIN(heal, "ii"), - BUILTIN(itemheal, "ii"), - BUILTIN(percentheal, "ii"), - BUILTIN(rand, "i*"), - BUILTIN(pow, "ii"), - BUILTIN(countitem, "I"), - BUILTIN(checkweight, "Ii"), - BUILTIN(readparam, "i*"), - BUILTIN(getcharid, "i*"), - BUILTIN(strcharinfo, "i"), - BUILTIN(getequipid, "i"), - BUILTIN(getequipname, "i"), - BUILTIN(statusup2, "ii"), - BUILTIN(bonus, "ii"), - BUILTIN(bonus2, "iii"), - BUILTIN(skill, "ii*"), - BUILTIN(setskill, "ii"), - BUILTIN(getskilllv, "i"), - BUILTIN(getgmlevel, ""), - BUILTIN(end, ""), - BUILTIN(getopt2, ""), - BUILTIN(setopt2, "i"), - BUILTIN(savepoint, "Mxy"), - BUILTIN(gettimetick, "i"), - BUILTIN(gettime, "i"), - BUILTIN(openstorage, "*"), - BUILTIN(monster, "Mxysmi*"), - BUILTIN(areamonster, "Mxyxysmi*"), - BUILTIN(killmonster, "ME"), - BUILTIN(killmonsterall, "M"), - BUILTIN(donpcevent, "E"), - BUILTIN(addtimer, "tE"), - BUILTIN(initnpctimer, ""), - BUILTIN(stopnpctimer, ""), - BUILTIN(startnpctimer, "*"), - BUILTIN(setnpctimer, "i"), - BUILTIN(getnpctimer, "i"), - BUILTIN(announce, "si"), - BUILTIN(mapannounce, "Msi"), - BUILTIN(getusers, "i"), - BUILTIN(getmapusers, "M"), - BUILTIN(getareausers, "Mxyxy*"), - BUILTIN(getareadropitem, "Mxyxyi*"), - BUILTIN(enablenpc, "s"), - BUILTIN(disablenpc, "s"), - BUILTIN(sc_start, "iTi*"), - BUILTIN(sc_end, "i"), - BUILTIN(sc_check, "i"), - BUILTIN(debugmes, "s"), - BUILTIN(resetstatus, ""), - BUILTIN(changesex, ""), - BUILTIN(attachrid, "i"), - BUILTIN(detachrid, ""), - BUILTIN(isloggedin, "i"), - BUILTIN(setmapflag, "Mi"), - BUILTIN(removemapflag, "Mi"), - BUILTIN(getmapflag, "Mi"), - BUILTIN(pvpon, "M"), - BUILTIN(pvpoff, "M"), - BUILTIN(emotion, "i"), - BUILTIN(marriage, "P"), - BUILTIN(divorce, ""), - BUILTIN(getitemname, "I"), - BUILTIN(getspellinvocation, "s"), - BUILTIN(getpartnerid2, ""), - BUILTIN(getexp, "ii"), - BUILTIN(getinventorylist, ""), - BUILTIN(getactivatedpoolskilllist, ""), - BUILTIN(getunactivatedpoolskilllist, ""), - BUILTIN(poolskill, "i"), - BUILTIN(unpoolskill, "i"), - BUILTIN(misceffect, "i*"), - BUILTIN(specialeffect, "i"), - BUILTIN(specialeffect2, "i"), - BUILTIN(nude, ""), - BUILTIN(mapwarp, "MMxy"), - BUILTIN(cmdothernpc, "ss"), - BUILTIN(gmcommand, "s"), - BUILTIN(npcwarp, "xys"), - BUILTIN(message, "Ps"), - BUILTIN(npctalk, "s"), - BUILTIN(mobcount, "ME"), - BUILTIN(getlook, "i"), - BUILTIN(getsavepoint, "i"), - BUILTIN(areatimer, "MxyxytE"), - BUILTIN(isin, "Mxyxy"), - BUILTIN(shop, "s"), - BUILTIN(isdead, ""), - BUILTIN(unequipbyid, "i"), - BUILTIN(fakenpcname, "ssi"), - BUILTIN(getx, ""), - BUILTIN(gety, ""), - BUILTIN(getmap, ""), - BUILTIN(mapexit, ""), - {nullptr, ZString(), ZString()}, + BUILTIN(mes, "s"_s, '\0'), + BUILTIN(goto, "L"_s, '\0'), + BUILTIN(callfunc, "F"_s, '\0'), + BUILTIN(callsub, "L"_s, '\0'), + BUILTIN(return, ""_s, '\0'), + BUILTIN(next, ""_s, '\0'), + BUILTIN(close, ""_s, '\0'), + BUILTIN(close2, ""_s, '\0'), + BUILTIN(menu, "sL**"_s, '\0'), + BUILTIN(rand, "i?"_s, 'i'), + BUILTIN(isat, "Mxy"_s, 'i'), + BUILTIN(warp, "Mxy"_s, '\0'), + BUILTIN(areawarp, "MxyxyMxy"_s, '\0'), + BUILTIN(heal, "ii"_s, '\0'), + BUILTIN(itemheal, "ii"_s, '\0'), + BUILTIN(percentheal, "ii"_s, '\0'), + BUILTIN(input, "N"_s, '\0'), + BUILTIN(if, "iF*"_s, '\0'), + BUILTIN(set, "Ne"_s, '\0'), + BUILTIN(setarray, "Ne*"_s, '\0'), + BUILTIN(cleararray, "Nei"_s, '\0'), + BUILTIN(getarraysize, "N"_s, 'i'), + BUILTIN(getelementofarray, "Ni"_s, '.'), + BUILTIN(setlook, "ii"_s, '\0'), + BUILTIN(countitem, "I"_s, 'i'), + BUILTIN(checkweight, "Ii"_s, 'i'), + BUILTIN(getitem, "Ii??"_s, '\0'), + BUILTIN(makeitem, "IiMxy"_s, '\0'), + BUILTIN(delitem, "Ii"_s, '\0'), + BUILTIN(readparam, "i?"_s, 'i'), + BUILTIN(getcharid, "i?"_s, 'i'), + BUILTIN(strcharinfo, "i"_s, 's'), + BUILTIN(getequipid, "i"_s, 'i'), + BUILTIN(getequipname, "i"_s, 's'), + BUILTIN(statusup2, "ii"_s, '\0'), + BUILTIN(bonus, "ii"_s, '\0'), + BUILTIN(bonus2, "iii"_s, '\0'), + BUILTIN(skill, "ii?"_s, '\0'), + BUILTIN(setskill, "ii"_s, '\0'), + BUILTIN(getskilllv, "i"_s, 'i'), + BUILTIN(getgmlevel, ""_s, 'i'), + BUILTIN(end, ""_s, '\0'), + BUILTIN(getopt2, ""_s, 'i'), + BUILTIN(setopt2, "i"_s, '\0'), + BUILTIN(savepoint, "Mxy"_s, '\0'), + BUILTIN(gettimetick, "i"_s, 'i'), + BUILTIN(gettime, "i"_s, 'i'), + BUILTIN(openstorage, ""_s, '\0'), + BUILTIN(getexp, "ii"_s, '\0'), + BUILTIN(monster, "Mxysmi?"_s, '\0'), + BUILTIN(areamonster, "Mxyxysmi?"_s, '\0'), + BUILTIN(killmonster, "ME"_s, '\0'), + BUILTIN(killmonsterall, "M"_s, '\0'), + BUILTIN(donpcevent, "E"_s, '\0'), + BUILTIN(addtimer, "tE"_s, '\0'), + BUILTIN(initnpctimer, ""_s, '\0'), + BUILTIN(startnpctimer, "?"_s, '\0'), + BUILTIN(stopnpctimer, ""_s, '\0'), + BUILTIN(getnpctimer, "i"_s, 'i'), + BUILTIN(setnpctimer, "i"_s, '\0'), + BUILTIN(announce, "si"_s, '\0'), + BUILTIN(mapannounce, "Msi"_s, '\0'), + BUILTIN(getusers, "i"_s, 'i'), + BUILTIN(getmapusers, "M"_s, 'i'), + BUILTIN(getareausers, "Mxyxy?"_s, 'i'), + BUILTIN(getareadropitem, "Mxyxyi?"_s, 'i'), + BUILTIN(enablenpc, "s"_s, '\0'), + BUILTIN(disablenpc, "s"_s, '\0'), + BUILTIN(sc_start, "iTi?"_s, '\0'), + BUILTIN(sc_end, "i"_s, '\0'), + BUILTIN(sc_check, "i"_s, 'i'), + BUILTIN(debugmes, "s"_s, '\0'), + BUILTIN(resetstatus, ""_s, '\0'), + BUILTIN(changesex, ""_s, '\0'), + BUILTIN(attachrid, "i"_s, 'i'), + BUILTIN(detachrid, ""_s, '\0'), + BUILTIN(isloggedin, "i"_s, 'i'), + BUILTIN(setmapflag, "Mi"_s, '\0'), + BUILTIN(removemapflag, "Mi"_s, '\0'), + BUILTIN(getmapflag, "Mi"_s, 'i'), + BUILTIN(pvpon, "M"_s, '\0'), + BUILTIN(pvpoff, "M"_s, '\0'), + BUILTIN(emotion, "i"_s, '\0'), + BUILTIN(mapwarp, "MMxy"_s, '\0'), + BUILTIN(cmdothernpc, "ss"_s, '\0'), + BUILTIN(mobcount, "ME"_s, 'i'), + BUILTIN(marriage, "P"_s, 'i'), + BUILTIN(divorce, ""_s, 'i'), + BUILTIN(getitemname, "I"_s, 's'), + BUILTIN(getspellinvocation, "s"_s, 's'), + BUILTIN(getpartnerid2, ""_s, 'i'), + BUILTIN(getinventorylist, ""_s, '\0'), + BUILTIN(getactivatedpoolskilllist, ""_s, '\0'), + BUILTIN(getunactivatedpoolskilllist, ""_s, '\0'), + BUILTIN(poolskill, "i"_s, '\0'), + BUILTIN(unpoolskill, "i"_s, '\0'), + BUILTIN(misceffect, "i?"_s, '\0'), + BUILTIN(specialeffect, "i"_s, '\0'), + BUILTIN(specialeffect2, "i"_s, '\0'), + BUILTIN(nude, ""_s, '\0'), + BUILTIN(unequipbyid, "i"_s, '\0'), + BUILTIN(gmcommand, "s"_s, '\0'), + BUILTIN(npcwarp, "xys"_s, '\0'), + BUILTIN(message, "Ps"_s, '\0'), + BUILTIN(npctalk, "s"_s, '\0'), + BUILTIN(getlook, "i"_s, 'i'), + BUILTIN(getsavepoint, "i"_s, '.'), + BUILTIN(areatimer, "MxyxytE"_s, '\0'), + BUILTIN(isin, "Mxyxy"_s, 'i'), + BUILTIN(shop, "s"_s, '\0'), + BUILTIN(isdead, ""_s, 'i'), + BUILTIN(fakenpcname, "ssi"_s, '\0'), + BUILTIN(getx, ""_s, 'i'), + BUILTIN(gety, ""_s, 'i'), + BUILTIN(getmap, ""_s, 's'), + BUILTIN(mapexit, ""_s, '\0'), + {nullptr, ""_s, ""_s, '\0'}, }; void set_script_var_i(dumb_ptr<map_session_data> sd, VarName var, int e, int val) @@ -5079,7 +5096,7 @@ int get_script_var_i(dumb_ptr<map_session_data> sd, VarName var, int e) get_val(sd, &dat); if (dat.type == ByteCode::INT) return dat.u.numi; - PRINTF("Warning: you lied about the type and I'm too lazy to fix it!"); + PRINTF("Warning: you lied about the type and I'm too lazy to fix it!"_fmt); return 0; } ZString get_script_var_s(dumb_ptr<map_session_data> sd, VarName var, int e) @@ -5092,6 +5109,7 @@ ZString get_script_var_s(dumb_ptr<map_session_data> sd, VarName var, int e) get_val(sd, &dat); if (dat.type == ByteCode::CONSTSTR) return dat.u.str; - PRINTF("Warning: you lied about the type and I can't fix it!"); + PRINTF("Warning: you lied about the type and I can't fix it!"_fmt); return ZString(); } +} // namespace tmwa diff --git a/src/map/script.hpp b/src/map/script.hpp index 9ae893d..ee9a5a9 100644 --- a/src/map/script.hpp +++ b/src/map/script.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_SCRIPT_HPP -#define TMWA_MAP_SCRIPT_HPP +#pragma once // script.hpp - EAthena script frontend, engine, and library. // // Copyright © ????-2004 Athena Dev Teams @@ -21,26 +20,27 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdint> -# include <cstring> // for inlined get_str - TODO remove +#include <cstdint> -# include <vector> +#include <vector> -# include "../range/slice.hpp" +#include "../range/slice.hpp" -# include "../strings/rstring.hpp" -# include "../strings/astring.hpp" -# include "../strings/zstring.hpp" +#include "../strings/zstring.hpp" -# include "../generic/db.hpp" +#include "../generic/db.hpp" +#include "../generic/dumb_ptr.hpp" -# include "../mmo/dumb_ptr.hpp" -# include "../mmo/utils.hpp" +#include "../mmo/ids.hpp" -# include "map.t.hpp" +#include "clif.t.hpp" +#include "map.t.hpp" + +namespace tmwa +{ enum class ByteCode : uint8_t; struct str_data_t; @@ -155,7 +155,7 @@ public: struct script_stack *stack; int start, end; ScriptEndState state; - int rid, oid; + BlockId rid, oid; ScriptPointer scriptp, new_scriptp; int defsp, new_defsp; }; @@ -177,10 +177,9 @@ struct argrec_t argrec_t(ZString n, int i) : name(n), v(i) {} argrec_t(ZString n, ZString z) : name(n), v(z) {} }; -int run_script_l(ScriptPointer, int, int, Slice<argrec_t> args); -int run_script(ScriptPointer, int, int); +int run_script_l(ScriptPointer, BlockId, BlockId, Slice<argrec_t> args); +int run_script(ScriptPointer, BlockId, BlockId); -struct ScriptLabel; extern Map<ScriptLabel, int> scriptlabel_db; extern @@ -200,5 +199,4 @@ void set_script_var_s(dumb_ptr<map_session_data> sd, VarName var, int e, XString int get_script_var_i(dumb_ptr<map_session_data> sd, VarName var, int e); ZString get_script_var_s(dumb_ptr<map_session_data> sd, VarName var, int e); - -#endif // TMWA_MAP_SCRIPT_HPP +} // namespace tmwa diff --git a/src/map/script.py b/src/map/script.py index 068307a..dcde08d 100644 --- a/src/map/script.py +++ b/src/map/script.py @@ -3,7 +3,7 @@ class ByteCode: (workaround for gcc bug 58150) ''' __slots__ = ('_value') - name = 'ByteCode' + name = 'tmwa::ByteCode' enabled = True def __init__(self, value): @@ -34,7 +34,7 @@ class script_data(object): ''' print a script_data ''' __slots__ = ('_value') - name = 'script_data' + name = 'tmwa::script_data' enabled = True def __init__(self, value): diff --git a/src/map/skill-pools.cpp b/src/map/skill-pools.cpp index 6b46d79..e37b7e3 100644 --- a/src/map/skill-pools.cpp +++ b/src/map/skill-pools.cpp @@ -1,3 +1,4 @@ +#include "skill-pools.hpp" #include "skill.hpp" // skill-pools.cpp - Additional support for focusable skills. // @@ -26,6 +27,9 @@ #include "../poison.hpp" + +namespace tmwa +{ Array<SkillID, MAX_POOL_SKILLS> skill_pool_skills; int skill_pool_skills_size = 0; @@ -34,7 +38,7 @@ void skill_pool_register(SkillID id) if (skill_pool_skills_size + 1 >= MAX_POOL_SKILLS) { FPRINTF(stderr, - "Too many pool skills! Increase MAX_POOL_SKILLS and recompile."); + "Too many pool skills! Increase MAX_POOL_SKILLS and recompile."_fmt); return; } @@ -61,7 +65,7 @@ int skill_pool(dumb_ptr<map_session_data> sd, SkillID *skills) int skill_pool_size(dumb_ptr<map_session_data> sd) { - return skill_pool(sd, NULL); + return skill_pool(sd, nullptr); } int skill_pool_max(dumb_ptr<map_session_data> sd) @@ -78,7 +82,7 @@ int skill_pool_activate(dumb_ptr<map_session_data> sd, SkillID skill_id) { sd->status.skill[skill_id].flags |= SkillFlags::POOL_ACTIVATED; pc_calcstatus(sd, 0); - MAP_LOG_PC(sd, "SKILL-ACTIVATE %d %d %d", + MAP_LOG_PC(sd, "SKILL-ACTIVATE %d %d %d"_fmt, skill_id, sd->status.skill[skill_id].lv, skill_power(sd, skill_id)); return 0; @@ -97,7 +101,7 @@ int skill_pool_deactivate(dumb_ptr<map_session_data> sd, SkillID skill_id) if (bool(sd->status.skill[skill_id].flags & SkillFlags::POOL_ACTIVATED)) { sd->status.skill[skill_id].flags &= ~SkillFlags::POOL_ACTIVATED; - MAP_LOG_PC(sd, "SKILL-DEACTIVATE %d", skill_id); + MAP_LOG_PC(sd, "SKILL-DEACTIVATE %d"_fmt, skill_id); pc_calcstatus(sd, 0); return 0; } @@ -142,3 +146,4 @@ int skill_power_bl(dumb_ptr<block_list> bl, SkillID skill) else return 0; } +} // namespace tmwa diff --git a/src/map/skill-pools.hpp b/src/map/skill-pools.hpp index 6781907..c8890e8 100644 --- a/src/map/skill-pools.hpp +++ b/src/map/skill-pools.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_SKILL_POOLS_HPP -#define TMWA_MAP_SKILL_POOLS_HPP +#pragma once // skill-pools.hpp - dummy header to make Make dependencies work. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,6 +18,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -#endif // TMWA_MAP_SKILL_POOLS_HPP + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 37a3b44..f579920 100644 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -22,9 +22,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include <cassert> -#include <cstdlib> -#include <cstring> -#include <ctime> + +#include <algorithm> #include "../compat/attr.hpp" #include "../compat/fun.hpp" @@ -32,56 +31,61 @@ #include "../strings/mstring.hpp" #include "../strings/rstring.hpp" +#include "../strings/astring.hpp" +#include "../strings/zstring.hpp" #include "../strings/xstring.hpp" +#include "../strings/literal.hpp" #include "../generic/random.hpp" #include "../io/cxxstdio.hpp" #include "../io/read.hpp" +#include "../net/timer.hpp" + #include "../mmo/extract.hpp" -#include "../mmo/socket.hpp" -#include "../mmo/timer.hpp" #include "battle.hpp" #include "clif.hpp" -#include "magic.hpp" -#include "map.hpp" +#include "magic-stmt.hpp" #include "mob.hpp" #include "pc.hpp" #include "../poison.hpp" + +namespace tmwa +{ struct skill_name_db skill_names[] = { - {SkillID::AC_OWL, "OWL", "Owl's_Eye"}, - - {SkillID::NPC_EMOTION, "EMOTION", "NPC_EMOTION"}, - {SkillID::NPC_POISON, "POISON", "NPC_POISON"}, - {SkillID::NPC_SELFDESTRUCTION, "SELFDESTRUCTION", "Kabooooom!"}, - {SkillID::NPC_SUMMONSLAVE, "SUMMONSLAVE", "NPC_SUMMONSLAVE"}, - - {SkillID::NV_EMOTE, "EMOTE", "Emote_Skill"}, - {SkillID::NV_TRADE, "TRADE", "Trade_Skill"}, - {SkillID::NV_PARTY, "PARTY", "Party_Skill"}, - - {SkillID::TMW_MAGIC, "MAGIC", "General Magic"}, - {SkillID::TMW_MAGIC_LIFE, "MAGIC_LIFE", "Life Magic"}, - {SkillID::TMW_MAGIC_WAR, "MAGIC_WAR", "War Magic"}, - {SkillID::TMW_MAGIC_TRANSMUTE, "MAGIC_TRANSMUTE", "Transmutation Magic"}, - {SkillID::TMW_MAGIC_NATURE, "MAGIC_NATURE", "Nature Magic"}, - {SkillID::TMW_MAGIC_ETHER, "MAGIC_ETHER", "Astral Magic"}, - {SkillID::TMW_MAGIC_DARK, "MAGIC_DARK", "Dark Magic"}, - {SkillID::TMW_MAGIC_LIGHT, "MAGIC_LIGHT", "Light Magic"}, - - {SkillID::TMW_BRAWLING, "BRAWLING", "Brawling"}, - {SkillID::TMW_LUCKY_COUNTER, "LUCKY_COUNTER", "Lucky Counter"}, - {SkillID::TMW_SPEED, "SPEED", "Speed"}, - {SkillID::TMW_RESIST_POISON, "RESIST_POISON", "Resist Poison"}, - {SkillID::TMW_ASTRAL_SOUL, "ASTRAL_SOUL", "Astral Soul"}, - {SkillID::TMW_RAGING, "RAGING", "Raging"}, - - {SkillID::ZERO, "", ""} + {SkillID::AC_OWL, "OWL"_s, "Owl's_Eye"_s}, + + {SkillID::NPC_EMOTION, "EMOTION"_s, "NPC_EMOTION"_s}, + {SkillID::NPC_POISON, "POISON"_s, "NPC_POISON"_s}, + {SkillID::NPC_SELFDESTRUCTION, "SELFDESTRUCTION"_s, "Kabooooom!"_s}, + {SkillID::NPC_SUMMONSLAVE, "SUMMONSLAVE"_s, "NPC_SUMMONSLAVE"_s}, + + {SkillID::NV_EMOTE, "EMOTE"_s, "Emote_Skill"_s}, + {SkillID::NV_TRADE, "TRADE"_s, "Trade_Skill"_s}, + {SkillID::NV_PARTY, "PARTY"_s, "Party_Skill"_s}, + + {SkillID::TMW_MAGIC, "MAGIC"_s, "General Magic"_s}, + {SkillID::TMW_MAGIC_LIFE, "MAGIC_LIFE"_s, "Life Magic"_s}, + {SkillID::TMW_MAGIC_WAR, "MAGIC_WAR"_s, "War Magic"_s}, + {SkillID::TMW_MAGIC_TRANSMUTE, "MAGIC_TRANSMUTE"_s, "Transmutation Magic"_s}, + {SkillID::TMW_MAGIC_NATURE, "MAGIC_NATURE"_s, "Nature Magic"_s}, + {SkillID::TMW_MAGIC_ETHER, "MAGIC_ETHER"_s, "Astral Magic"_s}, + {SkillID::TMW_MAGIC_DARK, "MAGIC_DARK"_s, "Dark Magic"_s}, + {SkillID::TMW_MAGIC_LIGHT, "MAGIC_LIGHT"_s, "Light Magic"_s}, + + {SkillID::TMW_BRAWLING, "BRAWLING"_s, "Brawling"_s}, + {SkillID::TMW_LUCKY_COUNTER, "LUCKY_COUNTER"_s, "Lucky Counter"_s}, + {SkillID::TMW_SPEED, "SPEED"_s, "Speed"_s}, + {SkillID::TMW_RESIST_POISON, "RESIST_POISON"_s, "Resist Poison"_s}, + {SkillID::TMW_ASTRAL_SOUL, "ASTRAL_SOUL"_s, "Astral Soul"_s}, + {SkillID::TMW_RAGING, "RAGING"_s, "Raging"_s}, + + {SkillID::ZERO, ""_s, ""_s} }; earray<skill_db_, SkillID, SkillID::MAX_SKILL_DB> skill_db; @@ -94,7 +98,7 @@ int skill_attack(BF attack_type, dumb_ptr<block_list> src, static void skill_status_change_timer(TimerData *tid, tick_t tick, - int id, StatusChange type); + BlockId id, StatusChange type); int skill_get_hit(SkillID id) { @@ -169,16 +173,16 @@ int skill_get_castnodex(SkillID id, int lv) int skill_additional_effect(dumb_ptr<block_list> src, dumb_ptr<block_list> bl, SkillID skillid, int skilllv) { - dumb_ptr<map_session_data> sd = NULL; - dumb_ptr<mob_data> md = NULL; + dumb_ptr<map_session_data> sd = nullptr; + dumb_ptr<mob_data> md = nullptr; int luk; int sc_def_mdef, sc_def_vit, sc_def_int, sc_def_luk; int sc_def_phys_shield_spell; - nullpo_ret(src); - nullpo_ret(bl); + nullpo_retz(src); + nullpo_retz(bl); if (skilllv < 0) return 0; @@ -256,16 +260,16 @@ int skill_attack(BF attack_type, dumb_ptr<block_list> src, eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; int type, lv, damage; - nullpo_ret(src); - nullpo_ret(dsrc); - nullpo_ret(bl); + nullpo_retz(src); + nullpo_retz(dsrc); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); //何もしない判定ここから if (dsrc->bl_m != bl->bl_m) //対象が同じマップにいなければ何もしない return 0; - if (src->bl_prev == NULL || dsrc->bl_prev == NULL || bl->bl_prev == NULL) //prevよくわからない※ + if (src->bl_prev == nullptr || dsrc->bl_prev == nullptr || bl->bl_prev == nullptr) //prevよくわからない※ return 0; if (src->bl_type == BL::PC && pc_isdead(src->is_player())) //術者?がPCですでに死んでいたら何もしない return 0; @@ -304,7 +308,7 @@ int skill_attack(BF attack_type, dumb_ptr<block_list> src, battle_damage(src, bl, damage, 0); /* ダメージがあるなら追加効果判定 */ - if (bl->bl_prev != NULL) + if (bl->bl_prev != nullptr) { dumb_ptr<map_session_data> sd = bl->is_player(); if (bl->bl_type != BL::PC || !pc_isdead(sd)) @@ -316,8 +320,7 @@ int skill_attack(BF attack_type, dumb_ptr<block_list> src, dumb_ptr<mob_data> md = bl->is_mob(); if (battle_config.mob_changetarget_byskill == 1) { - int target; - target = md->target_id; + BlockId target = md->target_id; if (src->bl_type == BL::PC) md->target_id = src->bl_id; mobskill_use(md, tick, MobSkillCondition::ANY); @@ -389,7 +392,9 @@ void skill_area_sub(dumb_ptr<block_list> bl, // these variables are set in the 'else' branches, // and used in the (recursive) 'if' branch -static int skill_area_temp_id, skill_area_temp_hp; +// TODO kill it, kill it with fire. +static BlockId skill_area_temp_id; +static int skill_area_temp_hp; /*========================================== @@ -401,7 +406,7 @@ int skill_castend_damage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl, SkillID skillid, int skilllv, tick_t tick, BCT flag) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; nullpo_retr(1, src); nullpo_retr(1, bl); @@ -411,7 +416,7 @@ int skill_castend_damage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl, if (sd && pc_isdead(sd)) return 1; - if (bl->bl_prev == NULL) + if (bl->bl_prev == nullptr) return 1; if (bl->bl_type == BL::PC && pc_isdead(bl->is_player())) return 1; @@ -496,10 +501,10 @@ int skill_castend_damage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl, int skill_castend_nodamage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl, SkillID skillid, int skilllv) { - dumb_ptr<map_session_data> sd = NULL; - dumb_ptr<map_session_data> dstsd = NULL; - dumb_ptr<mob_data> md = NULL; - dumb_ptr<mob_data> dstmd = NULL; + dumb_ptr<map_session_data> sd = nullptr; + dumb_ptr<map_session_data> dstsd = nullptr; + dumb_ptr<mob_data> md = nullptr; + dumb_ptr<mob_data> dstmd = nullptr; int sc_def_vit, sc_def_mdef, strip_fix; nullpo_retr(1, src); @@ -534,7 +539,7 @@ int skill_castend_nodamage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl, if (strip_fix < 0) strip_fix = 0; - if (bl == NULL || bl->bl_prev == NULL) + if (bl == nullptr || bl->bl_prev == nullptr) return 1; if (sd && pc_isdead(sd)) return 1; @@ -594,7 +599,7 @@ interval_t skill_castfix(dumb_ptr<block_list> bl, interval_t interval) sc_data = battle_get_sc_data(bl); dex = battle_get_dex(bl); - if (skill > SkillID::MAX_SKILL_DB /*|| skill < SkillID()*/) + if (skill >= SkillID::MAX_SKILL_DB /*|| skill < SkillID()*/) return interval_t::zero(); castnodex = skill_get_castnodex(skill, lv); @@ -649,7 +654,7 @@ interval_t skill_delayfix(dumb_ptr<block_list> bl, interval_t interval) */ int skill_castcancel(dumb_ptr<block_list> bl, int) { - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type == BL::PC) { @@ -686,11 +691,11 @@ int skill_status_change_active(dumb_ptr<block_list> bl, StatusChange type) { eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; - nullpo_ret(bl); + nullpo_retz(bl); if (bl->bl_type != BL::PC && bl->bl_type != BL::MOB) { if (battle_config.error_log) - PRINTF("skill_status_change_active: neither MOB nor PC !\n"); + PRINTF("skill_status_change_active: neither MOB nor PC !\n"_fmt); return 0; } @@ -715,7 +720,7 @@ void skill_status_change_end(dumb_ptr<block_list> bl, StatusChange type, TimerDa if (bl->bl_type != BL::PC && bl->bl_type != BL::MOB) { if (battle_config.error_log) - PRINTF("skill_status_change_end: neither MOB nor PC !\n"); + PRINTF("skill_status_change_end: neither MOB nor PC !\n"_fmt); return; } sc_data = battle_get_sc_data(bl); @@ -804,7 +809,7 @@ int skill_update_heal_animation(dumb_ptr<map_session_data> sd) { const Opt2 mask = Opt2::_heal; - nullpo_ret(sd); + nullpo_retz(sd); bool wis_active = bool(sd->opt2 & mask); bool is_active = sd->quick_regeneration_hp.amount > 0; @@ -823,14 +828,14 @@ int skill_update_heal_animation(dumb_ptr<map_session_data> sd) * ステータス異常終了タイマー *------------------------------------------ */ -void skill_status_change_timer(TimerData *tid, tick_t tick, int id, StatusChange type) +void skill_status_change_timer(TimerData *tid, tick_t tick, BlockId id, StatusChange type) { dumb_ptr<block_list> bl; - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; //short *sc_count; //使ってない? - if ((bl = map_id2bl(id)) == NULL) + if ((bl = map_id2bl(id)) == nullptr) return; //該当IDがすでに消滅しているというのはいかにもありそうなのでスルーしてみる sc_data = battle_get_sc_data(bl); @@ -846,7 +851,7 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, int id, StatusChange { // Must report termination spell_effect_report_termination(sc_data[type].spell_invocation, bl->bl_id, type, 0); - sc_data[type].spell_invocation = 0; + sc_data[type].spell_invocation = BlockId(); } switch (type) @@ -878,7 +883,7 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, int id, StatusChange md->hp -= hp; } } - sc_data[type].timer = Timer(tick + std::chrono::seconds(1), + sc_data[type].timer = Timer(tick + 1_s, std::bind(skill_status_change_timer, ph::_1, ph::_2, bl->bl_id, type)); return; @@ -886,7 +891,7 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, int id, StatusChange } else { - sc_data[type].timer = Timer(tick + std::chrono::seconds(2), + sc_data[type].timer = Timer(tick + 2_s, std::bind(skill_status_change_timer, ph::_1, ph::_2, bl->bl_id, type)); return; @@ -898,7 +903,7 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, int id, StatusChange /* 時間切れ無し?? */ case StatusChange::SC_WEIGHT50: case StatusChange::SC_WEIGHT90: - sc_data[type].timer = Timer(tick + std::chrono::minutes(10), + sc_data[type].timer = Timer(tick + 10_min, std::bind(skill_status_change_timer, ph::_1, ph::_2, bl->bl_id, type)); return; @@ -920,14 +925,14 @@ int skill_status_change_start(dumb_ptr<block_list> bl, StatusChange type, int val1, interval_t tick) { - return skill_status_effect(bl, type, val1, tick, 0); + return skill_status_effect(bl, type, val1, tick, BlockId()); } int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type, int val1, - interval_t tick, int spell_invocation) + interval_t tick, BlockId spell_invocation) { - dumb_ptr<map_session_data> sd = NULL; + dumb_ptr<map_session_data> sd = nullptr; eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data; short *sc_count; Option *option; @@ -938,20 +943,20 @@ int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type, SP updateflag = SP::ZERO; int scdef = 0; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (not sc_data) return 0; sc_count = battle_get_sc_count(bl); - nullpo_ret(sc_count); + nullpo_retz(sc_count); option = battle_get_option(bl); - nullpo_ret(option); + nullpo_retz(option); opt1 = battle_get_opt1(bl); - nullpo_ret(opt1); + nullpo_retz(opt1); opt2 = battle_get_opt2(bl); - nullpo_ret(opt2); + nullpo_retz(opt2); opt3 = battle_get_opt3(bl); - nullpo_ret(opt3); + nullpo_retz(opt3); switch (type) { @@ -971,7 +976,7 @@ int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type, else { if (battle_config.error_log) - PRINTF("skill_status_change_start: neither MOB nor PC !\n"); + PRINTF("skill_status_change_start: neither MOB nor PC !\n"_fmt); return 0; } @@ -1024,12 +1029,12 @@ int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type, } // huh? - tick = std::chrono::seconds(1); + tick = 1_s; break; case StatusChange::SC_WEIGHT50: case StatusChange::SC_WEIGHT90: - tick = std::chrono::minutes(10); + tick = 10_min; break; case StatusChange::SC_HASTE: @@ -1045,7 +1050,7 @@ int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type, break; default: if (battle_config.error_log) - PRINTF("UnknownStatusChange [%d]\n", type); + PRINTF("UnknownStatusChange [%d]\n"_fmt, type); return 0; } @@ -1109,20 +1114,20 @@ int skill_status_change_clear(dumb_ptr<block_list> bl, int type) Opt2 *opt2; Opt3 *opt3; - nullpo_ret(bl); + nullpo_retz(bl); sc_data = battle_get_sc_data(bl); if (not sc_data) return 0; sc_count = battle_get_sc_count(bl); - nullpo_ret(sc_count); + nullpo_retz(sc_count); option = battle_get_option(bl); - nullpo_ret(option); + nullpo_retz(option); opt1 = battle_get_opt1(bl); - nullpo_ret(opt1); + nullpo_retz(opt1); opt2 = battle_get_opt2(bl); - nullpo_ret(opt2); + nullpo_retz(opt2); opt3 = battle_get_opt3(bl); - nullpo_ret(opt3); + nullpo_retz(opt3); if (*sc_count == 0) return 0; @@ -1175,22 +1180,22 @@ void skill_unit_timer_sub_ondelete(dumb_ptr<block_list> bl, static SP scan_stat(XString statname) { - if (statname == "str") + if (statname == "str"_s) return SP::STR; - if (statname == "dex") + if (statname == "dex"_s) return SP::DEX; - if (statname == "agi") + if (statname == "agi"_s) return SP::AGI; - if (statname == "vit") + if (statname == "vit"_s) return SP::VIT; - if (statname == "int") + if (statname == "int"_s) return SP::INT; - if (statname == "luk") + if (statname == "luk"_s) return SP::LUK; - if (statname == "none") + if (statname == "none"_s) return SP::ZERO; - FPRINTF(stderr, "Unknown stat `%s'\n", AString(statname)); + FPRINTF(stderr, "Unknown stat `%s'\n"_fmt, AString(statname)); return SP::ZERO; } @@ -1199,7 +1204,7 @@ bool skill_readdb(ZString filename) io::ReadFile in(filename); if (!in.is_open()) { - PRINTF("can't read %s\n", filename); + PRINTF("can't read %s\n"_fmt, filename); return false; } @@ -1209,7 +1214,7 @@ bool skill_readdb(ZString filename) { // is_comment only works for whole-line comments // that could change once the Z dependency is dropped ... - XString comment = "//"; + LString comment = "//"_s; XString line = line_.xislice_h(std::search(line_.begin(), line_.end(), comment.begin(), comment.end())).rstrip(); if (!line) continue; @@ -1245,15 +1250,15 @@ bool skill_readdb(ZString filename) rv = false; continue; } - if (/*i < SkillID() ||*/ i > SkillID::MAX_SKILL_DB) + if (/*i < SkillID() ||*/ i >= SkillID::MAX_SKILL_DB) { rv = false; continue; } - if (castcancel == "yes") + if (castcancel == "yes"_s) skdb.castcancel = true; - else if (castcancel == "no") + else if (castcancel == "no"_s) skdb.castcancel = false; else { @@ -1261,17 +1266,17 @@ bool skill_readdb(ZString filename) continue; } - if (flags == "passive") + if (flags == "passive"_s) { skill_pool_register(i); skdb.poolflags = SkillFlags::POOL_FLAG; } - else if (flags == "active") + else if (flags == "active"_s) { skill_pool_register(i); skdb.poolflags = SkillFlags::POOL_FLAG | SkillFlags::POOL_ACTIVE; } - else if (flags == "no") + else if (flags == "no"_s) skdb.poolflags = SkillFlags::ZERO; else { @@ -1290,7 +1295,7 @@ bool skill_readdb(ZString filename) skill_db[i] = skdb; skill_lookup_by_id(i).desc = RString(tmp); } - PRINTF("read %s done\n", filename); + PRINTF("read %s done\n"_fmt, filename); return rv; } @@ -1312,3 +1317,4 @@ skill_name_db& skill_lookup_by_name(XString name) return ner; return skill_names[num_names - 1]; } +} // namespace tmwa diff --git a/src/map/skill.hpp b/src/map/skill.hpp index 1a615c1..ec353ce 100644 --- a/src/map/skill.hpp +++ b/src/map/skill.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_SKILL_HPP -#define TMWA_MAP_SKILL_HPP +#pragma once // skill.hpp - Old-style skills. // // Copyright © ????-2004 Athena Dev Teams @@ -21,17 +20,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "skill.t.hpp" -# include "skill-pools.hpp" +#include "skill.t.hpp" +#include "skill-pools.hpp" -# include "../strings/fwd.hpp" -# include "../strings/rstring.hpp" -# include "../strings/astring.hpp" +#include "../strings/fwd.hpp" +#include "../strings/rstring.hpp" +#include "../strings/literal.hpp" -# include "map.hpp" +#include "../generic/fwd.hpp" +#include "../generic/array.hpp" +#include "map.hpp" + + +namespace tmwa +{ constexpr int MAX_SKILL_PRODUCE_DB = 150; constexpr int MAX_SKILL_ARROW_DB = 150; constexpr int MAX_SKILL_ABRA_DB = 350; @@ -61,11 +66,11 @@ earray<skill_db_, SkillID, SkillID::MAX_SKILL_DB> skill_db; struct skill_name_db { SkillID id; // skill id - RString name; // search strings + LString name; // search strings RString desc; // description that shows up for searches // this makes const char(&)[] not decay into const char * in {} - skill_name_db(SkillID i, RString n, RString d) + skill_name_db(SkillID i, LString n, LString d) : id(i), name(n), desc(d) {} }; @@ -76,9 +81,6 @@ extern struct skill_name_db skill_names[]; skill_name_db& skill_lookup_by_id(SkillID id); skill_name_db& skill_lookup_by_name(XString name); -struct block_list; -struct map_session_data; - bool skill_readdb(ZString filename); // スキルデータベースへのアクセサ @@ -110,7 +112,7 @@ int skill_castcancel(dumb_ptr<block_list> bl, int type); // ステータス異常 int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type, int val1, - interval_t tick, int spell_invocation); + interval_t tick, BlockId spell_invocation); int skill_status_change_start(dumb_ptr<block_list> bl, StatusChange type, int val1, interval_t tick); @@ -164,4 +166,4 @@ int skill_power_bl(dumb_ptr<block_list> bl, SkillID skill); // [Fate] Remember that a certain skill ID belongs to a pool skill void skill_pool_register(SkillID id); -#endif // TMWA_MAP_SKILL_HPP +} // namespace tmwa diff --git a/src/map/skill.t.hpp b/src/map/skill.t.hpp index 4e30cba..d0e3926 100644 --- a/src/map/skill.t.hpp +++ b/src/map/skill.t.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_SKILL_T_HPP -#define TMWA_MAP_SKILL_T_HPP +#pragma once // skill.t.hpp - Old-style skills. // // Copyright © ????-2004 Athena Dev Teams @@ -21,12 +20,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdint> +#include <cstdint> -# include "../generic/enum.hpp" +#include "../generic/enum.hpp" + +namespace tmwa +{ // TODO remove most of these as their corresponding SkillIDs get deleted. enum class StatusChange : uint16_t { @@ -131,5 +133,4 @@ enum class SkillFlags : uint16_t ENUM_BITWISE_OPERATORS(SkillFlags) } using e::SkillFlags; - -#endif // TMWA_MAP_SKILL_T_HPP +} // namespace tmwa diff --git a/src/map/storage.cpp b/src/map/storage.cpp index 89357b9..a6e6a0d 100644 --- a/src/map/storage.cpp +++ b/src/map/storage.cpp @@ -1,14 +1,32 @@ #include "storage.hpp" -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see COPYING in the main folder - -#include <cstdlib> -#include <cstring> +// storage.cpp - Storage handling. +// +// Copyright © ????-2004 Athena Dev Teams +// Copyright © 2004-2011 The Mana World Development Team +// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../compat/nullpo.hpp" #include "../generic/db.hpp" +#include "../mmo/ids.hpp" +#include "../mmo/mmo.hpp" + #include "chrif.hpp" #include "clif.hpp" #include "intif.hpp" @@ -18,18 +36,21 @@ #include "../poison.hpp" + +namespace tmwa +{ static -Map<int, struct storage> storage_db; +Map<AccountId, Storage> storage_db; void do_final_storage(void) { storage_db.clear(); } -struct storage *account2storage(int account_id) +Storage *account2storage(AccountId account_id) { - struct storage *stor = storage_db.search(account_id); - if (stor == NULL) + Storage *stor = storage_db.search(account_id); + if (stor == nullptr) { stor = storage_db.init(account_id); stor->account_id = account_id; @@ -38,13 +59,13 @@ struct storage *account2storage(int account_id) } // Just to ask storage, without creation -struct storage *account2storage2(int account_id) +Storage *account2storage2(AccountId account_id) { return storage_db.search(account_id); } static -void storage_delete(int account_id) +void storage_delete(AccountId account_id) { storage_db.erase(account_id); } @@ -55,13 +76,13 @@ void storage_delete(int account_id) */ int storage_storageopen(dumb_ptr<map_session_data> sd) { - nullpo_ret(sd); + nullpo_retz(sd); if (sd->state.storage_open) return 1; //Already open? - struct storage *stor = storage_db.search(sd->status_key.account_id); - if (stor == NULL) + Storage *stor = storage_db.search(sd->status_key.account_id); + if (stor == nullptr) { //Request storage. intif_request_storage(sd->status_key.account_id); return 1; @@ -83,20 +104,19 @@ int storage_storageopen(dumb_ptr<map_session_data> sd) *------------------------------------------ */ static -int storage_additem(dumb_ptr<map_session_data> sd, struct storage *stor, - struct item *item_data, int amount) +int storage_additem(dumb_ptr<map_session_data> sd, Storage *stor, + Item *item_data, int amount) { struct item_data *data; - int i; - if (item_data->nameid <= 0 || amount <= 0) + if (!item_data->nameid || amount <= 0) return 1; data = itemdb_search(item_data->nameid); if (!itemdb_isequip2(data)) { //Stackable - for (i = 0; i < MAX_STORAGE; i++) + for (SOff0 i : SOff0::iter()) { if (compare_item(&stor->storage_[i], item_data)) { @@ -110,9 +130,12 @@ int storage_additem(dumb_ptr<map_session_data> sd, struct storage *stor, } } //Add item - for (i = 0; i < MAX_STORAGE && stor->storage_[i].nameid; i++); - - if (i >= MAX_STORAGE) + SOff0 i = *std::find_if(SOff0::iter().begin(), SOff0::iter().end(), + [&stor](SOff0 i_) + { + return !stor->storage_[i_].nameid; + }); + if (!i.ok()) return 1; stor->storage_[i] = *item_data; @@ -129,17 +152,17 @@ int storage_additem(dumb_ptr<map_session_data> sd, struct storage *stor, *------------------------------------------ */ static -int storage_delitem(dumb_ptr<map_session_data> sd, struct storage *stor, - int n, int amount) +int storage_delitem(dumb_ptr<map_session_data> sd, Storage *stor, + SOff0 n, int amount) { - if (stor->storage_[n].nameid == 0 || stor->storage_[n].amount < amount) + if (!stor->storage_[n].nameid || stor->storage_[n].amount < amount) return 1; stor->storage_[n].amount -= amount; if (stor->storage_[n].amount == 0) { - stor->storage_[n] = item{}; + stor->storage_[n] = Item{}; stor->storage_amount--; clif_updatestorageamount(sd, stor); } @@ -153,21 +176,21 @@ int storage_delitem(dumb_ptr<map_session_data> sd, struct storage *stor, * Add an item to the storage from the inventory. *------------------------------------------ */ -int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount) +int storage_storageadd(dumb_ptr<map_session_data> sd, IOff0 index, int amount) { - struct storage *stor; + Storage *stor; - nullpo_ret(sd); + nullpo_retz(sd); stor = account2storage2(sd->status_key.account_id); - nullpo_ret(stor); + nullpo_retz(stor); if ((stor->storage_amount > MAX_STORAGE) || !stor->storage_status) return 0; // storage full / storage closed - if (index < 0 || index >= MAX_INVENTORY) + if (!index.ok()) return 0; - if (sd->status.inventory[index].nameid <= 0) + if (!sd->status.inventory[index].nameid) return 0; //No item on that spot if (amount < 1 || amount > sd->status.inventory[index].amount) @@ -188,19 +211,19 @@ int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount) * Retrieve an item from the storage. *------------------------------------------ */ -int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount) +int storage_storageget(dumb_ptr<map_session_data> sd, SOff0 index, int amount) { - struct storage *stor; + Storage *stor; PickupFail flag; - nullpo_ret(sd); + nullpo_retz(sd); stor = account2storage2(sd->status_key.account_id); - nullpo_ret(stor); + nullpo_retz(stor); - if (index < 0 || index >= MAX_STORAGE) + if (!index.ok()) return 0; - if (stor->storage_[index].nameid <= 0) + if (!stor->storage_[index].nameid) return 0; //Nothing there if (amount < 1 || amount > stor->storage_[index].amount) @@ -209,7 +232,7 @@ int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount) if ((flag = pc_additem(sd, &stor->storage_[index], amount)) == PickupFail::OKAY) storage_delitem(sd, stor, index, amount); else - clif_additem(sd, 0, 0, flag); + clif_additem(sd, IOff0::from(0), 0, flag); // log_fromstorage(sd, index, 0); return 1; } @@ -220,11 +243,11 @@ int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount) */ int storage_storageclose(dumb_ptr<map_session_data> sd) { - struct storage *stor; + Storage *stor; - nullpo_ret(sd); + nullpo_retz(sd); stor = account2storage2(sd->status_key.account_id); - nullpo_ret(stor); + nullpo_retz(stor); clif_storageclose(sd); if (stor->storage_status) @@ -252,9 +275,9 @@ int storage_storageclose(dumb_ptr<map_session_data> sd) */ int storage_storage_quit(dumb_ptr<map_session_data> sd) { - struct storage *stor; + Storage *stor; - nullpo_ret(sd); + nullpo_retz(sd); stor = account2storage2(sd->status_key.account_id); if (stor) @@ -267,9 +290,9 @@ int storage_storage_quit(dumb_ptr<map_session_data> sd) return 0; } -int storage_storage_save(int account_id, int final) +int storage_storage_save(AccountId account_id, int final) { - struct storage *stor; + Storage *stor; stor = account2storage2(account_id); if (!stor) @@ -295,9 +318,9 @@ int storage_storage_save(int account_id, int final) } //Ack from Char-server indicating the storage was saved. [Skotlex] -int storage_storage_saved(int account_id) +int storage_storage_saved(AccountId account_id) { - struct storage *stor = account2storage2(account_id); + Storage *stor = account2storage2(account_id); if (stor) { @@ -311,3 +334,4 @@ int storage_storage_saved(int account_id) } return 0; } +} // namespace tmwa diff --git a/src/map/storage.hpp b/src/map/storage.hpp index 702c908..f3875c8 100644 --- a/src/map/storage.hpp +++ b/src/map/storage.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_STORAGE_HPP -#define TMWA_MAP_STORAGE_HPP +#pragma once // storage.hpp - Storage handling. // // Copyright © ????-2004 Athena Dev Teams @@ -21,19 +20,25 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "map.hpp" +#include "../generic/fwd.hpp" +#include "../mmo/fwd.hpp" + +#include "clif.t.hpp" + + +namespace tmwa +{ int storage_storageopen(dumb_ptr<map_session_data> sd); -int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount); -int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount); +int storage_storageadd(dumb_ptr<map_session_data> sd, IOff0 index, int amount); +int storage_storageget(dumb_ptr<map_session_data> sd, SOff0 index, int amount); int storage_storageclose(dumb_ptr<map_session_data> sd); void do_final_storage(void); -struct storage *account2storage(int account_id); -struct storage *account2storage2(int account_id); +Storage *account2storage(AccountId account_id); +Storage *account2storage2(AccountId account_id); int storage_storage_quit(dumb_ptr<map_session_data> sd); -int storage_storage_save(int account_id, int final); -int storage_storage_saved(int account_id); - -#endif // TMWA_MAP_STORAGE_HPP +int storage_storage_save(AccountId account_id, int final); +int storage_storage_saved(AccountId account_id); +} // namespace tmwa diff --git a/src/map/tmw.cpp b/src/map/tmw.cpp index 46128d1..60b5027 100644 --- a/src/map/tmw.cpp +++ b/src/map/tmw.cpp @@ -19,17 +19,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <cctype> -#include <cstring> - #include "../compat/nullpo.hpp" #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" +#include "../strings/literal.hpp" #include "../io/cxxstdio.hpp" +#include "../mmo/human_time_diff.hpp" +#include "../mmo/utils.hpp" + #include "atcommand.hpp" #include "battle.hpp" #include "chrif.hpp" @@ -40,6 +41,9 @@ #include "../poison.hpp" + +namespace tmwa +{ static void tmw_AutoBan(dumb_ptr<map_session_data> sd, ZString reason, int length); static @@ -91,7 +95,7 @@ int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, XString message) { sd->chat_lines_in = sd->chat_total_repeats = 0; - tmw_AutoBan(sd, "chat", battle_config.chat_spam_ban); + tmw_AutoBan(sd, "chat"_s, battle_config.chat_spam_ban); return 1; } @@ -100,8 +104,8 @@ int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, XString message) (sd->chat_lines_in >= battle_config.chat_spam_warn || sd->chat_total_repeats >= battle_config.chat_spam_warn)) { - clif_displaymessage(sd->sess, "WARNING: You are about to be automatically banned for spam!"); - clif_displaymessage(sd->sess, "WARNING: Please slow down, do not repeat, and do not SHOUT!"); + clif_displaymessage(sd->sess, "WARNING: You are about to be automatically banned for spam!"_s); + clif_displaymessage(sd->sess, "WARNING: Please slow down, do not repeat, and do not SHOUT!"_s); } return 0; @@ -114,23 +118,23 @@ void tmw_AutoBan(dumb_ptr<map_session_data> sd, ZString reason, int length) sd->auto_ban_info.in_progress = 1; - AString hack_msg = STRPRINTF("[GM] %s has been autobanned for %s spam", + AString hack_msg = STRPRINTF("[GM] %s has been autobanned for %s spam"_fmt, sd->status_key.name, reason); tmw_GmHackMsg(hack_msg); - AString fake_command = STRPRINTF("@autoban %s %dh (%s spam)", + AString fake_command = STRPRINTF("@autoban %s %dh (%s spam)"_fmt, sd->status_key.name, length, reason); log_atcommand(sd, fake_command); - AString anotherbuf = STRPRINTF("You have been banned for %s spamming. Please do not spam.", + AString anotherbuf = STRPRINTF("You have been banned for %s spamming. Please do not spam."_fmt, reason); clif_displaymessage(sd->sess, anotherbuf); /* type: 2 - ban(year, month, day, hour, minute, second) */ HumanTimeDiff ban_len {}; ban_len.hour = length; - chrif_char_ask_name(-1, sd->status_key.name, 2, ban_len); + chrif_char_ask_name(AccountId(), sd->status_key.name, 2, ban_len); clif_setwaitclose(sd->sess); } @@ -159,6 +163,7 @@ bool tmw_CheckChatLameness(dumb_ptr<map_session_data>, XString message) void tmw_GmHackMsg(ZString line) { intif_wis_message_to_gm(wisp_server_name, - battle_config.hack_info_GM_level, + GmLevel::from(static_cast<uint32_t>(battle_config.hack_info_GM_level)), line); } +} // namespace tmwa diff --git a/src/map/tmw.hpp b/src/map/tmw.hpp index 670599e..ffd6f7f 100644 --- a/src/map/tmw.hpp +++ b/src/map/tmw.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_TMW_HPP -#define TMWA_MAP_TMW_HPP +#pragma once // tmw.hpp - Some random functions added by TMW. // // Copyright © 2004-2011 The Mana World Development Team @@ -20,15 +19,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" -# include "../mmo/dumb_ptr.hpp" +#include "../generic/fwd.hpp" -# include "map.hpp" +namespace tmwa +{ int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, XString message); void tmw_GmHackMsg(ZString line); - -#endif // TMWA_MAP_TMW_HPP +} // namespace tmwa diff --git a/src/map/trade.cpp b/src/map/trade.cpp index c877d00..c52377d 100644 --- a/src/map/trade.cpp +++ b/src/map/trade.cpp @@ -34,21 +34,24 @@ #include "../poison.hpp" + +namespace tmwa +{ /*========================================== * 取引要請を相手に送る *------------------------------------------ */ -void trade_traderequest(dumb_ptr<map_session_data> sd, int target_id) +void trade_traderequest(dumb_ptr<map_session_data> sd, BlockId target_id) { dumb_ptr<map_session_data> target_sd; nullpo_retv(sd); - if ((target_sd = map_id2sd(target_id)) != NULL) + if ((target_sd = map_id2sd(target_id)) != nullptr) { if (!battle_config.invite_request_check) { - if (target_sd->party_invite > 0) + if (target_sd->party_invite) { clif_tradestart(sd, 2); // 相手はPT要請中かGuild要請中 return; @@ -60,7 +63,7 @@ void trade_traderequest(dumb_ptr<map_session_data> sd, int target_id) clif_tradestart(sd, 2); return; } - if ((target_sd->trade_partner != 0) || (sd->trade_partner != 0)) + if ((target_sd->trade_partner) || (sd->trade_partner)) { trade_tradecancel(sd); //person is in another trade } @@ -97,20 +100,20 @@ void trade_tradeack(dumb_ptr<map_session_data> sd, int type) dumb_ptr<map_session_data> target_sd; nullpo_retv(sd); - if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) + if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr) { clif_tradestart(target_sd, type); clif_tradestart(sd, type); if (type == 4) { // Cancel sd->deal_locked = 0; - sd->trade_partner = 0; + sd->trade_partner = AccountId(); target_sd->deal_locked = 0; - target_sd->trade_partner = 0; + target_sd->trade_partner = AccountId(); } - if (sd->npc_id != 0) + if (sd->npc_id) npc_event_dequeue(sd); - if (target_sd->npc_id != 0) + if (target_sd->npc_id) npc_event_dequeue(target_sd); //close STORAGE window if it's open. It protects from spooffing packets [Lupus] @@ -123,7 +126,7 @@ void trade_tradeack(dumb_ptr<map_session_data> sd, int type) * アイテム追加 *------------------------------------------ */ -void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount) +void trade_tradeadditem(dumb_ptr<map_session_data> sd, IOff2 index, int amount) { dumb_ptr<map_session_data> target_sd; struct item_data *id; @@ -131,30 +134,29 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount) int trade_weight = 0; int free_ = 0; int c; - int i; nullpo_retv(sd); - if (((target_sd = map_id2sd(sd->trade_partner)) != NULL) + if (((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr) && (sd->deal_locked < 1)) { - if (index < 2 || index >= MAX_INVENTORY + 2) + if (!index.ok()) { - if (index == 0 && amount > 0 && amount <= sd->status.zeny) + if (index.index == 0 && amount > 0 && amount <= sd->status.zeny) { sd->deal_zeny = amount; - clif_tradeadditem(sd, target_sd, 0, amount); + clif_tradeadditem(sd, target_sd, index, amount); } } // note: amount is overridden below! - else if (amount <= sd->status.inventory[index - 2].amount + else if (amount <= sd->status.inventory[index.unshift()].amount && amount > 0) { // determine free slots of receiver - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { - if (target_sd->status.inventory[i].nameid == 0 - && target_sd->inventory_data[i] == NULL) + if (!target_sd->status.inventory[i].nameid + && target_sd->inventory_data[i] == nullptr) free_++; } for (trade_i = 0; trade_i < TRADE_MAX; trade_i++) @@ -163,14 +165,14 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount) { // calculate trade weight trade_weight += - sd->inventory_data[index - 2]->weight * amount; + sd->inventory_data[index.unshift()]->weight * amount; // determine if item is a stackable already in receivers inventory, and up free count - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (target_sd->status.inventory[i].nameid == - sd->status.inventory[index - 2].nameid - && target_sd->inventory_data[i] != NULL) + sd->status.inventory[index.unshift()].nameid + && target_sd->inventory_data[i] != nullptr) { id = target_sd->inventory_data[i]; if (id->type != ItemType::WEAPON @@ -205,7 +207,7 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount) return; } } - pc_unequipinvyitem(sd, index - 2, CalcStatus::NOW); + pc_unequipinvyitem(sd, index.unshift(), CalcStatus::NOW); sd->deal_item_index[trade_i] = index; sd->deal_item_amount[trade_i] += amount; clif_tradeitemok(sd, index, amount, 0); //success to add item @@ -217,16 +219,16 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount) { // calculate weight for stored deal trade_weight += - sd->inventory_data[sd->deal_item_index[trade_i] - - 2]->weight * + sd->inventory_data[sd->deal_item_index[trade_i].unshift() + ]->weight * sd->deal_item_amount[trade_i]; // count free stackables in stored deal - for (i = 0; i < MAX_INVENTORY; i++) + for (IOff0 i : IOff0::iter()) { if (target_sd->status.inventory[i].nameid == sd->status. - inventory[sd->deal_item_index[trade_i] - 2].nameid - && target_sd->inventory_data[i] != NULL) + inventory[sd->deal_item_index[trade_i].unshift()].nameid + && target_sd->inventory_data[i] != nullptr) { id = target_sd->inventory_data[i]; if (id->type != ItemType::WEAPON @@ -260,11 +262,11 @@ void trade_tradeok(dumb_ptr<map_session_data> sd) for (trade_i = 0; trade_i < TRADE_MAX; trade_i++) { - int index = sd->deal_item_index[trade_i]; - if (index < 2 || index >= MAX_INVENTORY + 2) + IOff2 index = sd->deal_item_index[trade_i]; + if (!index.ok()) continue; if (sd->deal_item_amount[trade_i] > - sd->status.inventory[index - 2].amount + sd->status.inventory[index.unshift()].amount || sd->deal_item_amount[trade_i] < 0) { trade_tradecancel(sd); @@ -273,10 +275,10 @@ void trade_tradeok(dumb_ptr<map_session_data> sd) } - if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) + if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr) { sd->deal_locked = 1; - clif_tradeitemok(sd, 0, 0, 0); + clif_tradeitemok(sd, IOff2::from(0), 0, 0); clif_tradedeal_lock(sd, 0); clif_tradedeal_lock(target_sd, 1); } @@ -293,26 +295,28 @@ void trade_tradecancel(dumb_ptr<map_session_data> sd) nullpo_retv(sd); - if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) + if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr) { for (trade_i = 0; trade_i < TRADE_MAX; trade_i++) { //give items back (only virtual) if (sd->deal_item_amount[trade_i] != 0) { + assert (sd->deal_item_index[trade_i].ok()); clif_additem(sd, - sd->deal_item_index[trade_i] - 2, + sd->deal_item_index[trade_i].unshift(), sd->deal_item_amount[trade_i], PickupFail::OKAY); - sd->deal_item_index[trade_i] = 0; + sd->deal_item_index[trade_i] = IOff2::from(0); sd->deal_item_amount[trade_i] = 0; } if (target_sd->deal_item_amount[trade_i] != 0) { + assert (target_sd->deal_item_index[trade_i].ok()); clif_additem(target_sd, - target_sd->deal_item_index[trade_i] - 2, + target_sd->deal_item_index[trade_i].unshift(), target_sd->deal_item_amount[trade_i], PickupFail::OKAY); - target_sd->deal_item_index[trade_i] = 0; + target_sd->deal_item_index[trade_i] = IOff2::from(0); target_sd->deal_item_amount[trade_i] = 0; } } @@ -327,9 +331,9 @@ void trade_tradecancel(dumb_ptr<map_session_data> sd) target_sd->deal_zeny = 0; } sd->deal_locked = 0; - sd->trade_partner = 0; + sd->trade_partner = AccountId(); target_sd->deal_locked = 0; - target_sd->trade_partner = 0; + target_sd->trade_partner = AccountId(); clif_tradecancelled(sd); clif_tradecancelled(target_sd); } @@ -346,11 +350,11 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd) nullpo_retv(sd); - if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) + if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr) { - MAP_LOG_PC(sd, " TRADECOMMIT WITH %d GIVE %d GET %d", - target_sd->status_key.char_id, sd->deal_zeny, - target_sd->deal_zeny); + MAP_LOG_PC(sd, " TRADECOMMIT WITH %d GIVE %d GET %d"_fmt, + target_sd->status_key.char_id, sd->deal_zeny, + target_sd->deal_zeny); if ((sd->deal_locked >= 1) && (target_sd->deal_locked >= 1)) { // both have pressed 'ok' if (sd->deal_locked < 2) @@ -363,23 +367,24 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd) { sd->deal_zeny = 0; trade_tradecancel(sd); - MAP_LOG_PC(sd, " TRADECANCEL"); + MAP_LOG_PC(sd, " TRADECANCEL"_fmt); return; } if (target_sd->deal_zeny > target_sd->status.zeny) { target_sd->deal_zeny = 0; trade_tradecancel(sd); - MAP_LOG_PC(sd, " TRADECANCEL"); + MAP_LOG_PC(sd, " TRADECANCEL"_fmt); return; } - sd->trade_partner = 0; - target_sd->trade_partner = 0; + sd->trade_partner = AccountId(); + target_sd->trade_partner = AccountId(); for (trade_i = 0; trade_i < TRADE_MAX; trade_i++) { if (sd->deal_item_amount[trade_i] != 0) { - int n = sd->deal_item_index[trade_i] - 2; + assert (sd->deal_item_index[trade_i].ok()); + IOff0 n = sd->deal_item_index[trade_i].unshift(); PickupFail flag = pc_additem(target_sd, &sd->status.inventory[n], sd->deal_item_amount[trade_i]); @@ -390,12 +395,13 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd) clif_additem(sd, n, sd->deal_item_amount[trade_i], PickupFail::OKAY); - sd->deal_item_index[trade_i] = 0; + sd->deal_item_index[trade_i] = IOff2::from(0); sd->deal_item_amount[trade_i] = 0; } if (target_sd->deal_item_amount[trade_i] != 0) { - int n = target_sd->deal_item_index[trade_i] - 2; + assert (target_sd->deal_item_index[trade_i].ok()); + IOff0 n = target_sd->deal_item_index[trade_i].unshift(); PickupFail flag = pc_additem(sd, &target_sd->status.inventory[n], target_sd->deal_item_amount[trade_i]); @@ -405,10 +411,9 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd) 1); else clif_additem(target_sd, n, - target_sd->deal_item_amount[trade_i], PickupFail::OKAY); - target_sd->deal_item_index[trade_i] = 0; + target_sd->deal_item_index[trade_i] = IOff2::from(0); target_sd->deal_item_amount[trade_i] = 0; } } @@ -434,7 +439,7 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd) target_sd->deal_locked = 0; clif_tradecompleted(sd, 0); clif_tradecompleted(target_sd, 0); - MAP_LOG_PC(sd, " TRADEOK"); + MAP_LOG_PC(sd, " TRADEOK"_fmt); } } } @@ -449,14 +454,15 @@ void trade_verifyzeny(dumb_ptr<map_session_data> sd) nullpo_retv(sd); - if ((target_sd = map_id2sd(sd->trade_partner)) != NULL) + if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr) { if (sd->deal_zeny > sd->status.zeny) { if (sd->deal_locked < 1) - trade_tradeadditem(sd, 0, sd->status.zeny); // Fix money ammount + trade_tradeadditem(sd, IOff2::from(0), sd->status.zeny); // Fix money ammount else trade_tradecancel(sd); // Or cancel the trade if we can't fix it } } } +} // namespace tmwa diff --git a/src/map/trade.hpp b/src/map/trade.hpp index dc81c54..91ed954 100644 --- a/src/map/trade.hpp +++ b/src/map/trade.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MAP_TRADE_HPP -#define TMWA_MAP_TRADE_HPP +#pragma once // trade.hpp - Inter-player item and money transactions. // // Copyright © ????-2004 Athena Dev Teams @@ -21,16 +20,20 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "map.hpp" +#include "../generic/fwd.hpp" -void trade_traderequest(dumb_ptr<map_session_data> sd, int target_id); +#include "clif.t.hpp" + + +namespace tmwa +{ +void trade_traderequest(dumb_ptr<map_session_data> sd, BlockId target_id); void trade_tradeack(dumb_ptr<map_session_data> sd, int type); -void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount); +void trade_tradeadditem(dumb_ptr<map_session_data> sd, IOff2 index, int amount); void trade_tradeok(dumb_ptr<map_session_data> sd); void trade_tradecancel(dumb_ptr<map_session_data> sd); void trade_tradecommit(dumb_ptr<map_session_data> sd); void trade_verifyzeny(dumb_ptr<map_session_data> sd); - -#endif // TMWA_MAP_TRADE_HPP +} // namespace tmwa diff --git a/src/mmo/config_parse.cpp b/src/mmo/config_parse.cpp index b954e8b..8362810 100644 --- a/src/mmo/config_parse.cpp +++ b/src/mmo/config_parse.cpp @@ -18,6 +18,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include <algorithm> + #include "../strings/xstring.hpp" #include "../strings/zstring.hpp" @@ -28,9 +30,12 @@ #include "../poison.hpp" + +namespace tmwa +{ bool is_comment(XString line) { - return not line or line.startswith("//"); + return not line or line.startswith("//"_s); } template<class ZS> @@ -72,7 +77,7 @@ bool load_config_file(ZString filename, ConfigItemParser slave) io::LineReader in(filename); if (!in.is_open()) { - PRINTF("Unable to open file: %s\n", filename); + PRINTF("Unable to open file: %s\n"_fmt, filename); return false; } io::Line line; @@ -85,16 +90,16 @@ bool load_config_file(ZString filename, ConfigItemParser slave) ZString value; if (!config_split(line.text, &key, &value)) { - line.error("Bad config line"); + line.error("Bad config line"_s); rv = false; continue; } - if (key == "import") + if (key == "import"_s) { rv &= load_config_file(value, slave); continue; } - else if (key == "version-lt") + else if (key == "version-lt"_s) { Version vers; if (!extract(value, &vers)) @@ -106,7 +111,7 @@ bool load_config_file(ZString filename, ConfigItemParser slave) continue; break; } - else if (key == "version-le") + else if (key == "version-le"_s) { Version vers; if (!extract(value, &vers)) @@ -118,7 +123,7 @@ bool load_config_file(ZString filename, ConfigItemParser slave) continue; break; } - else if (key == "version-gt") + else if (key == "version-gt"_s) { Version vers; if (!extract(value, &vers)) @@ -130,7 +135,7 @@ bool load_config_file(ZString filename, ConfigItemParser slave) continue; break; } - else if (key == "version-ge") + else if (key == "version-ge"_s) { Version vers; if (!extract(value, &vers)) @@ -144,7 +149,7 @@ bool load_config_file(ZString filename, ConfigItemParser slave) } else if (!slave(key, value)) { - line.error("Bad config key or value"); + line.error("Bad config key or value"_s); rv = false; continue; } @@ -152,3 +157,4 @@ bool load_config_file(ZString filename, ConfigItemParser slave) } return rv; } +} // namespace tmwa diff --git a/src/mmo/config_parse.hpp b/src/mmo/config_parse.hpp index dd1b79e..50a115e 100644 --- a/src/mmo/config_parse.hpp +++ b/src/mmo/config_parse.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MMO_CONFIG_PARSE_HPP -#define TMWA_MMO_CONFIG_PARSE_HPP +#pragma once // config_parse.hpp - Framework for per-server config parsers. // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,10 +18,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" + +namespace tmwa +{ typedef bool (*ConfigItemParser)(XString key, ZString value); bool is_comment(XString line); @@ -32,5 +34,4 @@ bool config_split(XString line, XString *key, XString *value); /// Master config parser. This handles 'import' and 'version-ge' etc. /// Then it defers to the inferior parser for a line it does not understand. bool load_config_file(ZString filename, ConfigItemParser slave); - -#endif // TMWA_MMO_CONFIG_PARSE_HPP +} // namespace tmwa diff --git a/src/mmo/consts.cpp b/src/mmo/consts.cpp new file mode 100644 index 0000000..e49cdf5 --- /dev/null +++ b/src/mmo/consts.cpp @@ -0,0 +1,26 @@ +#include "consts.hpp" +// consts.cpp - empty mess of constants +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/mmo/consts.hpp b/src/mmo/consts.hpp new file mode 100644 index 0000000..c1a7eb6 --- /dev/null +++ b/src/mmo/consts.hpp @@ -0,0 +1,66 @@ +#pragma once +// consts.hpp - Huge mess of constants. +// +// Copyright © ????-2004 Athena Dev Teams +// Copyright © 2004-2011 The Mana World Development Team +// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include "../net/timer.t.hpp" + +#include "ids.hpp" +#include "strs.hpp" + + +namespace tmwa +{ +constexpr int FIFOSIZE_SERVERLINK = 256 * 1024; + +constexpr int MAX_MAP_PER_SERVER = 512; +constexpr int MAX_INVENTORY = 100; +constexpr int MAX_AMOUNT = 30000; +constexpr int MAX_ZENY = 1000000000; // 1G zeny +constexpr int TRADE_MAX = 10; + +constexpr int GLOBAL_REG_NUM = 96; +constexpr size_t ACCOUNT_REG_NUM = 16; +constexpr size_t ACCOUNT_REG2_NUM = 16; +constexpr interval_t DEFAULT_WALK_SPEED = 150_ms; +constexpr interval_t MIN_WALK_SPEED = interval_t::zero(); +constexpr interval_t MAX_WALK_SPEED = 1_s; +constexpr int MAX_STORAGE = 300; +constexpr int MAX_PARTY = 12; + +#define MIN_HAIR_STYLE battle_config.min_hair_style +#define MAX_HAIR_STYLE battle_config.max_hair_style +#define MIN_HAIR_COLOR battle_config.min_hair_color +#define MAX_HAIR_COLOR battle_config.max_hair_color +#define MIN_CLOTH_COLOR battle_config.min_cloth_color +#define MAX_CLOTH_COLOR battle_config.max_cloth_color + +// WTF is this doing here? +struct PartyMember +{ + AccountId account_id; + CharName name; + MapName map; + int leader, online, lv; + struct map_session_data *sd; +}; +} // namespace tmwa diff --git a/src/mmo/core.cpp b/src/mmo/core.cpp index 68b7823..f1a8d07 100644 --- a/src/mmo/core.cpp +++ b/src/mmo/core.cpp @@ -22,23 +22,26 @@ #include <sys/wait.h> -#include <unistd.h> +#include <alloca.h> #include <csignal> #include <cstdlib> -#include <ctime> -#include "../strings/zstring.hpp" +#include <tmwa/shared.hpp> -#include "../generic/random.hpp" +#include "../strings/zstring.hpp" +#include "../strings/literal.hpp" #include "../io/cxxstdio.hpp" -#include "socket.hpp" -#include "timer.hpp" +#include "../net/socket.hpp" +#include "../net/timer.hpp" #include "../poison.hpp" + +namespace tmwa +{ // Added by Gabuzomeu // // This is an implementation of signal() using sigaction() for portability. @@ -61,10 +64,12 @@ sigfunc compat_signal(int signo, sigfunc func) sact.sa_flags = 0; if (sigaction(signo, &sact, &oact) < 0) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" + { + DIAG_PUSH(); + DIAG_I(old_style_cast); return SIG_ERR; -#pragma GCC diagnostic pop + DIAG_POP(); + } return oact.sa_handler; } @@ -75,16 +80,18 @@ bool runflag = true; static void chld_proc(int) { - wait(NULL); + wait(nullptr); } static void sig_proc(int) { for (int i = 1; i < 31; ++i) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" + { + DIAG_PUSH(); + DIAG_I(old_style_cast); compat_signal(i, SIG_IGN); -#pragma GCC diagnostic pop + DIAG_POP(); + } runflag = false; } @@ -97,8 +104,14 @@ void sig_proc(int) Unless you use SA_SIGINFO and *carefully* check the origin, that means they must be SIG_DFL. */ +} // namespace tmwa + int main(int argc, char **argv) { + using namespace tmwa; + + check_paths(); + // ZString args[argc]; is (deliberately!) not supported by clang yet ZString *args = static_cast<ZString *>(alloca(argc * sizeof(ZString))); for (int i = 0; i < argc; ++i) @@ -107,29 +120,30 @@ int main(int argc, char **argv) if (!runflag) { - PRINTF("Fatal error during startup; exiting\n"); + PRINTF("Fatal error during startup; exiting\n"_fmt); return 1; } // set up exit handlers *after* the initialization has happened. // This is because term_func is likely to depend on successful init. -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" + DIAG_PUSH(); + DIAG_I(old_style_cast); compat_signal(SIGPIPE, SIG_IGN); -#pragma GCC diagnostic pop + DIAG_POP(); compat_signal(SIGTERM, sig_proc); compat_signal(SIGINT, sig_proc); compat_signal(SIGCHLD, chld_proc); // Signal to create coredumps by system when necessary (crash) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" + DIAG_PUSH(); + DIAG_I(old_style_cast); + DIAG_I(zero_as_null_pointer_constant); compat_signal(SIGSEGV, SIG_DFL); compat_signal(SIGBUS, SIG_DFL); compat_signal(SIGTRAP, SIG_DFL); compat_signal(SIGILL, SIG_DFL); compat_signal(SIGFPE, SIG_DFL); -#pragma GCC diagnostic pop + DIAG_POP(); atexit(term_func); diff --git a/src/mmo/core.hpp b/src/mmo/core.hpp index 5699045..5b2dbbb 100644 --- a/src/mmo/core.hpp +++ b/src/mmo/core.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MMO_CORE_HPP -#define TMWA_MMO_CORE_HPP +#pragma once // core.hpp - The main loop. // // Copyright © ????-2004 Athena Dev Teams @@ -21,12 +20,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../range/slice.hpp" +#include "../range/slice.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" + +namespace tmwa +{ /// core.c contains a server-independent main() function /// and then runs a do_sendrecv loop @@ -40,5 +42,4 @@ extern int do_init(Slice<ZString>); /// Cleanup function called whenever a signal kills us /// or when if we manage to exit() gracefully. extern void term_func(void); - -#endif // TMWA_MMO_CORE_HPP +} // namespace tmwa diff --git a/src/mmo/enums.cpp b/src/mmo/enums.cpp new file mode 100644 index 0000000..d05be91 --- /dev/null +++ b/src/mmo/enums.cpp @@ -0,0 +1,26 @@ +#include "enums.hpp" +// enums.cpp - Common enumerated types +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/mmo/enums.hpp b/src/mmo/enums.hpp new file mode 100644 index 0000000..bf8a75c --- /dev/null +++ b/src/mmo/enums.hpp @@ -0,0 +1,162 @@ +#pragma once +// enums.hpp - Common enumerated types +// +// Copyright © ????-2004 Athena Dev Teams +// Copyright © 2004-2011 The Mana World Development Team +// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include <cstdint> + +#include "../generic/enum.hpp" + + +namespace tmwa +{ +enum class SkillID : uint16_t; +constexpr SkillID MAX_SKILL = SkillID(474); // not 450 +constexpr SkillID get_enum_min_value(SkillID) { return SkillID(); } +constexpr SkillID get_enum_max_value(SkillID) { return MAX_SKILL; } + +namespace e +{ +enum class EPOS : uint16_t +{ + ZERO = 0x0000, + + LEGS = 0x0001, + WEAPON = 0x0002, + GLOVES = 0x0004, + CAPE = 0x0008, + MISC1 = 0x0010, + SHIELD = 0x0020, + SHOES = 0x0040, + MISC2 = 0x0080, + HAT = 0x0100, + TORSO = 0x0200, + + ARROW = 0x8000, +}; +ENUM_BITWISE_OPERATORS(EPOS) + +constexpr EPOS get_enum_min_value(EPOS) { return EPOS(0x0000); } +constexpr EPOS get_enum_max_value(EPOS) { return EPOS(0xffff); } +} +using e::EPOS; + +namespace e +{ +enum class SkillFlags : uint16_t; +} +using e::SkillFlags; + +// Option and Opt1..3 in map.hpp +namespace e +{ +enum class Option : uint16_t; +constexpr Option get_enum_min_value(Option) { return Option(0x0000); } +constexpr Option get_enum_max_value(Option) { return Option(0xffff); } +} +using e::Option; + +enum class ATTR +{ + STR = 0, + AGI = 1, + VIT = 2, + INT = 3, + DEX = 4, + LUK = 5, + + COUNT = 6, +}; + +constexpr ATTR ATTRs[6] = +{ + ATTR::STR, + ATTR::AGI, + ATTR::VIT, + ATTR::INT, + ATTR::DEX, + ATTR::LUK, +}; + +enum class ItemLook : uint16_t +{ + NONE = 0, + BLADE = 1, // or some other common weapons + _2, + SETZER_AND_SCYTHE = 3, + _6, + STAFF = 10, + BOW = 11, + _13 = 13, + _14 = 14, + _16 = 16, + SINGLE_HANDED_COUNT = 17, + + DUAL_BLADE = 0x11, + DUAL_2 = 0x12, + DUAL_6 = 0x13, + DUAL_12 = 0x14, + DUAL_16 = 0x15, + DUAL_26 = 0x16, +}; + +enum class SEX : uint8_t +{ + FEMALE = 0, + MALE = 1, + // For items. This is also used as error, sometime. + NEUTRAL = 2, +}; +inline +char sex_to_char(SEX sex) +{ + switch (sex) + { + case SEX::FEMALE: return 'F'; + case SEX::MALE: return 'M'; + default: return '\0'; + } +} +inline +SEX sex_from_char(char c) +{ + switch (c) + { + case 'F': return SEX::FEMALE; + case 'M': return SEX::MALE; + default: return SEX::NEUTRAL; + } +} + +inline +bool native_to_network(char *network, SEX native) +{ + *network = sex_to_char(native); + return true; +} +inline +bool network_to_native(SEX *native, char network) +{ + *native = sex_from_char(network); + return true; +} +} // namespace tmwa diff --git a/src/mmo/extract.cpp b/src/mmo/extract.cpp index 378986d..d486ed5 100644 --- a/src/mmo/extract.cpp +++ b/src/mmo/extract.cpp @@ -18,12 +18,19 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include <algorithm> + #include "../strings/astring.hpp" #include "../strings/xstring.hpp" #include "../strings/vstring.hpp" +#include "mmo.hpp" + #include "../poison.hpp" + +namespace tmwa +{ bool extract(XString str, XString *rv) { *rv = str; @@ -36,20 +43,21 @@ bool extract(XString str, AString *rv) return true; } -bool extract(XString str, struct global_reg *var) +bool extract(XString str, GlobalReg *var) { return extract(str, record<','>(&var->str, &var->value)); } -bool extract(XString str, struct item *it) +bool extract(XString str, Item *it) { XString ignored; - return extract(str, + XString corruption_hack_amount; + bool rv = extract(str, record<',', 11>( - &it->id, + &ignored, &it->nameid, - &it->amount, + &corruption_hack_amount, &it->equip, &ignored, &ignored, @@ -59,4 +67,34 @@ bool extract(XString str, struct item *it) &ignored, &ignored, &ignored)); + if (rv) + { + if (corruption_hack_amount == "-1"_s) + it->amount = 0; + else + rv = extract(corruption_hack_amount, &it->amount); + } + return rv; +} + +bool extract(XString str, MapName *m) +{ + XString::iterator it = std::find(str.begin(), str.end(), '.'); + str = str.xislice_h(it); + VString<15> tmp; + bool rv = extract(str, &tmp); + *m = tmp; + return rv; +} + +bool extract(XString str, CharName *out) +{ + VString<23> tmp; + if (extract(str, &tmp)) + { + *out = CharName(tmp); + return true; + } + return false; } +} // namespace tmwa diff --git a/src/mmo/extract.hpp b/src/mmo/extract.hpp index 622281b..355e2da 100644 --- a/src/mmo/extract.hpp +++ b/src/mmo/extract.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MMO_EXTRACT_HPP -#define TMWA_MMO_EXTRACT_HPP +#pragma once // extract.hpp - a simple, hierarchical, tokenizer // // Copyright © 2012-2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,14 +18,27 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <algorithm> +#include <cerrno> +#include <cstdlib> -# include "../strings/xstring.hpp" +#include <algorithm> +#include <vector> -# include "mmo.hpp" -# include "utils.hpp" +#include "../ints/wrap.hpp" + +#include "../strings/xstring.hpp" + +#include "../generic/enum.hpp" + +#include "utils.hpp" + + +namespace tmwa +{ +template<class T> +bool do_extract(XString str, T t); template<class T, typename=typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, char>::value && !std::is_same<T, bool>::value>::type> bool extract(XString str, T *iv) @@ -94,6 +106,12 @@ bool extract(XString str, VString<N> *out) return true; } +inline +bool extract(XString str, LString exact) +{ + return str == exact; +} + template<class T> class LStripper { @@ -192,31 +210,23 @@ bool extract(XString str, VRecord<split, T> rec) && extract(str.xislice_t(s + 1), rec); } -bool extract(XString str, struct global_reg *var); +bool extract(XString str, GlobalReg *var); -bool extract(XString str, struct item *it); +bool extract(XString str, Item *it); -inline -bool extract(XString str, MapName *m) -{ - XString::iterator it = std::find(str.begin(), str.end(), '.'); - str = str.xislice_h(it); - VString<15> tmp; - bool rv = extract(str, &tmp); - *m = tmp; - return rv; -} +bool extract(XString str, MapName *m); -inline -bool extract(XString str, CharName *out) +bool extract(XString str, CharName *out); + +template<class T> +bool do_extract(XString str, T t) { - VString<23> tmp; - if (extract(str, &tmp)) - { - *out = CharName(tmp); - return true; - } - return false; + return extract(str, t); } -#endif // TMWA_MMO_EXTRACT_HPP +template<class R> +bool extract(XString str, Wrapped<R> *w) +{ + return extract(str, &w->_value); +} +} // namespace tmwa diff --git a/src/mmo/extract_test.cpp b/src/mmo/extract_test.cpp index 60ab49e..e6dc7b2 100644 --- a/src/mmo/extract_test.cpp +++ b/src/mmo/extract_test.cpp @@ -22,160 +22,165 @@ #include "../strings/xstring.hpp" +#include "mmo.hpp" + #include "../poison.hpp" + +namespace tmwa +{ TEST(extract, record_int) { int x, y, z; x = y = z = 0; - EXPECT_FALSE(extract("1 2 3 4 ", record<' '>(&x, &y, &z))); + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' '>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_FALSE(extract("1 2 3 4", record<' '>(&x, &y, &z))); + EXPECT_FALSE(extract("1 2 3 4"_s, record<' '>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_TRUE(extract("1 2 3 ", record<' '>(&x, &y, &z))); + EXPECT_TRUE(extract("1 2 3 "_s, record<' '>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_TRUE(extract("1 2 3", record<' '>(&x, &y, &z))); + EXPECT_TRUE(extract("1 2 3"_s, record<' '>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_FALSE(extract("1 2 ", record<' '>(&x, &y, &z))); + EXPECT_FALSE(extract("1 2 "_s, record<' '>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract("1 2", record<' '>(&x, &y, &z))); + EXPECT_FALSE(extract("1 2"_s, record<' '>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract("1 ", record<' '>(&x, &y, &z))); + EXPECT_FALSE(extract("1 "_s, record<' '>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract("1", record<' '>(&x, &y, &z))); + EXPECT_FALSE(extract("1"_s, record<' '>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract(" ", record<' '>(&x, &y, &z))); + EXPECT_FALSE(extract(" "_s, record<' '>(&x, &y, &z))); EXPECT_EQ(0, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract("", record<' '>(&x, &y, &z))); + EXPECT_FALSE(extract(""_s, record<' '>(&x, &y, &z))); EXPECT_EQ(0, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract("1 2 3 4 ", record<' ', 2>(&x, &y, &z))); + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' ', 2>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_FALSE(extract("1 2 3 4", record<' ', 2>(&x, &y, &z))); + EXPECT_FALSE(extract("1 2 3 4"_s, record<' ', 2>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_TRUE(extract("1 2 3 ", record<' ', 2>(&x, &y, &z))); + EXPECT_TRUE(extract("1 2 3 "_s, record<' ', 2>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_TRUE(extract("1 2 3", record<' ', 2>(&x, &y, &z))); + EXPECT_TRUE(extract("1 2 3"_s, record<' ', 2>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_TRUE(extract("1 2 ", record<' ', 2>(&x, &y, &z))); + EXPECT_TRUE(extract("1 2 "_s, record<' ', 2>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_TRUE(extract("1 2", record<' ', 2>(&x, &y, &z))); + EXPECT_TRUE(extract("1 2"_s, record<' ', 2>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract("1 ", record<' ', 2>(&x, &y, &z))); + EXPECT_FALSE(extract("1 "_s, record<' ', 2>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract("1", record<' ', 2>(&x, &y, &z))); + EXPECT_FALSE(extract("1"_s, record<' ', 2>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract(" ", record<' ', 2>(&x, &y, &z))); + EXPECT_FALSE(extract(" "_s, record<' ', 2>(&x, &y, &z))); EXPECT_EQ(0, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract("", record<' ', 2>(&x, &y, &z))); + EXPECT_FALSE(extract(""_s, record<' ', 2>(&x, &y, &z))); EXPECT_EQ(0, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract("1 2 3 4 ", record<' ', 1>(&x, &y, &z))); + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' ', 1>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_FALSE(extract("1 2 3 4", record<' ', 1>(&x, &y, &z))); + EXPECT_FALSE(extract("1 2 3 4"_s, record<' ', 1>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_TRUE(extract("1 2 3 ", record<' ', 1>(&x, &y, &z))); + EXPECT_TRUE(extract("1 2 3 "_s, record<' ', 1>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_TRUE(extract("1 2 3", record<' ', 1>(&x, &y, &z))); + EXPECT_TRUE(extract("1 2 3"_s, record<' ', 1>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(3, z); x = y = z = 0; - EXPECT_TRUE(extract("1 2 ", record<' ', 1>(&x, &y, &z))); + EXPECT_TRUE(extract("1 2 "_s, record<' ', 1>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_TRUE(extract("1 2", record<' ', 1>(&x, &y, &z))); + EXPECT_TRUE(extract("1 2"_s, record<' ', 1>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(2, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_TRUE(extract("1 ", record<' ', 1>(&x, &y, &z))); + EXPECT_TRUE(extract("1 "_s, record<' ', 1>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_TRUE(extract("1", record<' ', 1>(&x, &y, &z))); + EXPECT_TRUE(extract("1"_s, record<' ', 1>(&x, &y, &z))); EXPECT_EQ(1, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract(" ", record<' ', 1>(&x, &y, &z))); + EXPECT_FALSE(extract(" "_s, record<' ', 1>(&x, &y, &z))); EXPECT_EQ(0, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); x = y = z = 0; - EXPECT_FALSE(extract("", record<' ', 1>(&x, &y, &z))); + EXPECT_FALSE(extract(""_s, record<' ', 1>(&x, &y, &z))); EXPECT_EQ(0, x); EXPECT_EQ(0, y); EXPECT_EQ(0, z); @@ -185,170 +190,171 @@ TEST(extract, record_int) TEST(extract, record_str) { XString x, y, z; - x = y = z = ""; - EXPECT_FALSE(extract("1 2 3 4 ", record<' '>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_FALSE(extract("1 2 3 4", record<' '>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 2 3 ", record<' '>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 2 3", record<' '>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 2 ", record<' '>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_FALSE(extract("1 2", record<' '>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_FALSE(extract("1 ", record<' '>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_FALSE(extract("1", record<' '>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_FALSE(extract(" ", record<' '>(&x, &y, &z))); - EXPECT_EQ("", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_FALSE(extract("", record<' '>(&x, &y, &z))); - EXPECT_EQ("", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; + x = y = z = ""_s; + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1 2 3 4"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1 2"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1 "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1"_s, record<' '>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract(" "_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract(""_s, record<' '>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; - EXPECT_FALSE(extract("1 2 3 4 ", record<' ', 2>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_FALSE(extract("1 2 3 4", record<' ', 2>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 2 3 ", record<' ', 2>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 2 3", record<' ', 2>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 2 ", record<' ', 2>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 2", record<' ', 2>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 ", record<' ', 2>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_FALSE(extract("1", record<' ', 2>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_TRUE(extract(" ", record<' ', 2>(&x, &y, &z))); - EXPECT_EQ("", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_FALSE(extract("", record<' ', 2>(&x, &y, &z))); - EXPECT_EQ("", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1 2 3 4"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1"_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract(" "_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract(""_s, record<' ', 2>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; - EXPECT_FALSE(extract("1 2 3 4 ", record<' ', 1>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_FALSE(extract("1 2 3 4", record<' ', 1>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 2 3 ", record<' ', 1>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 2 3", record<' ', 1>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("3", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 2 ", record<' ', 1>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 2", record<' ', 1>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("2", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_TRUE(extract("1 ", record<' ', 1>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_TRUE(extract("1", record<' ', 1>(&x, &y, &z))); - EXPECT_EQ("1", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_TRUE(extract(" ", record<' ', 1>(&x, &y, &z))); - EXPECT_EQ("", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; - EXPECT_TRUE(extract("", record<' ', 1>(&x, &y, &z))); - EXPECT_EQ("", x); - EXPECT_EQ("", y); - EXPECT_EQ("", z); - x = y = z = ""; + EXPECT_FALSE(extract("1 2 3 4 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_FALSE(extract("1 2 3 4"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 3"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ("3"_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 2"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ("2"_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1 "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract("1"_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ("1"_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract(" "_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; + EXPECT_TRUE(extract(""_s, record<' ', 1>(&x, &y, &z))); + EXPECT_EQ(""_s, x); + EXPECT_EQ(""_s, y); + EXPECT_EQ(""_s, z); + x = y = z = ""_s; } TEST(extract, mapname) { MapName map; - EXPECT_TRUE(extract("abc", &map)); - EXPECT_EQ(map, "abc"); - EXPECT_TRUE(extract("abc.gat", &map)); - EXPECT_EQ(map, "abc"); - EXPECT_TRUE(extract("abcdefghijklmno", &map)); - EXPECT_EQ(map, "abcdefghijklmno"); - EXPECT_TRUE(extract("abcdefghijklmno.gat", &map)); - EXPECT_EQ(map, "abcdefghijklmno"); + EXPECT_TRUE(extract("abc"_s, &map)); + EXPECT_EQ(map, "abc"_s); + EXPECT_TRUE(extract("abc.gat"_s, &map)); + EXPECT_EQ(map, "abc"_s); + EXPECT_TRUE(extract("abcdefghijklmno"_s, &map)); + EXPECT_EQ(map, "abcdefghijklmno"_s); + EXPECT_TRUE(extract("abcdefghijklmno.gat"_s, &map)); + EXPECT_EQ(map, "abcdefghijklmno"_s); } +} // namespace tmwa diff --git a/src/mmo/fwd.hpp b/src/mmo/fwd.hpp new file mode 100644 index 0000000..3b56bfb --- /dev/null +++ b/src/mmo/fwd.hpp @@ -0,0 +1,68 @@ +#pragma once +// mmo/fwd.hpp - list of type names for mmo lib +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +// meh, add more when I feel like it +class MapName; +class CharName; +class CharPair; + +class HumanTimeDiff; + +class AccountId; +class CharId; +class PartyId; +class ItemUnkId; +class ItemNameId; +class GmLevel; + +class AccountName; +class AccountPass; +class AccountCrypt; +class AccountEmail; +class ServerName; +class PartyName; +class VarName; +class MapName; +class CharName; + +class Item; +#if 0 +class Point; +class SkillValue; +#endif +class GlobalReg; +#if 0 +class CharKey; +class CharData; +class CharPair; +#endif +class Storage; +#if 0 +class GM_Account; +class PartyMember; +#endif +class PartyMost; +class PartyPair; +} // namespace tmwa diff --git a/src/mmo/human_time_diff.cpp b/src/mmo/human_time_diff.cpp index f2f720e..49a7664 100644 --- a/src/mmo/human_time_diff.cpp +++ b/src/mmo/human_time_diff.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/mmo/human_time_diff.hpp b/src/mmo/human_time_diff.hpp index 689b8d9..b5c19fb 100644 --- a/src/mmo/human_time_diff.hpp +++ b/src/mmo/human_time_diff.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MMO_HUMAN_TIME_DIFF_HPP -#define TMWA_MMO_HUMAN_TIME_DIFF_HPP +#pragma once // human_time_diff.hpp - broken deltas // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,12 +18,17 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/xstring.hpp" +#include <algorithm> -# include "extract.hpp" +#include "../strings/xstring.hpp" +#include "extract.hpp" + + +namespace tmwa +{ struct HumanTimeDiff { short year, month, day, hour, minute, second; @@ -61,26 +65,25 @@ bool extract(XString str, HumanTimeDiff *iv) str = str.xislice_t(it2); short *ptr = nullptr; - if (suffix == "y" || suffix == "a") + if (suffix == "y"_s || suffix == "a"_s) ptr = &iv->year; - else if (suffix == "m") + else if (suffix == "m"_s) ptr = &iv->month; - else if (suffix == "j" || suffix == "d") + else if (suffix == "j"_s || suffix == "d"_s) ptr = &iv->day; - else if (suffix == "h") + else if (suffix == "h"_s) ptr = &iv->hour; - else if (suffix == "mn") + else if (suffix == "mn"_s) ptr = &iv->minute; - else if (suffix == "s") + else if (suffix == "s"_s) ptr = &iv->second; else return false; - if (number.startswith('+') && !number.startswith("+-")) + if (number.startswith('+') && !number.startswith("+-"_s)) number = number.xslice_t(1); if (*ptr || !extract(number, ptr)) return false; } return true; } - -#endif // TMWA_MMO_HUMAN_TIME_DIFF_HPP +} // namespace tmwa diff --git a/src/mmo/human_time_diff_test.cpp b/src/mmo/human_time_diff_test.cpp index 138849b..c18599d 100644 --- a/src/mmo/human_time_diff_test.cpp +++ b/src/mmo/human_time_diff_test.cpp @@ -1,5 +1,5 @@ #include "human_time_diff.hpp" -// human_time_diff.hpp - Testwuite for broken deltas +// human_time_diff_test.cpp - Testwuite for broken deltas // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> // @@ -22,13 +22,16 @@ #include "../poison.hpp" + +namespace tmwa +{ // a sequence of [-+]?[0-9]+([ay]|m|[jd]|h|mn|s) TEST(humantimediff, single) { HumanTimeDiff diff; - EXPECT_TRUE(extract("42y", &diff)); + EXPECT_TRUE(extract("42y"_s, &diff)); EXPECT_EQ(42, diff.year); EXPECT_EQ(0, diff.month); EXPECT_EQ(0, diff.day); @@ -36,7 +39,7 @@ TEST(humantimediff, single) EXPECT_EQ(0, diff.minute); EXPECT_EQ(0, diff.second); - EXPECT_TRUE(extract("42m", &diff)); + EXPECT_TRUE(extract("42m"_s, &diff)); EXPECT_EQ(0, diff.year); EXPECT_EQ(42, diff.month); EXPECT_EQ(0, diff.day); @@ -44,7 +47,7 @@ TEST(humantimediff, single) EXPECT_EQ(0, diff.minute); EXPECT_EQ(0, diff.second); - EXPECT_TRUE(extract("42d", &diff)); + EXPECT_TRUE(extract("42d"_s, &diff)); EXPECT_EQ(0, diff.year); EXPECT_EQ(0, diff.month); EXPECT_EQ(42, diff.day); @@ -52,7 +55,7 @@ TEST(humantimediff, single) EXPECT_EQ(0, diff.minute); EXPECT_EQ(0, diff.second); - EXPECT_TRUE(extract("42h", &diff)); + EXPECT_TRUE(extract("42h"_s, &diff)); EXPECT_EQ(0, diff.year); EXPECT_EQ(0, diff.month); EXPECT_EQ(0, diff.day); @@ -60,7 +63,7 @@ TEST(humantimediff, single) EXPECT_EQ(0, diff.minute); EXPECT_EQ(0, diff.second); - EXPECT_TRUE(extract("42mn", &diff)); + EXPECT_TRUE(extract("42mn"_s, &diff)); EXPECT_EQ(0, diff.year); EXPECT_EQ(0, diff.month); EXPECT_EQ(0, diff.day); @@ -68,7 +71,7 @@ TEST(humantimediff, single) EXPECT_EQ(42, diff.minute); EXPECT_EQ(0, diff.second); - EXPECT_TRUE(extract("42s", &diff)); + EXPECT_TRUE(extract("42s"_s, &diff)); EXPECT_EQ(0, diff.year); EXPECT_EQ(0, diff.month); EXPECT_EQ(0, diff.day); @@ -76,28 +79,29 @@ TEST(humantimediff, single) EXPECT_EQ(0, diff.minute); EXPECT_EQ(42, diff.second); - EXPECT_TRUE(extract("+42y", &diff)); + EXPECT_TRUE(extract("+42y"_s, &diff)); EXPECT_EQ(42, diff.year); - EXPECT_TRUE(extract("-42y", &diff)); + EXPECT_TRUE(extract("-42y"_s, &diff)); EXPECT_EQ(-42, diff.year); - EXPECT_FALSE(extract("++42y", &diff)); - EXPECT_FALSE(extract("+-42y", &diff)); - EXPECT_FALSE(extract("-+42y", &diff)); - EXPECT_FALSE(extract("--42y", &diff)); - EXPECT_FALSE(extract("4+2y", &diff)); - EXPECT_FALSE(extract("42z", &diff)); + EXPECT_FALSE(extract("++42y"_s, &diff)); + EXPECT_FALSE(extract("+-42y"_s, &diff)); + EXPECT_FALSE(extract("-+42y"_s, &diff)); + EXPECT_FALSE(extract("--42y"_s, &diff)); + EXPECT_FALSE(extract("4+2y"_s, &diff)); + EXPECT_FALSE(extract("42z"_s, &diff)); } TEST(humantimediff, multiple) { HumanTimeDiff diff; - EXPECT_TRUE(extract("42y23m-2d", &diff)); + EXPECT_TRUE(extract("42y23m-2d"_s, &diff)); EXPECT_EQ(42, diff.year); EXPECT_EQ(23, diff.month); EXPECT_EQ(-2, diff.day); EXPECT_EQ(0, diff.hour); EXPECT_EQ(0, diff.minute); EXPECT_EQ(0, diff.second); - EXPECT_FALSE(extract("1y2y", &diff)); + EXPECT_FALSE(extract("1y2y"_s, &diff)); } +} // namespace tmwa diff --git a/src/mmo/ids.cpp b/src/mmo/ids.cpp new file mode 100644 index 0000000..d40d5c3 --- /dev/null +++ b/src/mmo/ids.cpp @@ -0,0 +1,26 @@ +#include "ids.hpp" +// ids.cpp - special integer classes for various object IDs +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/mmo/ids.hpp b/src/mmo/ids.hpp new file mode 100644 index 0000000..4e2b97c --- /dev/null +++ b/src/mmo/ids.hpp @@ -0,0 +1,168 @@ +#pragma once +// ids.hpp - special integer classes for various object IDs +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include "../ints/little.hpp" +#include "../ints/wrap.hpp" + +#include "extract.hpp" + + +namespace tmwa +{ +class Species : public Wrapped<uint16_t> { public: explicit operator bool() const = delete; bool operator !() const = delete; constexpr Species() : Wrapped<uint16_t>() {} protected: constexpr explicit Species(uint16_t a) : Wrapped<uint16_t>(a) {} }; + +constexpr Species NEGATIVE_SPECIES = Species(); + +inline +bool extract(XString str, Species *w) +{ + // lots of data files use this + if (str == "-1"_s) + { + *w = NEGATIVE_SPECIES; + return true; + } + return extract(str, &w->_value); +} + + +class AccountId : public Wrapped<uint32_t> { public: constexpr AccountId() : Wrapped<uint32_t>() {} protected: constexpr explicit AccountId(uint32_t a) : Wrapped<uint32_t>(a) {} }; +class CharId : public Wrapped<uint32_t> { public: constexpr CharId() : Wrapped<uint32_t>() {} protected: constexpr explicit CharId(uint32_t a) : Wrapped<uint32_t>(a) {} }; +// important note: slave mobs synthesize PartyId as -BlockId of master +class PartyId : public Wrapped<uint32_t> { public: constexpr PartyId() : Wrapped<uint32_t>() {} protected: constexpr explicit PartyId(uint32_t a) : Wrapped<uint32_t>(a) {} }; +class ItemNameId : public Wrapped<uint16_t> { public: constexpr ItemNameId() : Wrapped<uint16_t>() {} protected: constexpr explicit ItemNameId(uint16_t a) : Wrapped<uint16_t>(a) {} }; + +class BlockId : public Wrapped<uint32_t> { public: constexpr BlockId() : Wrapped<uint32_t>() {} protected: constexpr explicit BlockId(uint32_t a) : Wrapped<uint32_t>(a) {} }; + +class GmLevel +{ + uint32_t bits; + + friend bool extract(XString str, GmLevel *lvl) { return extract(str, &lvl->bits); } + constexpr explicit + GmLevel(uint32_t b) : bits(b) {} + constexpr explicit + operator uint32_t() const { return bits; } + + template<class T> + explicit + GmLevel(T) = delete; + template<class T, typename=typename std::enable_if<!std::is_same<T, uint32_t>::value && !std::is_same<T, bool>::value>::type> + explicit + operator T() = delete; +public: + constexpr + GmLevel() : bits() {} + constexpr static + GmLevel from(uint32_t bits) { return GmLevel(bits); } + template<class T> + constexpr static + GmLevel from(T) = delete; + + constexpr explicit + operator bool() const { return bits; } + constexpr + bool operator !() const { return !bits; } + + // the argument is the level of a command + constexpr + bool satisfies(GmLevel perm) const { return bits >= perm.bits; } + // the argument is another player's gm level, for info commands + constexpr + bool detects(GmLevel other) const { return bits >= other.bits; } + // the argument is another player's gm level, for aggressive commands + constexpr + bool overwhelms(GmLevel other) const { return bits >= other.bits; } + // the argument is another potential permission level + constexpr + bool obsoletes(GmLevel plvl) const { return bits >= plvl.bits; } + + constexpr + uint16_t get_public_word() const + { + return (bits == 60 || bits == 99) ? 0x0080 : 0; + } + + constexpr + uint32_t get_all_bits() const + { + return bits; + } + + friend constexpr + bool operator == (GmLevel l, GmLevel r) + { + return l.bits == r.bits; + } + friend constexpr + bool operator != (GmLevel l, GmLevel r) + { + return l.bits != r.bits; + } + + friend + bool native_to_network(Byte *network, GmLevel native) + { + network->value = native.bits; + return true; // LIES. But this code is going away soon anyway + } + friend + bool network_to_native(GmLevel *native, Byte network) + { + native->bits = network.value; + return true; // LIES. But this code is going away soon anyway + } + + // TODO kill this code too + friend + bool native_to_network(Little16 *network, GmLevel native) + { + uint16_t tmp = native.bits; + return native_to_network(network, tmp); + } + friend + bool network_to_native(GmLevel *native, Little16 network) + { + uint16_t tmp; + bool rv = network_to_native(&tmp, network); + native->bits = tmp; + return rv; + } + + friend + bool native_to_network(Little32 *network, GmLevel native) + { + return native_to_network(network, native.bits); + } + friend + bool network_to_native(GmLevel *native, Little32 network) + { + return network_to_native(&native->bits, network); + } +}; + +inline +uint32_t convert_for_printf(GmLevel g) +{ + return g.get_all_bits(); +} +} // namespace tmwa diff --git a/src/mmo/ip_test.cpp b/src/mmo/ip_test.cpp deleted file mode 100644 index 8e50453..0000000 --- a/src/mmo/ip_test.cpp +++ /dev/null @@ -1,352 +0,0 @@ -#include "ip.hpp" -// ip_test.cpp - Testsuite for implementation of IP address functions. -// -// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include <gtest/gtest.h> - -#include "../io/cxxstdio.hpp" - -#include "../poison.hpp" - -#define CB(X) (std::integral_constant<bool, (X)>::value) -TEST(ip4addr, cmp) -{ - constexpr static - IP4Address a = IP4_LOCALHOST; - constexpr static - IP4Address b = IP4_BROADCAST; - - EXPECT_FALSE(CB(a < a)); - EXPECT_TRUE (CB(a < b)); - EXPECT_FALSE(CB(b < a)); - EXPECT_FALSE(CB(b < b)); - - EXPECT_FALSE(CB(a > a)); - EXPECT_FALSE(CB(a > b)); - EXPECT_TRUE (CB(b > a)); - EXPECT_FALSE(CB(b > b)); - - EXPECT_TRUE (CB(a <= a)); - EXPECT_TRUE (CB(a <= b)); - EXPECT_FALSE(CB(b <= a)); - EXPECT_TRUE (CB(b <= b)); - - EXPECT_TRUE (CB(a >= a)); - EXPECT_FALSE(CB(a >= b)); - EXPECT_TRUE (CB(b >= a)); - EXPECT_TRUE (CB(b >= b)); - - EXPECT_TRUE (CB(a == a)); - EXPECT_FALSE(CB(a == b)); - EXPECT_FALSE(CB(b == a)); - EXPECT_TRUE (CB(b == b)); - - EXPECT_FALSE(CB(a != a)); - EXPECT_TRUE (CB(a != b)); - EXPECT_TRUE (CB(b != a)); - EXPECT_FALSE(CB(b != b)); -} - -TEST(ip4addr, str) -{ - IP4Address a; - EXPECT_EQ("0.0.0.0", STRNPRINTF(17, "%s", a)); - EXPECT_EQ("127.0.0.1", STRNPRINTF(17, "%s", IP4_LOCALHOST)); - EXPECT_EQ("255.255.255.255", STRNPRINTF(17, "%s", IP4_BROADCAST)); -} - -TEST(ip4addr, extract) -{ - IP4Address a; - EXPECT_TRUE(extract("0.0.0.0", &a)); - EXPECT_EQ("0.0.0.0", STRNPRINTF(16, "%s", a)); - EXPECT_TRUE(extract("127.0.0.1", &a)); - EXPECT_EQ("127.0.0.1", STRNPRINTF(16, "%s", a)); - EXPECT_TRUE(extract("255.255.255.255", &a)); - EXPECT_EQ("255.255.255.255", STRNPRINTF(16, "%s", a)); - EXPECT_TRUE(extract("1.2.3.4", &a)); - EXPECT_EQ("1.2.3.4", STRNPRINTF(16, "%s", a)); - - EXPECT_FALSE(extract("1.2.3.4.5", &a)); - EXPECT_FALSE(extract("1.2.3.4.", &a)); - EXPECT_FALSE(extract("1.2.3.", &a)); - EXPECT_FALSE(extract("1.2.3", &a)); - EXPECT_FALSE(extract("1.2.", &a)); - EXPECT_FALSE(extract("1.2", &a)); - EXPECT_FALSE(extract("1.", &a)); - EXPECT_FALSE(extract("1", &a)); - EXPECT_FALSE(extract("", &a)); -} - - -TEST(ip4mask, body) -{ - IP4Mask m; - EXPECT_EQ(IP4Address(), m.addr()); - EXPECT_EQ(IP4Address(), m.mask()); - m = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST); - EXPECT_EQ(IP4_LOCALHOST, m.addr()); - EXPECT_EQ(IP4_BROADCAST, m.mask()); -} - -TEST(ip4mask, str) -{ - IP4Mask m; - EXPECT_EQ("0.0.0.0/0.0.0.0", STRNPRINTF(33, "%s", m)); - m = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST); - EXPECT_EQ("127.0.0.1/255.255.255.255", STRNPRINTF(33, "%s", m)); -} - -TEST(ip4mask, extract) -{ - IP4Mask m; - EXPECT_FALSE(extract("9.8.7.6/33", &m)); - EXPECT_FALSE(extract("9.8.7.6.5", &m)); - EXPECT_FALSE(extract("9.8.7.6/", &m)); - EXPECT_FALSE(extract("9.8.7", &m)); - EXPECT_FALSE(extract("9.8", &m)); - EXPECT_FALSE(extract("9", &m)); - - EXPECT_TRUE(extract("127.0.0.1", &m)); - EXPECT_EQ("127.0.0.1/255.255.255.255", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("127.0.0.1.", &m)); - EXPECT_EQ("127.0.0.1/255.255.255.255", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("127.0.0.", &m)); - EXPECT_EQ("127.0.0.0/255.255.255.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("127.0.", &m)); - EXPECT_EQ("127.0.0.0/255.255.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("127.", &m)); - EXPECT_EQ("127.0.0.0/255.0.0.0", STRNPRINTF(32, "%s", m)); - - EXPECT_TRUE(extract("1.2.3.4/255.255.255.255", &m)); - EXPECT_EQ("1.2.3.4/255.255.255.255", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("1.2.3.0/255.255.255.0", &m)); - EXPECT_EQ("1.2.3.0/255.255.255.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("1.2.0.4/255.255.0.255", &m)); - EXPECT_EQ("1.2.0.4/255.255.0.255", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("1.2.0.0/255.255.0.0", &m)); - EXPECT_EQ("1.2.0.0/255.255.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("1.0.3.4/255.0.255.255", &m)); - EXPECT_EQ("1.0.3.4/255.0.255.255", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("1.0.3.0/255.0.255.0", &m)); - EXPECT_EQ("1.0.3.0/255.0.255.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("1.0.0.4/255.0.0.255", &m)); - EXPECT_EQ("1.0.0.4/255.0.0.255", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("1.0.0.0/255.0.0.0", &m)); - EXPECT_EQ("1.0.0.0/255.0.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.2.3.4/0.255.255.255", &m)); - EXPECT_EQ("0.2.3.4/0.255.255.255", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.2.3.0/0.255.255.0", &m)); - EXPECT_EQ("0.2.3.0/0.255.255.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.2.0.4/0.255.0.255", &m)); - EXPECT_EQ("0.2.0.4/0.255.0.255", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.2.0.0/0.255.0.0", &m)); - EXPECT_EQ("0.2.0.0/0.255.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.3.4/0.0.255.255", &m)); - EXPECT_EQ("0.0.3.4/0.0.255.255", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.3.0/0.0.255.0", &m)); - EXPECT_EQ("0.0.3.0/0.0.255.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.4/0.0.0.255", &m)); - EXPECT_EQ("0.0.0.4/0.0.0.255", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/0.0.0.0", &m)); - EXPECT_EQ("0.0.0.0/0.0.0.0", STRNPRINTF(32, "%s", m)); - - // please don't do this - EXPECT_TRUE(extract("120.248.200.217/89.57.126.5", &m)); - EXPECT_EQ("88.56.72.1/89.57.126.5", STRNPRINTF(32, "%s", m)); - - EXPECT_TRUE(extract("0.0.0.0/32", &m)); - EXPECT_EQ("0.0.0.0/255.255.255.255", STRNPRINTF(32, "%s", m)); - - EXPECT_TRUE(extract("0.0.0.0/31", &m)); - EXPECT_EQ("0.0.0.0/255.255.255.254", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/30", &m)); - EXPECT_EQ("0.0.0.0/255.255.255.252", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/29", &m)); - EXPECT_EQ("0.0.0.0/255.255.255.248", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/28", &m)); - EXPECT_EQ("0.0.0.0/255.255.255.240", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/27", &m)); - EXPECT_EQ("0.0.0.0/255.255.255.224", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/26", &m)); - EXPECT_EQ("0.0.0.0/255.255.255.192", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/25", &m)); - EXPECT_EQ("0.0.0.0/255.255.255.128", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/24", &m)); - EXPECT_EQ("0.0.0.0/255.255.255.0", STRNPRINTF(32, "%s", m)); - - EXPECT_TRUE(extract("0.0.0.0/23", &m)); - EXPECT_EQ("0.0.0.0/255.255.254.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/22", &m)); - EXPECT_EQ("0.0.0.0/255.255.252.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/21", &m)); - EXPECT_EQ("0.0.0.0/255.255.248.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/20", &m)); - EXPECT_EQ("0.0.0.0/255.255.240.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/19", &m)); - EXPECT_EQ("0.0.0.0/255.255.224.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/18", &m)); - EXPECT_EQ("0.0.0.0/255.255.192.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/17", &m)); - EXPECT_EQ("0.0.0.0/255.255.128.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/16", &m)); - EXPECT_EQ("0.0.0.0/255.255.0.0", STRNPRINTF(32, "%s", m)); - - EXPECT_TRUE(extract("0.0.0.0/15", &m)); - EXPECT_EQ("0.0.0.0/255.254.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/14", &m)); - EXPECT_EQ("0.0.0.0/255.252.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/13", &m)); - EXPECT_EQ("0.0.0.0/255.248.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/12", &m)); - EXPECT_EQ("0.0.0.0/255.240.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/11", &m)); - EXPECT_EQ("0.0.0.0/255.224.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/10", &m)); - EXPECT_EQ("0.0.0.0/255.192.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/9", &m)); - EXPECT_EQ("0.0.0.0/255.128.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/8", &m)); - EXPECT_EQ("0.0.0.0/255.0.0.0", STRNPRINTF(32, "%s", m)); - - EXPECT_TRUE(extract("0.0.0.0/7", &m)); - EXPECT_EQ("0.0.0.0/254.0.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/6", &m)); - EXPECT_EQ("0.0.0.0/252.0.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/5", &m)); - EXPECT_EQ("0.0.0.0/248.0.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/4", &m)); - EXPECT_EQ("0.0.0.0/240.0.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/3", &m)); - EXPECT_EQ("0.0.0.0/224.0.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/2", &m)); - EXPECT_EQ("0.0.0.0/192.0.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/1", &m)); - EXPECT_EQ("0.0.0.0/128.0.0.0", STRNPRINTF(32, "%s", m)); - EXPECT_TRUE(extract("0.0.0.0/0", &m)); - EXPECT_EQ("0.0.0.0/0.0.0.0", STRNPRINTF(32, "%s", m)); -} - -TEST(ip4mask, cover) -{ - IP4Address a; - IP4Address b = IP4_BROADCAST; - IP4Address l = IP4_LOCALHOST; - IP4Address h({127, 255, 255, 255}); - IP4Address p24l({10, 0, 0, 0}); - IP4Address p24h({10, 255, 255, 255}); - IP4Address p20l({172, 16, 0, 0}); - IP4Address p20h({172, 31, 255, 255}); - IP4Address p16l({192, 168, 0, 0}); - IP4Address p16h({192, 168, 255, 255}); - IP4Mask m; - EXPECT_TRUE(m.covers(a)); - EXPECT_TRUE(m.covers(b)); - EXPECT_TRUE(m.covers(l)); - EXPECT_TRUE(m.covers(h)); - EXPECT_TRUE(m.covers(p24l)); - EXPECT_TRUE(m.covers(p24h)); - EXPECT_TRUE(m.covers(p20l)); - EXPECT_TRUE(m.covers(p20h)); - EXPECT_TRUE(m.covers(p16l)); - EXPECT_TRUE(m.covers(p16h)); - m = IP4Mask(l, a); - EXPECT_TRUE(m.covers(a)); - EXPECT_TRUE(m.covers(b)); - EXPECT_TRUE(m.covers(l)); - EXPECT_TRUE(m.covers(h)); - EXPECT_TRUE(m.covers(p24l)); - EXPECT_TRUE(m.covers(p24h)); - EXPECT_TRUE(m.covers(p20l)); - EXPECT_TRUE(m.covers(p20h)); - EXPECT_TRUE(m.covers(p16l)); - EXPECT_TRUE(m.covers(p16h)); - m = IP4Mask(l, b); - EXPECT_FALSE(m.covers(a)); - EXPECT_FALSE(m.covers(b)); - EXPECT_TRUE(m.covers(l)); - EXPECT_FALSE(m.covers(h)); - EXPECT_FALSE(m.covers(p24l)); - EXPECT_FALSE(m.covers(p24h)); - EXPECT_FALSE(m.covers(p20l)); - EXPECT_FALSE(m.covers(p20h)); - EXPECT_FALSE(m.covers(p16l)); - EXPECT_FALSE(m.covers(p16h)); - - // but the really useful ones are with partial masks - m = IP4Mask(IP4Address({10, 0, 0, 0}), IP4Address({255, 0, 0, 0})); - EXPECT_FALSE(m.covers(a)); - EXPECT_FALSE(m.covers(b)); - EXPECT_FALSE(m.covers(l)); - EXPECT_FALSE(m.covers(h)); - EXPECT_TRUE(m.covers(p24l)); - EXPECT_TRUE(m.covers(p24h)); - EXPECT_FALSE(m.covers(p20l)); - EXPECT_FALSE(m.covers(p20h)); - EXPECT_FALSE(m.covers(p16l)); - EXPECT_FALSE(m.covers(p16h)); - EXPECT_FALSE(m.covers(IP4Address({9, 255, 255, 255}))); - EXPECT_FALSE(m.covers(IP4Address({11, 0, 0, 0}))); - m = IP4Mask(IP4Address({127, 0, 0, 0}), IP4Address({255, 0, 0, 0})); - EXPECT_FALSE(m.covers(a)); - EXPECT_FALSE(m.covers(b)); - EXPECT_TRUE(m.covers(l)); - EXPECT_TRUE(m.covers(h)); - EXPECT_FALSE(m.covers(p24l)); - EXPECT_FALSE(m.covers(p24h)); - EXPECT_FALSE(m.covers(p20l)); - EXPECT_FALSE(m.covers(p20h)); - EXPECT_FALSE(m.covers(p16l)); - EXPECT_FALSE(m.covers(p16h)); - EXPECT_FALSE(m.covers(IP4Address({126, 255, 255, 255}))); - EXPECT_FALSE(m.covers(IP4Address({128, 0, 0, 0}))); - m = IP4Mask(IP4Address({172, 16, 0, 0}), IP4Address({255, 240, 0, 0})); - EXPECT_FALSE(m.covers(a)); - EXPECT_FALSE(m.covers(b)); - EXPECT_FALSE(m.covers(l)); - EXPECT_FALSE(m.covers(h)); - EXPECT_FALSE(m.covers(p24l)); - EXPECT_FALSE(m.covers(p24h)); - EXPECT_TRUE(m.covers(p20l)); - EXPECT_TRUE(m.covers(p20h)); - EXPECT_FALSE(m.covers(p16l)); - EXPECT_FALSE(m.covers(p16h)); - EXPECT_FALSE(m.covers(IP4Address({172, 15, 255, 255}))); - EXPECT_FALSE(m.covers(IP4Address({172, 32, 0, 0}))); - m = IP4Mask(IP4Address({192, 168, 0, 0}), IP4Address({255, 255, 0, 0})); - EXPECT_FALSE(m.covers(a)); - EXPECT_FALSE(m.covers(b)); - EXPECT_FALSE(m.covers(l)); - EXPECT_FALSE(m.covers(h)); - EXPECT_FALSE(m.covers(p24l)); - EXPECT_FALSE(m.covers(p24h)); - EXPECT_FALSE(m.covers(p20l)); - EXPECT_FALSE(m.covers(p20h)); - EXPECT_TRUE(m.covers(p16l)); - EXPECT_TRUE(m.covers(p16h)); - EXPECT_FALSE(m.covers(IP4Address({192, 167, 255, 255}))); - EXPECT_FALSE(m.covers(IP4Address({192, 169, 0, 0}))); - - // OTOH this is crazy - EXPECT_TRUE(extract("120.248.200.217/89.57.126.5", &m)); - EXPECT_TRUE(m.covers(IP4Address({120, 248, 200, 217}))); - EXPECT_TRUE(m.covers(IP4Address({88, 56, 72, 1}))); - EXPECT_FALSE(m.covers(IP4Address({88, 56, 72, 0}))); - EXPECT_FALSE(m.covers(IP4Address({88, 56, 72, 255}))); -} diff --git a/src/mmo/md5more.cpp b/src/mmo/md5more.cpp index 3fce5c7..4e5d2da 100644 --- a/src/mmo/md5more.cpp +++ b/src/mmo/md5more.cpp @@ -20,14 +20,24 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include <algorithm> + #include "../compat/rawmem.hpp" #include "../generic/random.hpp" #include "../io/cxxstdio.hpp" +#include "../io/read.hpp" + +#include "../net/ip.hpp" + +#include "../mmo/mmo.hpp" #include "../poison.hpp" + +namespace tmwa +{ #define X block.data // TODO - refactor MD5 into a stream, and merge the implementations @@ -103,7 +113,7 @@ AccountCrypt MD5_saltcrypt(AccountPass key, SaltString salt) VString<31> obuf; // This truncates the string, but we have to keep it like that for compatibility - SNPRINTF(obuf, 32, "!%s$%s", salt, tbuf3); + SNPRINTF(obuf, 32, "!%s$%s"_fmt, salt, tbuf3); return stringish<AccountCrypt>(obuf); } @@ -134,7 +144,7 @@ IP4Address MD5_ip(IP4Address ip) // MD5sum a secret + the IP address VString<31> ipbuf; - SNPRINTF(ipbuf, 32, "%s %s", ip, secret); + SNPRINTF(ipbuf, 32, "%s %s"_fmt, ip, secret); md5_binary obuf; MD5_to_bin(MD5_from_string(ipbuf), obuf); @@ -146,3 +156,4 @@ IP4Address MD5_ip(IP4Address ip) static_cast<uint8_t>(obuf[6] ^ obuf[7] ^ obuf[14] ^ obuf[15]), }); } +} // namespace tmwa diff --git a/src/mmo/md5more.hpp b/src/mmo/md5more.hpp index b1da783..7d50713 100644 --- a/src/mmo/md5more.hpp +++ b/src/mmo/md5more.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MMO_MD5MORE_HPP -#define TMWA_MMO_MD5MORE_HPP +#pragma once // md5more.hpp - Non-basic MD5 functions. // // Copyright © ????-2004 Athena Dev Teams @@ -21,15 +20,17 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../generic/md5.hpp" +#include "../generic/md5.hpp" -# include "../io/read.hpp" +#include "../io/fwd.hpp" -# include "ip.hpp" -# include "mmo.hpp" +#include "../net/fwd.hpp" + +namespace tmwa +{ MD5_state MD5_from_FILE(io::ReadFile& in); // whoever wrote this fails basic understanding of @@ -44,5 +45,4 @@ bool pass_ok(AccountPass password, AccountCrypt crypted); /// This returns an IP4Address because it is configurable whether it gets called at all IP4Address MD5_ip(IP4Address ip); - -#endif // TMWA_MMO_MD5MORE_HPP +} // namespace tmwa diff --git a/src/mmo/mmo.cpp b/src/mmo/mmo.cpp index 8bf7edf..aafa431 100644 --- a/src/mmo/mmo.cpp +++ b/src/mmo/mmo.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/mmo/mmo.hpp b/src/mmo/mmo.hpp index c9d62ca..cfa278d 100644 --- a/src/mmo/mmo.hpp +++ b/src/mmo/mmo.hpp @@ -1,6 +1,5 @@ -#ifndef TMWA_MMO_MMO_HPP -#define TMWA_MMO_MMO_HPP -// mmo.hpp - Huge mess of structures and constants. +#pragma once +// mmo.hpp - Huge mess of structures. // // Copyright © ????-2004 Athena Dev Teams // Copyright © 2004-2011 The Mana World Development Team @@ -21,347 +20,25 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../compat/memory.hpp" +#include "../compat/memory.hpp" -# include "../strings/vstring.hpp" +#include "../proto2/types.hpp" -# include "../generic/enum.hpp" -# include "timer.t.hpp" - -// affects CharName -# define NAME_IGNORING_CASE 1 - -constexpr int FIFOSIZE_SERVERLINK = 256 * 1024; - -constexpr int MAX_MAP_PER_SERVER = 512; -constexpr int MAX_INVENTORY = 100; -constexpr int MAX_AMOUNT = 30000; -constexpr int MAX_ZENY = 1000000000; // 1G zeny -constexpr int TRADE_MAX = 10; - -enum class SkillID : uint16_t; -constexpr SkillID MAX_SKILL = SkillID(474); // not 450 -constexpr SkillID get_enum_min_value(SkillID) { return SkillID(); } -constexpr SkillID get_enum_max_value(SkillID) { return MAX_SKILL; } - -constexpr int GLOBAL_REG_NUM = 96; -constexpr int ACCOUNT_REG_NUM = 16; -constexpr int ACCOUNT_REG2_NUM = 16; -constexpr interval_t DEFAULT_WALK_SPEED = std::chrono::milliseconds(150); -constexpr interval_t MIN_WALK_SPEED = interval_t::zero(); -constexpr interval_t MAX_WALK_SPEED = std::chrono::seconds(1); -constexpr int MAX_STORAGE = 300; -constexpr int MAX_PARTY = 12; - -# define MIN_HAIR_STYLE battle_config.min_hair_style -# define MAX_HAIR_STYLE battle_config.max_hair_style -# define MIN_HAIR_COLOR battle_config.min_hair_color -# define MAX_HAIR_COLOR battle_config.max_hair_color -# define MIN_CLOTH_COLOR battle_config.min_cloth_color -# define MAX_CLOTH_COLOR battle_config.max_cloth_color - -template<class T, size_t n> -struct Array +namespace tmwa { - T data[n]; -public: - T& operator [](size_t i) { assert (i < n); return data[i]; } - const T& operator [](size_t i) const { assert (i < n); return data[i]; } - - T *begin() { return data + 0; } - T *end() { return data + n; } - const T *begin() const { return data + 0; } - const T *end() const { return data + n; } -}; - -struct AccountName : VString<23> {}; -struct AccountPass : VString<23> {}; -struct AccountCrypt : VString<39> {}; -struct AccountEmail : VString<39> {}; -struct ServerName : VString<19> {}; -struct PartyName : VString<23> {}; -struct VarName : VString<31> {}; - -# define DEFAULT_EMAIL stringish<AccountEmail>("a@a.com") - -// It is decreed: a mapname shall not contain an extension -class MapName : public strings::_crtp_string<MapName, MapName, strings::ZPair> -{ - VString<15> _impl; -public: - MapName() = default; - MapName(VString<15> v) : _impl(v.xislice_h(std::find(v.begin(), v.end(), '.'))) {} - - iterator begin() const { return &*_impl.begin(); } - iterator end() const { return &*_impl.end(); } - const char *c_str() const { return _impl.c_str(); } - - operator RString() const { return _impl; } - operator AString() const { return _impl; } - operator TString() const { return _impl; } - operator SString() const { return _impl; } - operator ZString() const { return _impl; } - operator XString() const { return _impl; } -}; -template<> inline -MapName stringish<MapName>(VString<15> iv) +bool operator == (const SkillValue& l, const SkillValue& r) { - return iv; + return l.lv == r.lv && l.flags == r.flags; } inline -const char *decay_for_printf(const MapName& vs) { return vs.c_str(); } - -// It is decreed: a charname is sometimes case sensitive -struct CharName +bool operator != (const SkillValue& l, const SkillValue& r) { -private: - VString<23> _impl; -public: - CharName() = default; - explicit CharName(VString<23> name) - : _impl(name) - {} - - VString<23> to__actual() const - { - return _impl; - } - VString<23> to__lower() const - { - return _impl.to_lower(); - } - VString<23> to__upper() const - { - return _impl.to_upper(); - } - VString<23> to__canonical() const - { -# if NAME_IGNORING_CASE == 0 - return to__actual(); -# endif -# if NAME_IGNORING_CASE == 1 - return to__lower(); -# endif - } - - friend bool operator == (const CharName& l, const CharName& r) - { return l.to__canonical() == r.to__canonical(); } - friend bool operator != (const CharName& l, const CharName& r) - { return l.to__canonical() != r.to__canonical(); } - friend bool operator < (const CharName& l, const CharName& r) - { return l.to__canonical() < r.to__canonical(); } - friend bool operator <= (const CharName& l, const CharName& r) - { return l.to__canonical() <= r.to__canonical(); } - friend bool operator > (const CharName& l, const CharName& r) - { return l.to__canonical() > r.to__canonical(); } - friend bool operator >= (const CharName& l, const CharName& r) - { return l.to__canonical() >= r.to__canonical(); } - - friend - VString<23> convert_for_printf(const CharName& vs) { return vs.to__actual(); } -}; -template<> -inline -CharName stringish<CharName>(VString<23> iv) -{ - return CharName(iv); -} - -namespace e -{ -enum class EPOS : uint16_t -{ - ZERO = 0x0000, - - LEGS = 0x0001, - WEAPON = 0x0002, - GLOVES = 0x0004, - CAPE = 0x0008, - MISC1 = 0x0010, - SHIELD = 0x0020, - SHOES = 0x0040, - MISC2 = 0x0080, - HAT = 0x0100, - TORSO = 0x0200, - - ARROW = 0x8000, -}; -ENUM_BITWISE_OPERATORS(EPOS) - -constexpr EPOS get_enum_min_value(EPOS) { return EPOS(0x0000); } -constexpr EPOS get_enum_max_value(EPOS) { return EPOS(0xffff); } -} -using e::EPOS; - -struct item -{ - int id; - short nameid; - short amount; - EPOS equip; -}; - -struct point -{ - MapName map_; - short x, y; -}; - -namespace e -{ -enum class SkillFlags : uint16_t; + return !(l == r); } -using e::SkillFlags; - -struct skill_value -{ - unsigned short lv; - SkillFlags flags; - - friend bool operator == (const skill_value& l, const skill_value& r) - { - return l.lv == r.lv && l.flags == r.flags; - } - friend bool operator != (const skill_value& l, const skill_value& r) - { - return !(l == r); - } -}; - -struct global_reg -{ - VarName str; - int value; -}; - -// Option and Opt1..3 in map.hpp -namespace e -{ -enum class Option : uint16_t; -constexpr Option get_enum_min_value(Option) { return Option(0x0000); } -constexpr Option get_enum_max_value(Option) { return Option(0xffff); } -} -using e::Option; - -enum class ATTR -{ - STR = 0, - AGI = 1, - VIT = 2, - INT = 3, - DEX = 4, - LUK = 5, - - COUNT = 6, -}; - -constexpr ATTR ATTRs[6] = -{ - ATTR::STR, - ATTR::AGI, - ATTR::VIT, - ATTR::INT, - ATTR::DEX, - ATTR::LUK, -}; - -enum class ItemLook : uint16_t -{ - NONE = 0, - BLADE = 1, // or some other common weapons - _2, - SETZER_AND_SCYTHE = 3, - _6, - STAFF = 10, - BOW = 11, - _13 = 13, - _14 = 14, - _16 = 16, - SINGLE_HANDED_COUNT = 17, - - DUAL_BLADE = 0x11, - DUAL_2 = 0x12, - DUAL_6 = 0x13, - DUAL_12 = 0x14, - DUAL_16 = 0x15, - DUAL_26 = 0x16, -}; - -enum class SEX : uint8_t -{ - FEMALE = 0, - MALE = 1, - // For items. This is also used as error, sometime. - NEUTRAL = 2, -}; -inline -char sex_to_char(SEX sex) -{ - switch (sex) - { - case SEX::FEMALE: return 'F'; - case SEX::MALE: return 'M'; - default: return '\0'; - } -} -inline -SEX sex_from_char(char c) -{ - switch (c) - { - case 'F': return SEX::FEMALE; - case 'M': return SEX::MALE; - default: return SEX::NEUTRAL; - } -} - -struct CharKey -{ - CharName name; - int account_id; - int char_id; - unsigned char char_num; -}; - -struct CharData -{ - int partner_id; - - int base_exp, job_exp, zeny; - - short species; - short status_point, skill_point; - int hp, max_hp, sp, max_sp; - Option option; - short karma, manner; - short hair, hair_color, clothes_color; - int party_id; - - ItemLook weapon; - short shield; - short head_top, head_mid, head_bottom; - - unsigned char base_level, job_level; - earray<short, ATTR, ATTR::COUNT> attrs; - SEX sex; - - unsigned long mapip; - unsigned int mapport; - - struct point last_point, save_point; - Array<struct item, MAX_INVENTORY> inventory; - earray<skill_value, SkillID, MAX_SKILL> skill; - int global_reg_num; - Array<struct global_reg, GLOBAL_REG_NUM> global_reg; - int account_reg_num; - Array<struct global_reg, ACCOUNT_REG_NUM> account_reg; - int account_reg2_num; - Array<struct global_reg, ACCOUNT_REG2_NUM> account_reg2; -}; struct CharPair { @@ -373,37 +50,20 @@ struct CharPair {} }; -struct storage -{ - int dirty; - int account_id; - short storage_status; - short storage_amount; - Array<struct item, MAX_STORAGE> storage_; -}; - struct GM_Account { - int account_id; - uint8_t level; + AccountId account_id; + GmLevel level; }; -struct party_member +struct PartyPair { - int account_id; - CharName name; - MapName map; - int leader, online, lv; - struct map_session_data *sd; -}; + PartyId party_id = {}; + PartyMost *party_most = {}; -struct party -{ - int party_id; - PartyName name; - int exp; - int item; - Array<struct party_member, MAX_PARTY> member; + explicit + operator bool() const { return party_most; } + bool operator !() const { return !party_most; } + PartyMost *operator->() const { return party_most; } }; - -#endif // TMWA_MMO_MMO_HPP +} // namespace tmwa diff --git a/src/mmo/socket.hpp b/src/mmo/socket.hpp deleted file mode 100644 index c166794..0000000 --- a/src/mmo/socket.hpp +++ /dev/null @@ -1,424 +0,0 @@ -#ifndef TMWA_MMO_SOCKET_HPP -#define TMWA_MMO_SOCKET_HPP -// socket.hpp - Network event system. -// -// Copyright © ????-2004 Athena Dev Teams -// Copyright © 2004-2011 The Mana World Development Team -// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -# include "../sanity.hpp" - -# include <netinet/in.h> - -# include <cstdio> - -# include <array> - -# include "../compat/rawmem.hpp" - -# include "../strings/astring.hpp" -# include "../strings/vstring.hpp" -# include "../strings/xstring.hpp" - -# include "../io/fd.hpp" - -# include "dumb_ptr.hpp" -# include "ip.hpp" -# include "utils.hpp" -# include "timer.t.hpp" - -struct SessionData -{ -}; -struct SessionDeleter -{ - // defined per-server - void operator()(SessionData *sd); -}; - -struct Session; -struct SessionIO -{ - void (*func_recv)(Session *); - void (*func_send)(Session *); -}; - -struct SessionParsers -{ - void (*func_parse)(Session *); - void (*func_delete)(Session *); -}; - -struct Session -{ - Session(SessionIO, SessionParsers); - Session(Session&&) = delete; - Session& operator = (Session&&) = delete; - - void set_io(SessionIO); - void set_parsers(SessionParsers); - - /// Checks whether a newly-connected socket actually does anything - TimeT created; - bool connected; - -private: - /// Flag needed since structure must be freed in a server-dependent manner - bool eof; -public: - void set_eof() { eof = true; } - - /// Currently used by clif_setwaitclose - Timer timed_close; - - /// Since this is a single-threaded application, it can't block - /// These are the read/write queues - dumb_ptr<uint8_t[]> rdata, wdata; - size_t max_rdata, max_wdata; - /// How much is actually in the queue - size_t rdata_size, wdata_size; - /// How much has already been read from the queue - /// Note that there is no need for a wdata_pos - size_t rdata_pos; - - IP4Address client_ip; - -private: - /// Send or recieve - /// Only called when select() indicates the socket is ready - /// If, after that, nothing is read, it sets eof - // These could probably be hard-coded with a little work - void (*func_recv)(Session *); - void (*func_send)(Session *); - /// This is the important one - /// Set to different functions depending on whether the connection - /// is a player or a server/ladmin - void (*func_parse)(Session *); - /// Cleanup function since we're not fully RAII yet - void (*func_delete)(Session *); - -public: - // this really ought to be part of session_data, once that gets sane - SessionParsers for_inferior; - - /// Server-specific data type - // (this really should include the deleter, but ...) - std::unique_ptr<SessionData, SessionDeleter> session_data; - - io::FD fd; - - friend void do_sendrecv(interval_t next); - friend void do_parsepacket(void); - friend void delete_session(Session *); -}; - -inline -int convert_for_printf(Session *s) -{ - return s->fd.uncast_dammit(); -} - -// save file descriptors for important stuff -constexpr int SOFT_LIMIT = FD_SETSIZE - 50; - -// socket timeout to establish a full connection in seconds -constexpr int CONNECT_TIMEOUT = 15; - - -void set_session(io::FD fd, std::unique_ptr<Session> sess); -Session *get_session(io::FD fd); -void reset_session(io::FD fd); -int get_fd_max(); - -class IncrFD -{ -public: - static - io::FD inced(io::FD v) - { - return io::FD::cast_dammit(v.uncast_dammit() + 1); - } -}; -IteratorPair<ValueIterator<io::FD, IncrFD>> iter_fds(); - - -/// open a socket, bind, and listen. Return an fd, or -1 if socket() fails, -/// but exit if bind() or listen() fails -Session *make_listen_port(uint16_t port, SessionParsers inferior); -/// Connect to an address, return a connected socket or -1 -// FIXME - this is IPv4 only! -Session *make_connection(IP4Address ip, uint16_t port, SessionParsers); -/// free() the structure and close() the fd -void delete_session(Session *); -/// Make a the internal queues bigger -void realloc_fifo(Session *s, size_t rfifo_size, size_t wfifo_size); -/// Update all sockets that can be read/written from the queues -void do_sendrecv(interval_t next); -/// Call the parser function for every socket that has read data -void do_parsepacket(void); - -template<class T> -uint8_t *pod_addressof_m(T& structure) -{ - static_assert(is_trivially_copyable<T>::value, "Can only byte-copy POD-ish structs"); - return &reinterpret_cast<uint8_t&>(structure); -} - -template<class T> -const uint8_t *pod_addressof_c(const T& structure) -{ - static_assert(is_trivially_copyable<T>::value, "Can only byte-copy POD-ish structs"); - return &reinterpret_cast<const uint8_t&>(structure); -} - - -/// Check how much can be read -inline -size_t RFIFOREST(Session *s) -{ - return s->rdata_size - s->rdata_pos; -} -/// Read from the queue -inline -const void *RFIFOP(Session *s, size_t pos) -{ - return &s->rdata[s->rdata_pos + pos]; -} -inline -uint8_t RFIFOB(Session *s, size_t pos) -{ - return *static_cast<const uint8_t *>(RFIFOP(s, pos)); -} -inline -uint16_t RFIFOW(Session *s, size_t pos) -{ - return *static_cast<const uint16_t *>(RFIFOP(s, pos)); -} -inline -uint32_t RFIFOL(Session *s, size_t pos) -{ - return *static_cast<const uint32_t *>(RFIFOP(s, pos)); -} -template<class T> -void RFIFO_STRUCT(Session *s, size_t pos, T& structure) -{ - really_memcpy(pod_addressof_m(structure), static_cast<const uint8_t *>(RFIFOP(s, pos)), sizeof(T)); -} -inline -IP4Address RFIFOIP(Session *s, size_t pos) -{ - IP4Address o; - RFIFO_STRUCT(s, pos, o); - return o; -} -template<uint8_t len> -inline -VString<len-1> RFIFO_STRING(Session *s, size_t pos) -{ - const char *const begin = static_cast<const char *>(RFIFOP(s, pos)); - const char *const end = begin + len-1; - const char *const mid = std::find(begin, end, '\0'); - return XString(begin, mid, nullptr); -} -inline -AString RFIFO_STRING(Session *s, size_t pos, size_t len) -{ - const char *const begin = static_cast<const char *>(RFIFOP(s, pos)); - const char *const end = begin + len; - const char *const mid = std::find(begin, end, '\0'); - return XString(begin, mid, nullptr); -} -inline -void RFIFO_BUF_CLONE(Session *s, uint8_t *buf, size_t len) -{ - really_memcpy(buf, static_cast<const uint8_t *>(RFIFOP(s, 0)), len); -} - -/// Done reading -void RFIFOSKIP(Session *s, size_t len); - -/// Read from an arbitrary buffer -inline -const void *RBUFP(const uint8_t *p, size_t pos) -{ - return p + pos; -} -inline -uint8_t RBUFB(const uint8_t *p, size_t pos) -{ - return *static_cast<const uint8_t *>(RBUFP(p, pos)); -} -inline -uint16_t RBUFW(const uint8_t *p, size_t pos) -{ - return *static_cast<const uint16_t *>(RBUFP(p, pos)); -} -inline -uint32_t RBUFL(const uint8_t *p, size_t pos) -{ - return *static_cast<const uint32_t *>(RBUFP(p, pos)); -} -template<class T> -void RBUF_STRUCT(const uint8_t *p, size_t pos, T& structure) -{ - really_memcpy(pod_addressof_m(structure), p + pos, sizeof(T)); -} -inline -IP4Address RBUFIP(const uint8_t *p, size_t pos) -{ - IP4Address o; - RBUF_STRUCT(p, pos, o); - return o; -} -template<uint8_t len> -inline -VString<len-1> RBUF_STRING(const uint8_t *p, size_t pos) -{ - const char *const begin = static_cast<const char *>(RBUFP(p, pos)); - const char *const end = begin + len-1; - const char *const mid = std::find(begin, end, '\0'); - return XString(begin, mid, nullptr); -} -inline -AString RBUF_STRING(const uint8_t *p, size_t pos, size_t len) -{ - const char *const begin = static_cast<const char *>(RBUFP(p, pos)); - const char *const end = begin + len; - const char *const mid = std::find(begin, end, '\0'); - return XString(begin, mid, nullptr); -} - - -/// Unused - check how much data can be written -// the existence of this seems scary -inline -size_t WFIFOSPACE(Session *s) -{ - return s->max_wdata - s->wdata_size; -} -/// Write to the queue -inline -void *WFIFOP(Session *s, size_t pos) -{ - return &s->wdata[s->wdata_size + pos]; -} -inline -uint8_t& WFIFOB(Session *s, size_t pos) -{ - return *static_cast<uint8_t *>(WFIFOP(s, pos)); -} -inline -uint16_t& WFIFOW(Session *s, size_t pos) -{ - return *static_cast<uint16_t *>(WFIFOP(s, pos)); -} -inline -uint32_t& WFIFOL(Session *s, size_t pos) -{ - return *static_cast<uint32_t *>(WFIFOP(s, pos)); -} -template<class T> -void WFIFO_STRUCT(Session *s, size_t pos, T& structure) -{ - really_memcpy(static_cast<uint8_t *>(WFIFOP(s, pos)), pod_addressof_c(structure), sizeof(T)); -} -inline -IP4Address& WFIFOIP(Session *s, size_t pos) -{ - static_assert(is_trivially_copyable<IP4Address>::value, "That was the whole point"); - return *static_cast<IP4Address *>(WFIFOP(s, pos)); -} -inline -void WFIFO_STRING(Session *s, size_t pos, XString str, size_t len) -{ - char *const begin = static_cast<char *>(WFIFOP(s, pos)); - char *const end = begin + len; - char *const mid = std::copy(str.begin(), str.end(), begin); - std::fill(mid, end, '\0'); -} -inline -void WFIFO_ZERO(Session *s, size_t pos, size_t len) -{ - uint8_t *b = static_cast<uint8_t *>(WFIFOP(s, pos)); - uint8_t *e = b + len; - std::fill(b, e, '\0'); -} -inline -void WFIFO_BUF_CLONE(Session *s, const uint8_t *buf, size_t len) -{ - really_memcpy(static_cast<uint8_t *>(WFIFOP(s, 0)), buf, len); -} - -/// Finish writing -void WFIFOSET(Session *s, size_t len); - -/// Write to an arbitrary buffer -inline -void *WBUFP(uint8_t *p, size_t pos) -{ - return p + pos; -} -inline -uint8_t& WBUFB(uint8_t *p, size_t pos) -{ - return *static_cast<uint8_t *>(WBUFP(p, pos)); -} -inline -uint16_t& WBUFW(uint8_t *p, size_t pos) -{ - return *static_cast<uint16_t *>(WBUFP(p, pos)); -} -inline -uint32_t& WBUFL(uint8_t *p, size_t pos) -{ - return *static_cast<uint32_t *>(WBUFP(p, pos)); -} -template<class T> -void WBUF_STRUCT(uint8_t *p, size_t pos, T& structure) -{ - really_memcpy(p + pos, pod_addressof_c(structure), sizeof(T)); -} -inline -IP4Address& WBUFIP(uint8_t *p, size_t pos) -{ - return *static_cast<IP4Address *>(WBUFP(p, pos)); -} -inline -void WBUF_STRING(uint8_t *p, size_t pos, XString s, size_t len) -{ - char *const begin = static_cast<char *>(WBUFP(p, pos)); - char *const end = begin + len; - char *const mid = std::copy(s.begin(), s.end(), begin); - std::fill(mid, end, '\0'); -} -inline -void WBUF_ZERO(uint8_t *p, size_t pos, size_t len) -{ - uint8_t *b = static_cast<uint8_t *>(WBUFP(p, pos)); - uint8_t *e = b + len; - std::fill(b, e, '\0'); -} - -inline -void RFIFO_WFIFO_CLONE(Session *rs, Session *ws, size_t len) -{ - really_memcpy(static_cast<uint8_t *>(WFIFOP(ws, 0)), - static_cast<const uint8_t *>(RFIFOP(rs, 0)), len); -} - -#endif // TMWA_MMO_SOCKET_HPP diff --git a/src/map/magic-interpreter-aux.cpp b/src/mmo/strs.cpp index 10a376b..71dceec 100644 --- a/src/map/magic-interpreter-aux.cpp +++ b/src/mmo/strs.cpp @@ -1,5 +1,5 @@ -#include "magic-interpreter-aux.hpp" -// magic-interpreter-aux.cpp - Edge of the magic system. +#include "strs.hpp" +// strs.cpp - common string types // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> // @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/mmo/strs.hpp b/src/mmo/strs.hpp new file mode 100644 index 0000000..fea0c98 --- /dev/null +++ b/src/mmo/strs.hpp @@ -0,0 +1,126 @@ +#pragma once +// strs.hpp - common string types +// +// Copyright © ????-2004 Athena Dev Teams +// Copyright © 2004-2011 The Mana World Development Team +// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include "../strings/vstring.hpp" + + +namespace tmwa +{ +// affects CharName +#define NAME_IGNORING_CASE 1 + +struct AccountName : VString<23> {}; +struct AccountPass : VString<23> {}; +struct AccountCrypt : VString<39> {}; +struct AccountEmail : VString<39> {}; +struct ServerName : VString<19> {}; +struct PartyName : VString<23> {}; +struct VarName : VString<31> {}; + +#define DEFAULT_EMAIL stringish<AccountEmail>("a@a.com"_s) + +// It is decreed: a mapname shall not contain an extension +class MapName : public strings::_crtp_string<MapName, MapName, strings::ZPair> +{ + VString<15> _impl; +public: + MapName() = default; + MapName(VString<15> v) : _impl(v.xislice_h(std::find(v.begin(), v.end(), '.'))) {} + + iterator begin() const { return &*_impl.begin(); } + iterator end() const { return &*_impl.end(); } + const char *c_str() const { return _impl.c_str(); } + + operator RString() const { return _impl; } + operator AString() const { return _impl; } + operator TString() const { return _impl; } + operator SString() const { return _impl; } + operator ZString() const { return _impl; } + operator XString() const { return _impl; } +}; +template<> +inline +MapName stringish<MapName>(VString<15> iv) +{ + return iv; +} +inline +const char *decay_for_printf(const MapName& vs) { return vs.c_str(); } + +// It is decreed: a charname is sometimes case sensitive +struct CharName +{ +private: + VString<23> _impl; +public: + CharName() = default; + explicit CharName(VString<23> name) + : _impl(name) + {} + + VString<23> to__actual() const + { + return _impl; + } + VString<23> to__lower() const + { + return _impl.to_lower(); + } + VString<23> to__upper() const + { + return _impl.to_upper(); + } + VString<23> to__canonical() const + { +#if NAME_IGNORING_CASE == 0 + return to__actual(); +#endif +#if NAME_IGNORING_CASE == 1 + return to__lower(); +#endif + } + + friend bool operator == (const CharName& l, const CharName& r) + { return l.to__canonical() == r.to__canonical(); } + friend bool operator != (const CharName& l, const CharName& r) + { return l.to__canonical() != r.to__canonical(); } + friend bool operator < (const CharName& l, const CharName& r) + { return l.to__canonical() < r.to__canonical(); } + friend bool operator <= (const CharName& l, const CharName& r) + { return l.to__canonical() <= r.to__canonical(); } + friend bool operator > (const CharName& l, const CharName& r) + { return l.to__canonical() > r.to__canonical(); } + friend bool operator >= (const CharName& l, const CharName& r) + { return l.to__canonical() >= r.to__canonical(); } + + friend + VString<23> convert_for_printf(const CharName& vs) { return vs.to__actual(); } +}; +template<> +inline +CharName stringish<CharName>(VString<23> iv) +{ + return CharName(iv); +} +} // namespace tmwa diff --git a/src/mmo/utils.cpp b/src/mmo/utils.cpp index a1316d1..f8aff2e 100644 --- a/src/mmo/utils.cpp +++ b/src/mmo/utils.cpp @@ -20,12 +20,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <netinet/in.h> #include <sys/time.h> #include <algorithm> -#include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" @@ -36,6 +34,9 @@ #include "../poison.hpp" + +namespace tmwa +{ //--------------------------------------------------- // E-mail check: return 0 (not correct) or 1 (valid). //--------------------------------------------------- @@ -57,9 +58,9 @@ bool e_mail_check(XString email) return 0; if (hostname.front() == '.' || hostname.back() == '.') return 0; - if (hostname.contains_seq("..")) + if (hostname.contains_seq(".."_s)) return 0; - if (email.contains_any(" ;")) + if (email.contains_any(" ;"_s)) return 0; return email.is_print(); } @@ -70,18 +71,18 @@ bool e_mail_check(XString email) //------------------------------------------------- int config_switch(ZString str) { - if (str == "true" || str == "on" || str == "yes" - || str == "oui" || str == "ja" - || str == "si") + if (str == "true"_s || str == "on"_s || str == "yes"_s + || str == "oui"_s || str == "ja"_s + || str == "si"_s) return 1; - if (str == "false" || str == "off" || str == "no" - || str == "non" || str == "nein") + if (str == "false"_s || str == "off"_s || str == "no"_s + || str == "non"_s || str == "nein"_s) return 0; int rv; if (extract(str, &rv)) return rv; - FPRINTF(stderr, "Fatal: bad option value %s", str); + FPRINTF(stderr, "Fatal: bad option value %s"_fmt, str); abort(); } @@ -93,17 +94,17 @@ void stamp_time(timestamp_seconds_buffer& out, const TimeT *t) struct tm when = t ? *t : TimeT::now(); char buf[20]; strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &when); - out = stringish<timestamp_seconds_buffer>(const_(buf)); + out = stringish<timestamp_seconds_buffer>(VString<19>(strings::really_construct_from_a_pointer, buf)); } void stamp_time(timestamp_milliseconds_buffer& out) { struct timeval tv; - gettimeofday(&tv, NULL); + gettimeofday(&tv, nullptr); struct tm when = TimeT(tv.tv_sec); char buf[24]; strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &when); sprintf(buf + 19, ".%03d", static_cast<int>(tv.tv_usec / 1000)); - out = stringish<timestamp_milliseconds_buffer>(const_(buf)); + out = stringish<timestamp_milliseconds_buffer>(VString<23>(strings::really_construct_from_a_pointer, buf)); } void log_with_timestamp(io::WriteFile& out, XString line) @@ -119,3 +120,4 @@ void log_with_timestamp(io::WriteFile& out, XString line) out.really_put(": ", 2); out.put_line(line); } +} // namespace tmwa diff --git a/src/mmo/utils.hpp b/src/mmo/utils.hpp index d59f7ac..fc3ea74 100644 --- a/src/mmo/utils.hpp +++ b/src/mmo/utils.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MMO_UTILS_HPP -#define TMWA_MMO_UTILS_HPP +#pragma once // utils.hpp - Useful stuff that hasn't been categorized. // // Copyright © ????-2004 Athena Dev Teams @@ -21,19 +20,25 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdio> +#include <cstring> +#include <ctime> -# include <type_traits> +#include <type_traits> -# include "../strings/fwd.hpp" -# include "../strings/vstring.hpp" +#include "../ints/little.hpp" -# include "../generic/operators.hpp" +#include "../strings/fwd.hpp" +#include "../strings/vstring.hpp" -# include "../io/fwd.hpp" +#include "../generic/operators.hpp" +#include "../io/fwd.hpp" + + +namespace tmwa +{ template<class T> struct is_trivially_copyable : std::integral_constant<bool, @@ -82,7 +87,7 @@ struct TimeT : Comparable TimeT now() { // poisoned, but this is still in header-land - return time(NULL); + return time(nullptr); } bool error() const @@ -101,12 +106,40 @@ long long convert_for_printf(TimeT t) return t.value; } -inline -long long& convert_for_scanf(TimeT& t) +// 2038 problem +inline __attribute__((warn_unused_result)) +bool native_to_network(Little32 *net, TimeT nat) { - return t.value; + time_t tmp = nat; + return native_to_network(net, static_cast<uint32_t>(tmp)); +} + +inline __attribute__((warn_unused_result)) +bool network_to_native(TimeT *nat, Little32 net) +{ + uint32_t tmp; + bool rv = network_to_native(&tmp, net); + *nat = static_cast<time_t>(tmp); + return rv; } +inline __attribute__((warn_unused_result)) +bool native_to_network(Little64 *net, TimeT nat) +{ + time_t tmp = nat; + return native_to_network(net, static_cast<uint64_t>(tmp)); +} + +inline __attribute__((warn_unused_result)) +bool network_to_native(TimeT *nat, Little64 net) +{ + uint64_t tmp; + bool rv = network_to_native(&tmp, net); + *nat = static_cast<time_t>(tmp); + return rv; +} + + struct timestamp_seconds_buffer : VString<19> {}; struct timestamp_milliseconds_buffer : VString<23> {}; void stamp_time(timestamp_seconds_buffer&, const TimeT *t=nullptr); @@ -115,21 +148,20 @@ void stamp_time(timestamp_milliseconds_buffer&); void log_with_timestamp(io::WriteFile& out, XString line); // TODO VString? -# define TIMESTAMP_DUMMY "YYYY-MM-DD HH:MM:SS" +#define TIMESTAMP_DUMMY "YYYY-MM-DD HH:MM:SS" static_assert(sizeof(TIMESTAMP_DUMMY) == sizeof(timestamp_seconds_buffer), "timestamp size"); -# define WITH_TIMESTAMP(str) str TIMESTAMP_DUMMY +#define WITH_TIMESTAMP(str) str TIMESTAMP_DUMMY // str: prefix: YYYY-MM-DD HH:MM:SS // sizeof: 01234567890123456789012345678 // str + sizeof: ^ // -1: ^ // there's probably a better way to do this now -# define REPLACE_TIMESTAMP(str, t) \ +#define REPLACE_TIMESTAMP(str, t) \ stamp_time( \ reinterpret_cast<timestamp_seconds_buffer *>( \ str + sizeof(str) \ )[-1], \ &t \ ) - -#endif // TMWA_MMO_UTILS_HPP +} // namespace tmwa diff --git a/src/mmo/version.cpp b/src/mmo/version.cpp index 54b1709..2e337c1 100644 --- a/src/mmo/version.cpp +++ b/src/mmo/version.cpp @@ -28,6 +28,9 @@ #include "../poison.hpp" + +namespace tmwa +{ Version CURRENT_VERSION = { VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, @@ -61,7 +64,7 @@ Version CURRENT_MAP_SERVER_VERSION = VENDOR_POINT, }; -const char CURRENT_VERSION_STRING[] = VERSION_STRING; +LString CURRENT_VERSION_STRING = VERSION_STRING; bool extract(XString str, Version *vers) { @@ -70,3 +73,4 @@ bool extract(XString str, Version *vers) // It would've been useful during the magic migration. return extract(str, record<'.'>(&vers->major, &vers->minor, &vers->patch)); } +} // namespace tmwa diff --git a/src/mmo/version.hpp b/src/mmo/version.hpp index 11bab39..440dce6 100644 --- a/src/mmo/version.hpp +++ b/src/mmo/version.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MMO_VERSION_HPP -#define TMWA_MMO_VERSION_HPP +#pragma once // version.hpp - Prevent mass rebuild when conf/version.hpp changes. // // Copyright © ????-2004 Athena Dev Teams @@ -21,20 +20,24 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdint> +#include <cstdint> -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" + +namespace tmwa +{ // TODO make these bitwise enums -# define TMWA_FLAG_REGISTRATION 0x01 +#define TMWA_FLAG_REGISTRATION 0x01 -# define TMWA_SERVER_LOGIN 0x01 -# define TMWA_SERVER_CHAR 0x02 -# define TMWA_SERVER_INTER 0x04 -# define TMWA_SERVER_MAP 0x08 +#define TMWA_SERVER_LOGIN 0x01 +#define TMWA_SERVER_CHAR 0x02 +#define TMWA_SERVER_INTER 0x04 +#define TMWA_SERVER_MAP 0x08 +// TODO now that I generate the protocol, split 'flags' out of the struct struct Version { uint8_t major; @@ -46,6 +49,35 @@ struct Version uint8_t which; uint16_t vend; // can't add vendor name yet + + constexpr friend + bool operator < (Version l, Version r) + { + return (l.major < r.major + || (l.major == r.major + && (l.minor < r.minor + || (l.minor == r.minor + && (l.patch < r.patch + || (l.patch == r.patch + && (l.devel < r.devel + || (l.devel == r.devel + && l.vend < r.vend)))))))); + } + constexpr friend + bool operator > (Version l, Version r) + { + return r < l; + } + constexpr friend + bool operator <= (Version l, Version r) + { + return !(r < l); + } + constexpr friend + bool operator >= (Version l, Version r) + { + return !(l < r); + } }; static_assert(sizeof(Version) == 8, "this is sent over the network, can't change"); @@ -55,37 +87,7 @@ extern Version CURRENT_LOGIN_SERVER_VERSION; extern Version CURRENT_CHAR_SERVER_VERSION; extern Version CURRENT_MAP_SERVER_VERSION; -extern const char CURRENT_VERSION_STRING[]; +extern LString CURRENT_VERSION_STRING; bool extract(XString str, Version *vers); - -constexpr -bool operator < (Version l, Version r) -{ - return (l.major < r.major - || (l.major == r.major - && (l.minor < r.minor - || (l.minor == r.minor - && (l.patch < r.patch - || (l.patch == r.patch - && (l.devel < r.devel - || (l.devel == r.devel - && l.vend < r.vend)))))))); -} -constexpr -bool operator > (Version l, Version r) -{ - return r < l; -} -constexpr -bool operator <= (Version l, Version r) -{ - return !(r < l); -} -constexpr -bool operator >= (Version l, Version r) -{ - return !(l < r); -} - -#endif // TMWA_MMO_VERSION_HPP +} // namespace tmwa diff --git a/src/monitor/main.cpp b/src/monitor/main.cpp index c882105..ec1139a 100644 --- a/src/monitor/main.cpp +++ b/src/monitor/main.cpp @@ -24,11 +24,13 @@ #include <unistd.h> #include <csignal> +#include <cstdlib> #include "../strings/mstring.hpp" #include "../strings/astring.hpp" #include "../strings/zstring.hpp" #include "../strings/xstring.hpp" +#include "../strings/literal.hpp" #include "../io/cxxstdio.hpp" #include "../io/fd.hpp" @@ -39,12 +41,14 @@ #include "../poison.hpp" -#define LOGIN_SERVER "./login-server" -#define MAP_SERVER "./map-server" -#define CHAR_SERVER "./char-server" -#define CONFIG "conf/eathena-monitor.conf" +#define LOGIN_SERVER "./login-server"_s +#define MAP_SERVER "./map-server"_s +#define CHAR_SERVER "./char-server"_s +#define CONFIG "conf/eathena-monitor.conf"_s +namespace tmwa +{ // initialiized to $HOME/tmwserver static AString workdir; @@ -72,17 +76,17 @@ AString make_path(XString base, XString path) static bool parse_option(XString name, ZString value) { - if (name == "login_server") + if (name == "login_server"_s) login_server = value; - else if (name == "map_server") + else if (name == "map_server"_s) map_server = value; - else if (name == "char_server") + else if (name == "char_server"_s) char_server = value; - else if (name == "workdir") + else if (name == "workdir"_s) workdir = value; else { - FPRINTF(stderr, "WARNING: ingnoring invalid option '%s' : '%s'\n", + FPRINTF(stderr, "WARNING: ingnoring invalid option '%s' : '%s'\n"_fmt, AString(name), value); return false; } @@ -96,7 +100,7 @@ bool read_config(ZString filename) io::ReadFile in(filename); if (!in.is_open()) { - FPRINTF(stderr, "Monitor config file not found: %s\n", filename); + FPRINTF(stderr, "Monitor config file not found: %s\n"_fmt, filename); exit(1); } @@ -109,14 +113,14 @@ bool read_config(ZString filename) ZString value; if (!config_split(line, &name, &value)) { - PRINTF("Bad line: %s\n", line); + PRINTF("Bad line: %s\n"_fmt, line); rv = false; continue; } if (!parse_option(name, value)) { - PRINTF("Bad key/value: %s\n", line); + PRINTF("Bad key/value: %s\n"_fmt, line); rv = false; continue; } @@ -127,19 +131,19 @@ bool read_config(ZString filename) static pid_t start_process(ZString exec) { - const char *args[2] = {exec.c_str(), NULL}; + const char *args[2] = {exec.c_str(), nullptr}; pid_t pid = fork(); if (pid == -1) { - FPRINTF(stderr, "Failed to fork"); + FPRINTF(stderr, "Failed to fork"_fmt); return 0; } if (pid == 0) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-qual" + DIAG_PUSH(); + DIAG_I(cast_qual); execv(exec.c_str(), const_cast<char **>(args)); -#pragma GCC diagnostic pop + DIAG_POP(); perror("Failed to exec"); kill(getppid(), SIGABRT); exit(1); @@ -157,15 +161,18 @@ void stop_process(int sig) kill(pid_login, sig); if (pid_char) kill(pid_char, sig); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" + DIAG_PUSH(); + DIAG_I(old_style_cast); + DIAG_I(zero_as_null_pointer_constant); signal(sig, SIG_DFL); -#pragma GCC diagnostic pop + DIAG_POP(); raise(sig); } +} // namespace tmwa int main(int argc, char *argv[]) { + using namespace tmwa; // These are all the signals we are likely to get // The shell handles stop/cont signal(SIGTERM, stop_process); @@ -173,7 +180,7 @@ int main(int argc, char *argv[]) signal(SIGQUIT, stop_process); signal(SIGABRT, stop_process); - workdir = make_path(ZString(strings::really_construct_from_a_pointer, getenv("HOME"), nullptr), "tmwserver"); + workdir = make_path(ZString(strings::really_construct_from_a_pointer, getenv("HOME"), nullptr), "tmwserver"_s); ZString config = CONFIG; if (argc > 1) @@ -186,11 +193,11 @@ int main(int argc, char *argv[]) exit(1); } - PRINTF("Starting:\n"); - PRINTF("* workdir: %s\n", workdir); - PRINTF("* login_server: %s\n", login_server); - PRINTF("* char_server: %s\n", char_server); - PRINTF("* map_server: %s\n", map_server); + PRINTF("Starting:\n"_fmt); + PRINTF("* workdir: %s\n"_fmt, workdir); + PRINTF("* login_server: %s\n"_fmt, login_server); + PRINTF("* char_server: %s\n"_fmt, char_server); + PRINTF("* map_server: %s\n"_fmt, map_server); { //make sure all possible file descriptors are free for use by the servers //if there are file descriptors higher than the max open from before the limit dropped, that's not our problem @@ -198,9 +205,9 @@ int main(int argc, char *argv[]) while ((fd = fd.prev()) > io::FD::stderr()) { if (fd.close() == 0) - FPRINTF(stderr, "close fd %d\n", fd.uncast_dammit()); + FPRINTF(stderr, "close fd %d\n"_fmt, fd.uncast_dammit()); } - fd = io::FD::open("/dev/null", O_RDWR); + fd = io::FD::open("/dev/null"_s, O_RDWR); if (fd == io::FD()) { perror("open /dev/null"); @@ -219,22 +226,22 @@ int main(int argc, char *argv[]) if (!pid_login) { pid_login = start_process(login_server); - FPRINTF(stderr, "[%s] forked login server: %lu\n", + FPRINTF(stderr, "[%s] forked login server: %lu\n"_fmt, timestamp, static_cast<unsigned long>(pid_login)); } if (!pid_char) { pid_char = start_process(char_server); - FPRINTF(stderr, "[%s] forked char server: %lu\n", + FPRINTF(stderr, "[%s] forked char server: %lu\n"_fmt, timestamp, static_cast<unsigned long>(pid_char)); } if (!pid_map) { pid_map = start_process(map_server); - FPRINTF(stderr, "[%s] forked map server: %lu\n", + FPRINTF(stderr, "[%s] forked map server: %lu\n"_fmt, timestamp, static_cast<unsigned long>(pid_map)); } - pid_t dead = wait(NULL); + pid_t dead = wait(nullptr); if (dead == -1) { perror("Failed to wait for child"); diff --git a/src/net/fwd.hpp b/src/net/fwd.hpp new file mode 100644 index 0000000..2097772 --- /dev/null +++ b/src/net/fwd.hpp @@ -0,0 +1,33 @@ +#pragma once +// net/fwd.hpp - list of type names for net lib +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +class Session; + +class IP4Address; + +class TimerData; + +enum class RecvResult; +} // namespace tmwa diff --git a/src/mmo/ip.cpp b/src/net/ip.cpp index 146734a..bfc2028 100644 --- a/src/mmo/ip.cpp +++ b/src/net/ip.cpp @@ -23,8 +23,13 @@ #include "../io/cxxstdio.hpp" +#include "../mmo/extract.hpp" + #include "../poison.hpp" + +namespace tmwa +{ bool extract(XString str, IP4Address *rv) { if (str.endswith('.')) @@ -104,11 +109,12 @@ bool extract(XString str, IP4Mask *rv) VString<15> convert_for_printf(IP4Address a_) { const uint8_t *a = a_.bytes(); - return STRNPRINTF(16, "%hhu.%hhu.%hhu.%hhu", a[0], a[1], a[2], a[3]); + return STRNPRINTF(16, "%hhu.%hhu.%hhu.%hhu"_fmt, a[0], a[1], a[2], a[3]); } VString<31> convert_for_printf(IP4Mask a) { - return STRNPRINTF(32, "%s/%s", + return STRNPRINTF(32, "%s/%s"_fmt, a.addr(), a.mask()); } +} // namespace tmwa diff --git a/src/mmo/ip.hpp b/src/net/ip.hpp index a425710..e9e71f4 100644 --- a/src/mmo/ip.hpp +++ b/src/net/ip.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MMO_IP_HPP -#define TMWA_MMO_IP_HPP +#pragma once // ip.hpp - classes to deal with IP addresses. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,14 +18,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <netinet/in.h> +#include <netinet/in.h> -# include "../strings/fwd.hpp" +#include <cstddef> +#include <cstdint> -# include "extract.hpp" +#include "../strings/fwd.hpp" + +namespace tmwa +{ // TODO - in the long run ports belong here also // and of course, IPv6 stuff. // But what about unix socket addresses? @@ -160,5 +163,4 @@ VString<31> convert_for_printf(IP4Mask m); bool extract(XString str, IP4Address *iv); bool extract(XString str, IP4Mask *iv); - -#endif // TMWA_MMO_IP_HPP +} // namespace tmwa diff --git a/src/mmo/ip.py b/src/net/ip.py index e6a8183..bcf90a2 100644 --- a/src/mmo/ip.py +++ b/src/net/ip.py @@ -2,7 +2,7 @@ class IP4Address(object): ''' print an IP4Address ''' __slots__ = ('_value') - name = 'IP4Address' + name = 'tmwa::IP4Address' enabled = True def __init__(self, value): diff --git a/src/net/ip_test.cpp b/src/net/ip_test.cpp new file mode 100644 index 0000000..419dc03 --- /dev/null +++ b/src/net/ip_test.cpp @@ -0,0 +1,359 @@ +#include "ip.hpp" +// ip_test.cpp - Testsuite for implementation of IP address functions. +// +// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <gtest/gtest.h> + +#include "../strings/vstring.hpp" +#include "../strings/literal.hpp" + +#include "../io/cxxstdio.hpp" + +#include "../poison.hpp" + + +namespace tmwa +{ +#define CB(X) (std::integral_constant<bool, (X)>::value) +TEST(ip4addr, cmp) +{ + constexpr static + IP4Address a = IP4_LOCALHOST; + constexpr static + IP4Address b = IP4_BROADCAST; + + EXPECT_FALSE(CB(a < a)); + EXPECT_TRUE (CB(a < b)); + EXPECT_FALSE(CB(b < a)); + EXPECT_FALSE(CB(b < b)); + + EXPECT_FALSE(CB(a > a)); + EXPECT_FALSE(CB(a > b)); + EXPECT_TRUE (CB(b > a)); + EXPECT_FALSE(CB(b > b)); + + EXPECT_TRUE (CB(a <= a)); + EXPECT_TRUE (CB(a <= b)); + EXPECT_FALSE(CB(b <= a)); + EXPECT_TRUE (CB(b <= b)); + + EXPECT_TRUE (CB(a >= a)); + EXPECT_FALSE(CB(a >= b)); + EXPECT_TRUE (CB(b >= a)); + EXPECT_TRUE (CB(b >= b)); + + EXPECT_TRUE (CB(a == a)); + EXPECT_FALSE(CB(a == b)); + EXPECT_FALSE(CB(b == a)); + EXPECT_TRUE (CB(b == b)); + + EXPECT_FALSE(CB(a != a)); + EXPECT_TRUE (CB(a != b)); + EXPECT_TRUE (CB(b != a)); + EXPECT_FALSE(CB(b != b)); +} + +TEST(ip4addr, str) +{ + IP4Address a; + EXPECT_EQ("0.0.0.0"_s, STRNPRINTF(17, "%s"_fmt, a)); + EXPECT_EQ("127.0.0.1"_s, STRNPRINTF(17, "%s"_fmt, IP4_LOCALHOST)); + EXPECT_EQ("255.255.255.255"_s, STRNPRINTF(17, "%s"_fmt, IP4_BROADCAST)); +} + +TEST(ip4addr, extract) +{ + IP4Address a; + EXPECT_TRUE(extract("0.0.0.0"_s, &a)); + EXPECT_EQ("0.0.0.0"_s, STRNPRINTF(16, "%s"_fmt, a)); + EXPECT_TRUE(extract("127.0.0.1"_s, &a)); + EXPECT_EQ("127.0.0.1"_s, STRNPRINTF(16, "%s"_fmt, a)); + EXPECT_TRUE(extract("255.255.255.255"_s, &a)); + EXPECT_EQ("255.255.255.255"_s, STRNPRINTF(16, "%s"_fmt, a)); + EXPECT_TRUE(extract("1.2.3.4"_s, &a)); + EXPECT_EQ("1.2.3.4"_s, STRNPRINTF(16, "%s"_fmt, a)); + + EXPECT_FALSE(extract("1.2.3.4.5"_s, &a)); + EXPECT_FALSE(extract("1.2.3.4."_s, &a)); + EXPECT_FALSE(extract("1.2.3."_s, &a)); + EXPECT_FALSE(extract("1.2.3"_s, &a)); + EXPECT_FALSE(extract("1.2."_s, &a)); + EXPECT_FALSE(extract("1.2"_s, &a)); + EXPECT_FALSE(extract("1."_s, &a)); + EXPECT_FALSE(extract("1"_s, &a)); + EXPECT_FALSE(extract(""_s, &a)); +} + + +TEST(ip4mask, body) +{ + IP4Mask m; + EXPECT_EQ(IP4Address(), m.addr()); + EXPECT_EQ(IP4Address(), m.mask()); + m = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST); + EXPECT_EQ(IP4_LOCALHOST, m.addr()); + EXPECT_EQ(IP4_BROADCAST, m.mask()); +} + +TEST(ip4mask, str) +{ + IP4Mask m; + EXPECT_EQ("0.0.0.0/0.0.0.0"_s, STRNPRINTF(33, "%s"_fmt, m)); + m = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST); + EXPECT_EQ("127.0.0.1/255.255.255.255"_s, STRNPRINTF(33, "%s"_fmt, m)); +} + +TEST(ip4mask, extract) +{ + IP4Mask m; + EXPECT_FALSE(extract("9.8.7.6/33"_s, &m)); + EXPECT_FALSE(extract("9.8.7.6.5"_s, &m)); + EXPECT_FALSE(extract("9.8.7.6/"_s, &m)); + EXPECT_FALSE(extract("9.8.7"_s, &m)); + EXPECT_FALSE(extract("9.8"_s, &m)); + EXPECT_FALSE(extract("9"_s, &m)); + + EXPECT_TRUE(extract("127.0.0.1"_s, &m)); + EXPECT_EQ("127.0.0.1/255.255.255.255"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("127.0.0.1."_s, &m)); + EXPECT_EQ("127.0.0.1/255.255.255.255"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("127.0.0."_s, &m)); + EXPECT_EQ("127.0.0.0/255.255.255.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("127.0."_s, &m)); + EXPECT_EQ("127.0.0.0/255.255.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("127."_s, &m)); + EXPECT_EQ("127.0.0.0/255.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + + EXPECT_TRUE(extract("1.2.3.4/255.255.255.255"_s, &m)); + EXPECT_EQ("1.2.3.4/255.255.255.255"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("1.2.3.0/255.255.255.0"_s, &m)); + EXPECT_EQ("1.2.3.0/255.255.255.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("1.2.0.4/255.255.0.255"_s, &m)); + EXPECT_EQ("1.2.0.4/255.255.0.255"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("1.2.0.0/255.255.0.0"_s, &m)); + EXPECT_EQ("1.2.0.0/255.255.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("1.0.3.4/255.0.255.255"_s, &m)); + EXPECT_EQ("1.0.3.4/255.0.255.255"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("1.0.3.0/255.0.255.0"_s, &m)); + EXPECT_EQ("1.0.3.0/255.0.255.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("1.0.0.4/255.0.0.255"_s, &m)); + EXPECT_EQ("1.0.0.4/255.0.0.255"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("1.0.0.0/255.0.0.0"_s, &m)); + EXPECT_EQ("1.0.0.0/255.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.2.3.4/0.255.255.255"_s, &m)); + EXPECT_EQ("0.2.3.4/0.255.255.255"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.2.3.0/0.255.255.0"_s, &m)); + EXPECT_EQ("0.2.3.0/0.255.255.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.2.0.4/0.255.0.255"_s, &m)); + EXPECT_EQ("0.2.0.4/0.255.0.255"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.2.0.0/0.255.0.0"_s, &m)); + EXPECT_EQ("0.2.0.0/0.255.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.3.4/0.0.255.255"_s, &m)); + EXPECT_EQ("0.0.3.4/0.0.255.255"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.3.0/0.0.255.0"_s, &m)); + EXPECT_EQ("0.0.3.0/0.0.255.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.4/0.0.0.255"_s, &m)); + EXPECT_EQ("0.0.0.4/0.0.0.255"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/0.0.0.0"_s, &m)); + EXPECT_EQ("0.0.0.0/0.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + + // please don't do this + EXPECT_TRUE(extract("120.248.200.217/89.57.126.5"_s, &m)); + EXPECT_EQ("88.56.72.1/89.57.126.5"_s, STRNPRINTF(32, "%s"_fmt, m)); + + EXPECT_TRUE(extract("0.0.0.0/32"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.255.255"_s, STRNPRINTF(32, "%s"_fmt, m)); + + EXPECT_TRUE(extract("0.0.0.0/31"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.255.254"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/30"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.255.252"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/29"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.255.248"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/28"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.255.240"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/27"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.255.224"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/26"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.255.192"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/25"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.255.128"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/24"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.255.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + + EXPECT_TRUE(extract("0.0.0.0/23"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.254.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/22"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.252.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/21"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.248.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/20"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.240.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/19"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.224.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/18"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.192.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/17"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.128.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/16"_s, &m)); + EXPECT_EQ("0.0.0.0/255.255.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + + EXPECT_TRUE(extract("0.0.0.0/15"_s, &m)); + EXPECT_EQ("0.0.0.0/255.254.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/14"_s, &m)); + EXPECT_EQ("0.0.0.0/255.252.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/13"_s, &m)); + EXPECT_EQ("0.0.0.0/255.248.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/12"_s, &m)); + EXPECT_EQ("0.0.0.0/255.240.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/11"_s, &m)); + EXPECT_EQ("0.0.0.0/255.224.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/10"_s, &m)); + EXPECT_EQ("0.0.0.0/255.192.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/9"_s, &m)); + EXPECT_EQ("0.0.0.0/255.128.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/8"_s, &m)); + EXPECT_EQ("0.0.0.0/255.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + + EXPECT_TRUE(extract("0.0.0.0/7"_s, &m)); + EXPECT_EQ("0.0.0.0/254.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/6"_s, &m)); + EXPECT_EQ("0.0.0.0/252.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/5"_s, &m)); + EXPECT_EQ("0.0.0.0/248.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/4"_s, &m)); + EXPECT_EQ("0.0.0.0/240.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/3"_s, &m)); + EXPECT_EQ("0.0.0.0/224.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/2"_s, &m)); + EXPECT_EQ("0.0.0.0/192.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/1"_s, &m)); + EXPECT_EQ("0.0.0.0/128.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); + EXPECT_TRUE(extract("0.0.0.0/0"_s, &m)); + EXPECT_EQ("0.0.0.0/0.0.0.0"_s, STRNPRINTF(32, "%s"_fmt, m)); +} + +TEST(ip4mask, cover) +{ + IP4Address a; + IP4Address b = IP4_BROADCAST; + IP4Address l = IP4_LOCALHOST; + IP4Address h({127, 255, 255, 255}); + IP4Address p24l({10, 0, 0, 0}); + IP4Address p24h({10, 255, 255, 255}); + IP4Address p20l({172, 16, 0, 0}); + IP4Address p20h({172, 31, 255, 255}); + IP4Address p16l({192, 168, 0, 0}); + IP4Address p16h({192, 168, 255, 255}); + IP4Mask m; + EXPECT_TRUE(m.covers(a)); + EXPECT_TRUE(m.covers(b)); + EXPECT_TRUE(m.covers(l)); + EXPECT_TRUE(m.covers(h)); + EXPECT_TRUE(m.covers(p24l)); + EXPECT_TRUE(m.covers(p24h)); + EXPECT_TRUE(m.covers(p20l)); + EXPECT_TRUE(m.covers(p20h)); + EXPECT_TRUE(m.covers(p16l)); + EXPECT_TRUE(m.covers(p16h)); + m = IP4Mask(l, a); + EXPECT_TRUE(m.covers(a)); + EXPECT_TRUE(m.covers(b)); + EXPECT_TRUE(m.covers(l)); + EXPECT_TRUE(m.covers(h)); + EXPECT_TRUE(m.covers(p24l)); + EXPECT_TRUE(m.covers(p24h)); + EXPECT_TRUE(m.covers(p20l)); + EXPECT_TRUE(m.covers(p20h)); + EXPECT_TRUE(m.covers(p16l)); + EXPECT_TRUE(m.covers(p16h)); + m = IP4Mask(l, b); + EXPECT_FALSE(m.covers(a)); + EXPECT_FALSE(m.covers(b)); + EXPECT_TRUE(m.covers(l)); + EXPECT_FALSE(m.covers(h)); + EXPECT_FALSE(m.covers(p24l)); + EXPECT_FALSE(m.covers(p24h)); + EXPECT_FALSE(m.covers(p20l)); + EXPECT_FALSE(m.covers(p20h)); + EXPECT_FALSE(m.covers(p16l)); + EXPECT_FALSE(m.covers(p16h)); + + // but the really useful ones are with partial masks + m = IP4Mask(IP4Address({10, 0, 0, 0}), IP4Address({255, 0, 0, 0})); + EXPECT_FALSE(m.covers(a)); + EXPECT_FALSE(m.covers(b)); + EXPECT_FALSE(m.covers(l)); + EXPECT_FALSE(m.covers(h)); + EXPECT_TRUE(m.covers(p24l)); + EXPECT_TRUE(m.covers(p24h)); + EXPECT_FALSE(m.covers(p20l)); + EXPECT_FALSE(m.covers(p20h)); + EXPECT_FALSE(m.covers(p16l)); + EXPECT_FALSE(m.covers(p16h)); + EXPECT_FALSE(m.covers(IP4Address({9, 255, 255, 255}))); + EXPECT_FALSE(m.covers(IP4Address({11, 0, 0, 0}))); + m = IP4Mask(IP4Address({127, 0, 0, 0}), IP4Address({255, 0, 0, 0})); + EXPECT_FALSE(m.covers(a)); + EXPECT_FALSE(m.covers(b)); + EXPECT_TRUE(m.covers(l)); + EXPECT_TRUE(m.covers(h)); + EXPECT_FALSE(m.covers(p24l)); + EXPECT_FALSE(m.covers(p24h)); + EXPECT_FALSE(m.covers(p20l)); + EXPECT_FALSE(m.covers(p20h)); + EXPECT_FALSE(m.covers(p16l)); + EXPECT_FALSE(m.covers(p16h)); + EXPECT_FALSE(m.covers(IP4Address({126, 255, 255, 255}))); + EXPECT_FALSE(m.covers(IP4Address({128, 0, 0, 0}))); + m = IP4Mask(IP4Address({172, 16, 0, 0}), IP4Address({255, 240, 0, 0})); + EXPECT_FALSE(m.covers(a)); + EXPECT_FALSE(m.covers(b)); + EXPECT_FALSE(m.covers(l)); + EXPECT_FALSE(m.covers(h)); + EXPECT_FALSE(m.covers(p24l)); + EXPECT_FALSE(m.covers(p24h)); + EXPECT_TRUE(m.covers(p20l)); + EXPECT_TRUE(m.covers(p20h)); + EXPECT_FALSE(m.covers(p16l)); + EXPECT_FALSE(m.covers(p16h)); + EXPECT_FALSE(m.covers(IP4Address({172, 15, 255, 255}))); + EXPECT_FALSE(m.covers(IP4Address({172, 32, 0, 0}))); + m = IP4Mask(IP4Address({192, 168, 0, 0}), IP4Address({255, 255, 0, 0})); + EXPECT_FALSE(m.covers(a)); + EXPECT_FALSE(m.covers(b)); + EXPECT_FALSE(m.covers(l)); + EXPECT_FALSE(m.covers(h)); + EXPECT_FALSE(m.covers(p24l)); + EXPECT_FALSE(m.covers(p24h)); + EXPECT_FALSE(m.covers(p20l)); + EXPECT_FALSE(m.covers(p20h)); + EXPECT_TRUE(m.covers(p16l)); + EXPECT_TRUE(m.covers(p16h)); + EXPECT_FALSE(m.covers(IP4Address({192, 167, 255, 255}))); + EXPECT_FALSE(m.covers(IP4Address({192, 169, 0, 0}))); + + // OTOH this is crazy + EXPECT_TRUE(extract("120.248.200.217/89.57.126.5"_s, &m)); + EXPECT_TRUE(m.covers(IP4Address({120, 248, 200, 217}))); + EXPECT_TRUE(m.covers(IP4Address({88, 56, 72, 1}))); + EXPECT_FALSE(m.covers(IP4Address({88, 56, 72, 0}))); + EXPECT_FALSE(m.covers(IP4Address({88, 56, 72, 255}))); +} +} // namespace tmwa diff --git a/src/net/packets.cpp b/src/net/packets.cpp new file mode 100644 index 0000000..3cba856 --- /dev/null +++ b/src/net/packets.cpp @@ -0,0 +1,106 @@ +#include "packets.hpp" +// packets.cpp - palatable socket buffer accessors +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../io/cxxstdio.hpp" +#include "../io/write.hpp" + +#include "../poison.hpp" + + +namespace tmwa +{ +size_t packet_avail(Session *s) +{ + return s->rdata_size - s->rdata_pos; +} + +bool packet_fetch(Session *s, size_t offset, Byte *data, size_t sz) +{ + if (packet_avail(s) < offset + sz) + return false; + const Byte *start = reinterpret_cast<const Byte *>(&s->rdata[s->rdata_pos + offset]); + const Byte *end = start + sz; + std::copy(start, end, data); + return true; +} +void packet_discard(Session *s, size_t sz) +{ + s->rdata_pos += sz; + + assert (s->rdata_size >= s->rdata_pos); +} +bool packet_send(Session *s, const Byte *data, size_t sz) +{ + if (s->wdata_size + sz > s->max_wdata) + { + realloc_fifo(s, s->max_rdata, s->max_wdata << 1); + PRINTF("socket: %d wdata expanded to %zu bytes.\n"_fmt, s, s->max_wdata); + } + if (!s->max_wdata || !s->wdata) + { + return false; + } + s->wdata_size += sz; + + Byte *end = reinterpret_cast<Byte *>(&s->wdata[s->wdata_size + 0]); + Byte *start = end - sz; + std::copy(data, data + sz, start); + return true; +} + +void packet_dump(io::WriteFile& logfp, Session *s) +{ + FPRINTF(logfp, + "---- 00-01-02-03-04-05-06-07 08-09-0A-0B-0C-0D-0E-0F\n"_fmt); + char tmpstr[16 + 1] {}; + int i; + for (i = 0; i < packet_avail(s); i++) + { + if ((i & 15) == 0) + FPRINTF(logfp, "%04X "_fmt, i); + Byte rfifob_ib; + packet_fetch(s, i, &rfifob_ib, 1); + uint8_t rfifob_i = rfifob_ib.value; + FPRINTF(logfp, "%02x "_fmt, rfifob_i); + if (rfifob_i > 0x1f) + tmpstr[i % 16] = rfifob_i; + else + tmpstr[i % 16] = '.'; + if ((i - 7) % 16 == 0) // -8 + 1 + FPRINTF(logfp, " "_fmt); + else if ((i + 1) % 16 == 0) + { + FPRINTF(logfp, " %s\n"_fmt, tmpstr); + std::fill(tmpstr + 0, tmpstr + 17, '\0'); + } + } + if (i % 16 != 0) + { + for (int j = i; j % 16 != 0; j++) + { + FPRINTF(logfp, " "_fmt); + if ((j - 7) % 16 == 0) // -8 + 1 + FPRINTF(logfp, " "_fmt); + } + FPRINTF(logfp, " %s\n"_fmt, tmpstr); + } + FPRINTF(logfp, "\n"_fmt); +} +} // namespace tmwa diff --git a/src/net/packets.hpp b/src/net/packets.hpp new file mode 100644 index 0000000..5cc377c --- /dev/null +++ b/src/net/packets.hpp @@ -0,0 +1,585 @@ +#pragma once +// packets.hpp - palatable socket buffer accessors +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include <vector> + +#include "../compat/cast.hpp" + +#include "../ints/little.hpp" + +#include "../io/fwd.hpp" + +// TODO ordering violation, should invert +#include "../proto2/fwd.hpp" + +#include "socket.hpp" + + +namespace tmwa +{ +struct Buffer +{ + std::vector<Byte> bytes; +}; + +enum class RecvResult +{ + Incomplete, + Complete, + Error, +}; + +enum class SendResult +{ + Success, + Fail, +}; + + +size_t packet_avail(Session *s); +void packet_dump(io::WriteFile& out, Session *s); + +bool packet_fetch(Session *s, size_t offset, Byte *data, size_t sz); +void packet_discard(Session *s, size_t sz); +bool packet_send(Session *s, const Byte *data, size_t sz); + +inline +bool packet_peek_id(Session *s, uint16_t *packet_id) +{ + Little16 id; + bool okay = packet_fetch(s, 0, reinterpret_cast<Byte *>(&id), 2); + if (okay) + { + if (!network_to_native(packet_id, id)) + { + s->set_eof(); + return false; + } + } + return okay; +} + +inline +void send_buffer(Session *s, const Buffer& buffer) +{ + bool ok = !buffer.bytes.empty() && packet_send(s, buffer.bytes.data(), buffer.bytes.size()); + if (!ok) + s->set_eof(); +} + +template<uint16_t id> +__attribute__((warn_unused_result)) +RecvResult net_recv_fpacket(Session *s, NetPacket_Fixed<id>& fixed) +{ + bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&fixed), sizeof(NetPacket_Fixed<id>)); + if (ok) + { + packet_discard(s, sizeof(NetPacket_Fixed<id>)); + return RecvResult::Complete; + } + return RecvResult::Incomplete; +} + +template<uint16_t id> +__attribute__((warn_unused_result)) +RecvResult net_recv_ppacket(Session *s, NetPacket_Payload<id>& payload) +{ + bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&payload), sizeof(NetPacket_Payload<id>)); + if (ok) + { + packet_discard(s, sizeof(NetPacket_Payload<id>)); + return RecvResult::Complete; + } + return RecvResult::Incomplete; +} + +template<uint16_t id> +__attribute__((warn_unused_result)) +RecvResult net_recv_vpacket(Session *s, NetPacket_Head<id>& head, std::vector<NetPacket_Repeat<id>>& repeat) +{ + bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&head), sizeof(NetPacket_Head<id>)); + if (ok) + { + Packet_Head<id> nat; + if (!network_to_native(&nat, head)) + return RecvResult::Error; + if (packet_avail(s) < nat.magic_packet_length) + return RecvResult::Incomplete; + if (nat.magic_packet_length < sizeof(NetPacket_Head<id>)) + return RecvResult::Error; + size_t bytes_repeat = nat.magic_packet_length - sizeof(NetPacket_Head<id>); + if (bytes_repeat % sizeof(NetPacket_Repeat<id>)) + return RecvResult::Error; + repeat.resize(bytes_repeat / sizeof(NetPacket_Repeat<id>)); + if (packet_fetch(s, sizeof(NetPacket_Head<id>), reinterpret_cast<Byte *>(repeat.data()), bytes_repeat)) + { + packet_discard(s, nat.magic_packet_length); + return RecvResult::Complete; + } + return RecvResult::Incomplete; + } + return RecvResult::Incomplete; +} + +template<uint16_t id> +__attribute__((warn_unused_result)) +RecvResult net_recv_opacket(Session *s, NetPacket_Head<id>& head, bool *has_opt, NetPacket_Option<id>& opt) +{ + bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&head), sizeof(NetPacket_Head<id>)); + if (ok) + { + Packet_Head<id> nat; + if (!network_to_native(&nat, head)) + return RecvResult::Error; + if (packet_avail(s) < nat.magic_packet_length) + return RecvResult::Incomplete; + if (nat.magic_packet_length < sizeof(NetPacket_Head<id>)) + return RecvResult::Error; + size_t bytes_repeat = nat.magic_packet_length - sizeof(NetPacket_Head<id>); + if (bytes_repeat % sizeof(NetPacket_Option<id>)) + return RecvResult::Error; + size_t has_opt_pls = bytes_repeat / sizeof(NetPacket_Option<id>); + if (has_opt_pls > 1) + return RecvResult::Error; + *has_opt = has_opt_pls; + if (!*has_opt || packet_fetch(s, sizeof(NetPacket_Head<id>), reinterpret_cast<Byte *>(&opt), sizeof(NetPacket_Option<id>))) + { + packet_discard(s, nat.magic_packet_length); + return RecvResult::Complete; + } + return RecvResult::Incomplete; + } + return RecvResult::Incomplete; +} + + +template<uint16_t id, uint16_t size> +Buffer create_fpacket(const Packet_Fixed<id>& fixed) +{ + static_assert(id == Packet_Fixed<id>::PACKET_ID, "Packet_Fixed<id>::PACKET_ID"); + static_assert(size == sizeof(NetPacket_Fixed<id>), "sizeof(NetPacket_Fixed<id>)"); + + Buffer buf; + buf.bytes.resize(sizeof(NetPacket_Fixed<id>)); + auto& net_fixed = reinterpret_cast<NetPacket_Fixed<id>&>( + *(buf.bytes.begin() + 0)); + if (!native_to_network(&net_fixed, fixed)) + { + return Buffer(); + } + return buf; +} + +template<uint16_t id> +Buffer create_ppacket(Packet_Payload<id>& payload) +{ + static_assert(id == Packet_Payload<id>::PACKET_ID, "Packet_Payload<id>::PACKET_ID"); + + if (id != 0x8000) + payload.magic_packet_length = sizeof(NetPacket_Payload<id>); + + Buffer buf; + buf.bytes.resize(sizeof(NetPacket_Payload<id>)); + auto& net_payload = reinterpret_cast<NetPacket_Payload<id>&>( + *(buf.bytes.begin() + 0)); + if (!native_to_network(&net_payload, payload)) + { + return Buffer(); + } + return buf; +} + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +Buffer create_vpacket(Packet_Head<id>& head, const std::vector<Packet_Repeat<id>>& repeat) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "sizeof(NetPacket_Head<id>)"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "sizeof(NetPacket_Repeat<id>)"); + + // since these are already allocated, can't overflow address space + size_t total_size = sizeof(NetPacket_Head<id>) + repeat.size() * sizeof(NetPacket_Repeat<id>); + // truncates + head.magic_packet_length = total_size; + if (head.magic_packet_length != total_size) + { + return Buffer(); + } + + Buffer buf; + buf.bytes.resize(total_size); + auto& net_head = reinterpret_cast<NetPacket_Head<id>&>( + *(buf.bytes.begin() + 0)); + if (!native_to_network(&net_head, head)) + { + return Buffer(); + } + for (size_t i = 0; i < repeat.size(); ++i) + { + auto& net_repeat_i = reinterpret_cast<NetPacket_Repeat<id>&>( + *(buf.bytes.begin() + + sizeof(NetPacket_Head<id>) + + i * sizeof(NetPacket_Repeat<id>))); + if (!native_to_network(&net_repeat_i, repeat[i])) + { + return Buffer(); + } + } + return buf; +} + +template<uint16_t id, uint16_t headsize, uint16_t optsize> +Buffer create_opacket(Packet_Head<id>& head, bool has_opt, const Packet_Option<id>& opt) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "sizeof(NetPacket_Head<id>)"); + static_assert(id == Packet_Option<id>::PACKET_ID, "Packet_Option<id>::PACKET_ID"); + static_assert(optsize == sizeof(NetPacket_Option<id>), "sizeof(NetPacket_Option<id>)"); + + // since these are already allocated, can't overflow address space + size_t total_size = sizeof(NetPacket_Head<id>) + has_opt * sizeof(NetPacket_Option<id>); + // truncates + head.magic_packet_length = total_size; + if (head.magic_packet_length != total_size) + { + return Buffer(); + } + + Buffer buf; + buf.bytes.resize(total_size); + + auto& net_head = reinterpret_cast<NetPacket_Head<id>&>( + *(buf.bytes.begin() + 0)); + if (!native_to_network(&net_head, head)) + { + return Buffer(); + } + if (has_opt) + { + auto& net_opt = reinterpret_cast<NetPacket_Option<id>&>( + *(buf.bytes.begin() + + sizeof(NetPacket_Head<id>))); + if (!native_to_network(&net_opt, opt)) + { + return Buffer(); + } + } + + return buf; +} + +template<uint16_t id, uint16_t size> +void send_fpacket(Session *s, const Packet_Fixed<id>& fixed) +{ + Buffer pkt = create_fpacket<id, size>(fixed); + send_buffer(s, pkt); +} + +template<uint16_t id> +void send_ppacket(Session *s, Packet_Payload<id>& payload) +{ + Buffer pkt = create_ppacket<id>(payload); + send_buffer(s, pkt); +} + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +void send_vpacket(Session *s, Packet_Head<id>& head, const std::vector<Packet_Repeat<id>>& repeat) +{ + Buffer pkt = create_vpacket<id, headsize, repeatsize>(head, repeat); + send_buffer(s, pkt); +} + +template<uint16_t id, uint16_t headsize, uint16_t optsize> +void send_opacket(Session *s, Packet_Head<id>& head, bool has_opt, const Packet_Option<id>& opt) +{ + Buffer pkt = create_opacket<id, headsize, optsize>(head, has_opt, opt); + send_buffer(s, pkt); +} + +template<uint16_t id, uint16_t size> +__attribute__((warn_unused_result)) +RecvResult recv_fpacket(Session *s, Packet_Fixed<id>& fixed) +{ + static_assert(id == Packet_Fixed<id>::PACKET_ID, "Packet_Fixed<id>::PACKET_ID"); + static_assert(size == sizeof(NetPacket_Fixed<id>), "NetPacket_Fixed<id>"); + + NetPacket_Fixed<id> net_fixed; + RecvResult rv = net_recv_fpacket(s, net_fixed); + if (rv == RecvResult::Complete) + { + if (!network_to_native(&fixed, net_fixed)) + return RecvResult::Error; + assert (fixed.magic_packet_id == Packet_Fixed<id>::PACKET_ID); + } + return rv; +} + +template<uint16_t id> +__attribute__((warn_unused_result)) +RecvResult recv_ppacket(Session *s, Packet_Payload<id>& payload) +{ + static_assert(id == Packet_Payload<id>::PACKET_ID, "Packet_Payload<id>::PACKET_ID"); + + NetPacket_Payload<id> net_payload; + RecvResult rv = net_recv_ppacket(s, net_payload); + if (rv == RecvResult::Complete) + { + if (!network_to_native(&payload, net_payload)) + return RecvResult::Error; + assert (payload.magic_packet_id == Packet_Payload<id>::PACKET_ID); + if (id == 0x8000) + { + // 0x8000 is special + if (packet_avail(s) < payload.magic_packet_length) + return RecvResult::Incomplete; + payload.magic_packet_length = 4; + return RecvResult::Complete; + } + if (payload.magic_packet_length != sizeof(net_payload)) + return RecvResult::Error; + } + return rv; +} + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +__attribute__((warn_unused_result)) +RecvResult recv_vpacket(Session *s, Packet_Head<id>& head, std::vector<Packet_Repeat<id>>& repeat) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "NetPacket_Head<id>"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "NetPacket_Repeat<id>"); + + NetPacket_Head<id> net_head; + std::vector<NetPacket_Repeat<id>> net_repeat; + RecvResult rv = net_recv_vpacket(s, net_head, net_repeat); + if (rv == RecvResult::Complete) + { + if (!network_to_native(&head, net_head)) + return RecvResult::Error; + assert (head.magic_packet_id == Packet_Head<id>::PACKET_ID); + + repeat.resize(net_repeat.size()); + for (size_t i = 0; i < net_repeat.size(); ++i) + { + if (!network_to_native(&repeat[i], net_repeat[i])) + return RecvResult::Error; + } + } + return rv; +} + +template<uint16_t id, uint16_t headsize, uint16_t optsize> +__attribute__((warn_unused_result)) +RecvResult recv_opacket(Session *s, Packet_Head<id>& head, bool *has_opt, Packet_Option<id>& opt) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "NetPacket_Head<id>"); + static_assert(id == Packet_Option<id>::PACKET_ID, "Packet_Option<id>::PACKET_ID"); + static_assert(optsize == sizeof(NetPacket_Option<id>), "NetPacket_Option<id>"); + + NetPacket_Head<id> net_head; + NetPacket_Option<id> net_opt; + RecvResult rv = net_recv_opacket(s, net_head, has_opt, net_opt); + if (rv == RecvResult::Complete) + { + if (!network_to_native(&head, net_head)) + return RecvResult::Error; + assert (head.magic_packet_id == Packet_Head<id>::PACKET_ID); + + if (*has_opt) + { + if (!network_to_native(&opt, net_opt)) + return RecvResult::Error; + } + } + return rv; +} + + +// convenience for trailing strings + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +Buffer create_vpacket(Packet_Head<id>& head, const XString& repeat) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "NetPacket_Head<id>"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "NetPacket_Repeat<id>"); + static_assert(repeatsize == 1, "repeatsize"); + + // since it's already allocated, it can't overflow address space + size_t total_length = sizeof(NetPacket_Head<id>) + (repeat.size() + 1) * sizeof(NetPacket_Repeat<id>); + head.magic_packet_length = total_length; + if (head.magic_packet_length != total_length) + { + return Buffer(); + } + + Buffer buf; + buf.bytes.resize(total_length); + auto& net_head = reinterpret_cast<NetPacket_Head<id>&>( + *(buf.bytes.begin() + 0)); + std::vector<NetPacket_Repeat<id>> net_repeat(repeat.size() + 1); + if (!native_to_network(&net_head, head)) + { + return Buffer(); + } + for (size_t i = 0; i < repeat.size(); ++i) + { + auto& net_repeat_i = reinterpret_cast<NetPacket_Repeat<id>&>( + *(buf.bytes.begin() + + sizeof(NetPacket_Head<id>) + + i)); + net_repeat_i.c = Byte{static_cast<uint8_t>(repeat[i])}; + } + auto& net_repeat_repeat_size = reinterpret_cast<NetPacket_Repeat<id>&>( + *(buf.bytes.begin() + + sizeof(NetPacket_Head<id>) + + repeat.size())); + net_repeat_repeat_size.c = Byte{static_cast<uint8_t>('\0')}; + return buf; +} + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +void send_vpacket(Session *s, Packet_Head<id>& head, const XString& repeat) +{ + Buffer pkt = create_vpacket<id, headsize, repeatsize>(head, repeat); + send_buffer(s, pkt); +} + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +__attribute__((warn_unused_result)) +RecvResult recv_vpacket(Session *s, Packet_Head<id>& head, AString& repeat) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "NetPacket_Head<id>"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "NetPacket_Repeat<id>"); + static_assert(repeatsize == 1, "repeatsize"); + + NetPacket_Head<id> net_head; + std::vector<NetPacket_Repeat<id>> net_repeat; + RecvResult rv = net_recv_vpacket(s, net_head, net_repeat); + assert (head.magic_packet_id == Packet_Head<id>::PACKET_ID); + if (rv == RecvResult::Complete) + { + if (!network_to_native(&head, net_head)) + return RecvResult::Error; + // reinterpret_cast is needed to correctly handle an empty vector + const char *begin = sign_cast<const char *>(net_repeat.data()); + const char *end = begin + net_repeat.size(); + end = std::find(begin, end, '\0'); + repeat = XString(begin, end, nullptr); + } + return rv; +} + + +// if there is nothing in the head but the id and length, use the below + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +Buffer create_packet_repeatonly(const std::vector<Packet_Repeat<id>>& v) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "repeat headsize"); + static_assert(headsize == 4, "repeat headsize"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "sizeof(NetPacket_Repeat<id>)"); + + Packet_Head<id> head; + return create_vpacket<id, 4, repeatsize>(head, v); +} + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +void send_packet_repeatonly(Session *s, const std::vector<Packet_Repeat<id>>& v) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "repeat headsize"); + static_assert(headsize == 4, "repeat headsize"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "sizeof(NetPacket_Repeat<id>)"); + + Packet_Head<id> head; + send_vpacket<id, 4, repeatsize>(s, head, v); +} + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +__attribute__((warn_unused_result)) +RecvResult recv_packet_repeatonly(Session *s, std::vector<Packet_Repeat<id>>& v) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "repeat headsize"); + static_assert(headsize == 4, "repeat headsize"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "sizeof(NetPacket_Repeat<id>)"); + + Packet_Head<id> head; + return recv_vpacket<id, 4, repeatsize>(s, head, v); +} + + +// and the combination of both of the above + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +Buffer create_packet_repeatonly(const XString& repeat) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "repeat headsize"); + static_assert(headsize == 4, "repeat headsize"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "sizeof(NetPacket_Repeat<id>)"); + static_assert(repeatsize == 1, "repeatsize"); + + Packet_Head<id> head; + return create_vpacket<id, 4, repeatsize>(head, repeat); +} + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +void send_packet_repeatonly(Session *s, const XString& repeat) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "repeat headsize"); + static_assert(headsize == 4, "repeat headsize"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "sizeof(NetPacket_Repeat<id>)"); + static_assert(repeatsize == 1, "repeatsize"); + + Packet_Head<id> head; + send_vpacket<id, 4, repeatsize>(s, head, repeat); +} + +template<uint16_t id, uint16_t headsize, uint16_t repeatsize> +__attribute__((warn_unused_result)) +RecvResult recv_packet_repeatonly(Session *s, AString& repeat) +{ + static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID"); + static_assert(headsize == sizeof(NetPacket_Head<id>), "repeat headsize"); + static_assert(headsize == 4, "repeat headsize"); + static_assert(id == Packet_Repeat<id>::PACKET_ID, "Packet_Repeat<id>::PACKET_ID"); + static_assert(repeatsize == sizeof(NetPacket_Repeat<id>), "sizeof(NetPacket_Repeat<id>)"); + static_assert(repeatsize == 1, "repeatsize"); + + Packet_Head<id> head; + return recv_vpacket<id, 4, repeatsize>(s, head, repeat); +} +} // namespace tmwa diff --git a/src/mmo/socket.cpp b/src/net/socket.cpp index 1e294bd..a01cd81 100644 --- a/src/mmo/socket.cpp +++ b/src/net/socket.cpp @@ -21,25 +21,30 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <arpa/inet.h> #include <netinet/tcp.h> #include <sys/socket.h> -//#include <sys/types.h> #include <fcntl.h> -#include <unistd.h> #include <cstdlib> -#include <cstring> -#include <ctime> + +#include <array> + +#include "../compat/memory.hpp" #include "../io/cxxstdio.hpp" -#include "core.hpp" + +// TODO get rid of ordering violations +#include "../mmo/utils.hpp" +#include "../mmo/core.hpp" + #include "timer.hpp" -#include "utils.hpp" #include "../poison.hpp" + +namespace tmwa +{ static io::FD_Set readfds; static @@ -50,11 +55,11 @@ const uint32_t RFIFO_SIZE = 65536; static const uint32_t WFIFO_SIZE = 65536; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" +DIAG_PUSH(); +DIAG_I(old_style_cast); static std::array<std::unique_ptr<Session>, FD_SETSIZE> session; -#pragma GCC diagnostic pop +DIAG_POP(); Session::Session(SessionIO io, SessionParsers p) : created() @@ -118,8 +123,8 @@ IteratorPair<ValueIterator<io::FD, IncrFD>> iter_fds() inline void RFIFOFLUSH(Session *s) { - really_memmove(&s->rdata[0], &s->rdata[s->rdata_pos], RFIFOREST(s)); - s->rdata_size = RFIFOREST(s); + really_memmove(&s->rdata[0], &s->rdata[s->rdata_pos], s->rdata_size - s->rdata_pos); + s->rdata_size -= s->rdata_pos; s->rdata_pos = 0; } @@ -190,7 +195,7 @@ void connect_client(Session *ls) } if (fd.uncast_dammit() >= SOFT_LIMIT) { - FPRINTF(stderr, "softlimit reached, disconnecting : %d\n", fd.uncast_dammit()); + FPRINTF(stderr, "softlimit reached, disconnecting : %d\n"_fmt, fd.uncast_dammit()); fd.shutdown(SHUT_RDWR); fd.close(); return; @@ -225,7 +230,7 @@ void connect_client(Session *ls) fd.fcntl(F_SETFL, O_NONBLOCK); set_session(fd, make_unique<Session>( - SessionIO{func_recv: recv_to_fifo, func_send: send_from_fifo}, + SessionIO{.func_recv= recv_to_fifo, .func_send= send_from_fifo}, ls->for_inferior)); Session *s = get_session(fd); s->fd = fd; @@ -264,14 +269,12 @@ Session *make_listen_port(uint16_t port, SessionParsers inferior) fd.setsockopt(IPPROTO_TCP, TCP_NODELAY, &yes, sizeof yes); server_address.sin_family = AF_INET; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" -#if __GNUC__ > 4 || __GNUC_MINOR__ >= 8 -# pragma GCC diagnostic ignored "-Wuseless-cast" -#endif + DIAG_PUSH(); + DIAG_I(old_style_cast); + DIAG_I(useless_cast); server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(port); -#pragma GCC diagnostic pop + DIAG_POP(); if (fd.bind(reinterpret_cast<struct sockaddr *>(&server_address), sizeof(server_address)) == -1) @@ -288,8 +291,8 @@ Session *make_listen_port(uint16_t port, SessionParsers inferior) readfds.set(fd); set_session(fd, make_unique<Session>( - SessionIO{func_recv: connect_client, func_send: nullptr}, - SessionParsers{func_parse: nullptr, func_delete: nothing_delete})); + SessionIO{.func_recv= connect_client, .func_send= nullptr}, + SessionParsers{.func_parse= nullptr, .func_delete= nothing_delete})); Session *s = get_session(fd); s->for_inferior = inferior; s->fd = fd; @@ -325,13 +328,11 @@ Session *make_connection(IP4Address ip, uint16_t port, SessionParsers parsers) server_address.sin_family = AF_INET; server_address.sin_addr = in_addr(ip); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" -#if __GNUC__ > 4 || __GNUC_MINOR__ >= 8 -# pragma GCC diagnostic ignored "-Wuseless-cast" -#endif + DIAG_PUSH(); + DIAG_I(old_style_cast); + DIAG_I(useless_cast); server_address.sin_port = htons(port); -#pragma GCC diagnostic pop + DIAG_POP(); fd.fcntl(F_SETFL, O_NONBLOCK); @@ -343,7 +344,7 @@ Session *make_connection(IP4Address ip, uint16_t port, SessionParsers parsers) readfds.set(fd); set_session(fd, make_unique<Session>( - SessionIO{func_recv: recv_to_fifo, func_send: send_from_fifo}, + SessionIO{.func_recv= recv_to_fifo, .func_send= send_from_fifo}, parsers)); Session *s = get_session(fd); s->fd = fd; @@ -398,19 +399,6 @@ void realloc_fifo(Session *s, size_t rfifo_size, size_t wfifo_size) } } -void WFIFOSET(Session *s, size_t len) -{ - if (s->wdata_size + len + 16384 > s->max_wdata) - { - realloc_fifo(s, s->max_rdata, s->max_wdata << 1); - PRINTF("socket: %d wdata expanded to %zu bytes.\n", s, s->max_wdata); - } - if (s->wdata_size + len + 2048 < s->max_wdata) - s->wdata_size += len; - else - FPRINTF(stderr, "socket: %d wdata lost !!\n", s), abort(); -} - void do_sendrecv(interval_t next_ms) { bool any = false; @@ -429,7 +417,8 @@ void do_sendrecv(interval_t next_ms) { if (!has_timers()) { - PRINTF("Shutting down - nothing to do\n"); + PRINTF("Shutting down - nothing to do\n"_fmt); + // TODO hoist this runflag = false; } return; @@ -441,7 +430,7 @@ void do_sendrecv(interval_t next_ms) timeout.tv_sec = next_s.count(); timeout.tv_usec = next_us.count(); } - if (io::FD_Set::select(fd_max, &rfd, &wfd, NULL, &timeout) <= 0) + if (io::FD_Set::select(fd_max, &rfd, &wfd, nullptr, &timeout) <= 0) return; for (io::FD i : iter_fds()) { @@ -474,7 +463,7 @@ void do_parsepacket(void) if (!s->connected && static_cast<time_t>(TimeT::now()) - static_cast<time_t>(s->created) > CONNECT_TIMEOUT) { - PRINTF("Session #%d timed out\n", s); + PRINTF("Session #%d timed out\n"_fmt, s); s->set_eof(); } if (s->rdata_size && !s->eof && s->func_parse) @@ -495,14 +484,4 @@ void do_parsepacket(void) RFIFOFLUSH(s); } } - -void RFIFOSKIP(Session *s, size_t len) -{ - s->rdata_pos += len; - - if (s->rdata_size < s->rdata_pos) - { - FPRINTF(stderr, "too many skip\n"); - abort(); - } -} +} // namespace tmwa diff --git a/src/net/socket.hpp b/src/net/socket.hpp new file mode 100644 index 0000000..576ef85 --- /dev/null +++ b/src/net/socket.hpp @@ -0,0 +1,177 @@ +#pragma once +// socket.hpp - Network event system. +// +// Copyright © ????-2004 Athena Dev Teams +// Copyright © 2004-2011 The Mana World Development Team +// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include <algorithm> + +#include <sys/select.h> + +#include <memory> + +#include "../compat/iter.hpp" +#include "../compat/rawmem.hpp" +#include "../compat/time_t.hpp" + +#include "../strings/astring.hpp" +#include "../strings/vstring.hpp" +#include "../strings/xstring.hpp" + +#include "../generic/dumb_ptr.hpp" + +#include "../io/fd.hpp" + +#include "ip.hpp" +#include "timer.t.hpp" + + +namespace tmwa +{ +struct SessionData +{ +}; +struct SessionDeleter +{ + // defined per-server + void operator()(SessionData *sd); +}; + +struct SessionIO +{ + void (*func_recv)(Session *); + void (*func_send)(Session *); +}; + +struct SessionParsers +{ + void (*func_parse)(Session *); + void (*func_delete)(Session *); +}; + +struct Session +{ + Session(SessionIO, SessionParsers); + Session(Session&&) = delete; + Session& operator = (Session&&) = delete; + + void set_io(SessionIO); + void set_parsers(SessionParsers); + + /// Checks whether a newly-connected socket actually does anything + TimeT created; + bool connected; + +private: + /// Flag needed since structure must be freed in a server-dependent manner + bool eof; +public: + void set_eof() { eof = true; } + + /// Currently used by clif_setwaitclose + Timer timed_close; + + /// Since this is a single-threaded application, it can't block + /// These are the read/write queues + dumb_ptr<uint8_t[]> rdata, wdata; + size_t max_rdata, max_wdata; + /// How much is actually in the queue + size_t rdata_size, wdata_size; + /// How much has already been read from the queue + /// Note that there is no need for a wdata_pos + size_t rdata_pos; + + IP4Address client_ip; + +private: + /// Send or recieve + /// Only called when select() indicates the socket is ready + /// If, after that, nothing is read, it sets eof + // These could probably be hard-coded with a little work + void (*func_recv)(Session *); + void (*func_send)(Session *); + /// This is the important one + /// Set to different functions depending on whether the connection + /// is a player or a server/ladmin + void (*func_parse)(Session *); + /// Cleanup function since we're not fully RAII yet + void (*func_delete)(Session *); + +public: + // this really ought to be part of session_data, once that gets sane + SessionParsers for_inferior; + + /// Server-specific data type + // (this really should include the deleter, but ...) + std::unique_ptr<SessionData, SessionDeleter> session_data; + + io::FD fd; + + friend void do_sendrecv(interval_t next); + friend void do_parsepacket(void); + friend void delete_session(Session *); +}; + +inline +int convert_for_printf(Session *s) +{ + return s->fd.uncast_dammit(); +} + +// save file descriptors for important stuff +constexpr int SOFT_LIMIT = FD_SETSIZE - 50; + +// socket timeout to establish a full connection in seconds +constexpr int CONNECT_TIMEOUT = 15; + + +void set_session(io::FD fd, std::unique_ptr<Session> sess); +Session *get_session(io::FD fd); +void reset_session(io::FD fd); +int get_fd_max(); + +class IncrFD +{ +public: + static + io::FD inced(io::FD v) + { + return io::FD::cast_dammit(v.uncast_dammit() + 1); + } +}; +IteratorPair<ValueIterator<io::FD, IncrFD>> iter_fds(); + + +/// open a socket, bind, and listen. Return an fd, or -1 if socket() fails, +/// but exit if bind() or listen() fails +Session *make_listen_port(uint16_t port, SessionParsers inferior); +/// Connect to an address, return a connected socket or -1 +// FIXME - this is IPv4 only! +Session *make_connection(IP4Address ip, uint16_t port, SessionParsers); +/// free() the structure and close() the fd +void delete_session(Session *); +/// Make a the internal queues bigger +void realloc_fifo(Session *s, size_t rfifo_size, size_t wfifo_size); +/// Update all sockets that can be read/written from the queues +void do_sendrecv(interval_t next); +/// Call the parser function for every socket that has read data +void do_parsepacket(void); +} // namespace tmwa diff --git a/src/mmo/timer.cpp b/src/net/timer.cpp index 6e28a12..6a22616 100644 --- a/src/mmo/timer.cpp +++ b/src/net/timer.cpp @@ -24,18 +24,17 @@ #include <sys/time.h> #include <cassert> -#include <cstring> +#include <algorithm> #include <queue> #include "../strings/zstring.hpp" -#include "../io/cxxstdio.hpp" - -#include "utils.hpp" - #include "../poison.hpp" + +namespace tmwa +{ struct TimerData { /// This will be reset on call, to avoid problems. @@ -78,7 +77,7 @@ tick_t milli_clock::now(void) noexcept struct timeval tval; // BUG: This will cause strange behavior if the system clock is changed! // it should be reimplemented in terms of clock_gettime(CLOCK_MONOTONIC, ) - gettimeofday(&tval, NULL); + gettimeofday(&tval, nullptr); return gettick_cache = tick_t(std::chrono::seconds(tval.tv_sec) + std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::microseconds(tval.tv_usec))); @@ -167,7 +166,7 @@ interval_t do_timer(tick_t tick) { /// Number of milliseconds until it calls this again // this says to wait 1 sec if all timers get popped - interval_t nextmin = std::chrono::seconds(1); + interval_t nextmin = 1_s; while (dumb_ptr<TimerData> td = top_timer_heap()) { @@ -187,7 +186,7 @@ interval_t do_timer(tick_t tick) td->owner->detach(); // If we are too far past the requested tick, call with // the current tick instead to fix reregistration problems - if (td->tick + std::chrono::seconds(1) < tick) + if (td->tick + 1_s < tick) td->func(td.operator->(), tick); else td->func(td.operator->(), td->tick); @@ -197,14 +196,14 @@ interval_t do_timer(tick_t tick) td.delete_(); continue; } - if (td->tick + std::chrono::seconds(1) < tick) + if (td->tick + 1_s < tick) td->tick = tick + td->interval; else td->tick += td->interval; push_timer_heap(td); } - return std::max(nextmin, std::chrono::milliseconds(10)); + return std::max(nextmin, 10_ms); } tick_t file_modified(ZString name) @@ -219,3 +218,4 @@ bool has_timers() { return !timer_heap.empty(); } +} // namespace tmwa diff --git a/src/mmo/timer.hpp b/src/net/timer.hpp index 363cf17..338e339 100644 --- a/src/mmo/timer.hpp +++ b/src/net/timer.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MMO_TIMER_HPP -#define TMWA_MMO_TIMER_HPP +#pragma once // timer.hpp - Future event scheduler. // // Copyright © ????-2004 Athena Dev Teams @@ -21,12 +20,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "timer.t.hpp" +#include "timer.t.hpp" -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/fwd.hpp" +#include "../strings/fwd.hpp" + +namespace tmwa +{ // updated automatically when using milli_clock::now() // which is done only by core.cpp extern tick_t gettick_cache; @@ -46,5 +48,4 @@ tick_t file_modified(ZString name); /// Check if there are any events at all scheduled. bool has_timers(); - -#endif // TMWA_MMO_TIMER_HPP +} // namespace tmwa diff --git a/src/mmo/timer.t.hpp b/src/net/timer.t.hpp index 6066e7c..090e62a 100644 --- a/src/mmo/timer.t.hpp +++ b/src/net/timer.t.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_MMO_TIMER_T_HPP -#define TMWA_MMO_TIMER_T_HPP +#pragma once // timer.t.hpp - Future event scheduler. // // Copyright © ????-2004 Athena Dev Teams @@ -21,14 +20,41 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <chrono> -# include <functional> +#include <cstdlib> -# include "dumb_ptr.hpp" +#include <chrono> +#include <functional> -struct TimerData; +#include "../ints/little.hpp" + +#include "../generic/dumb_ptr.hpp" + + +namespace tmwa +{ +constexpr +std::chrono::nanoseconds operator "" _ns(unsigned long long ns) +{ return std::chrono::nanoseconds(ns); } +constexpr +std::chrono::microseconds operator "" _us(unsigned long long us) +{ return std::chrono::microseconds(us); } +constexpr +std::chrono::milliseconds operator "" _ms(unsigned long long ms) +{ return std::chrono::milliseconds(ms); } +constexpr +std::chrono::seconds operator "" _s(unsigned long long s) +{ return std::chrono::seconds(s); } +constexpr +std::chrono::minutes operator "" _min(unsigned long long min) +{ return std::chrono::minutes(min); } +constexpr +std::chrono::hours operator "" _h(unsigned long long h) +{ return std::chrono::hours(h); } +constexpr +std::chrono::duration<int, std::ratio<60*60*24>> operator "" _d(unsigned long long d) +{ return std::chrono::duration<int, std::ratio<60*60*24>>(d); } /// An implementation of the C++ "clock" concept, exposing /// durations in milliseconds. @@ -51,6 +77,55 @@ typedef milli_clock::duration interval_t; /// (to get additional arguments, use std::bind or a lambda). typedef std::function<void (TimerData *, tick_t)> timer_func; +// 49.7 day problem +inline __attribute__((warn_unused_result)) +bool native_to_network(Little32 *net, tick_t nat) +{ + auto tmp = nat.time_since_epoch().count(); + return native_to_network(net, static_cast<uint32_t>(tmp)); +} + +inline __attribute__((warn_unused_result)) +bool network_to_native(tick_t *nat, Little32 net) +{ + (void)nat; + (void)net; + abort(); +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(Little32 *net, interval_t nat) +{ + auto tmp = nat.count(); + return native_to_network(net, static_cast<uint32_t>(tmp)); +} + +inline __attribute__((warn_unused_result)) +bool network_to_native(interval_t *nat, Little32 net) +{ + uint32_t tmp; + bool rv = network_to_native(&tmp, net); + *nat = interval_t(tmp); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *net, interval_t nat) +{ + auto tmp = nat.count(); + return native_to_network(net, static_cast<uint16_t>(tmp)); +} + +inline __attribute__((warn_unused_result)) +bool network_to_native(interval_t *nat, Little16 net) +{ + uint16_t tmp; + bool rv = network_to_native(&tmp, net); + *nat = interval_t(tmp); + return rv; +} + + class Timer { friend struct TimerData; @@ -86,5 +161,4 @@ public: /// Check if there is no connected timer. bool operator !() { return !td; } }; - -#endif // TMWA_MMO_TIMER_T_HPP +} // namespace tmwa diff --git a/src/poison.hpp b/src/poison.hpp index 0328825..6903e1a 100644 --- a/src/poison.hpp +++ b/src/poison.hpp @@ -1,4 +1,4 @@ -#ifndef GENERATING_DEPENDENCIES +#pragma once // poison.hpp - List of dangerous functions and objects. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -18,10 +18,12 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# if 0 -# include "../sanity.hpp" -# endif +// just mention "fwd.hpp" to make formatter happy + +namespace tmwa +{ +#ifndef GENERATING_DEPENDENCIES // impossible(*) to use safely // removed in C11 # pragma GCC poison gets @@ -78,13 +80,12 @@ # pragma GCC poison open_memstream # pragma GCC poison open_wmemstream -// *scanf %ms is done very carefully. -//#pragma GCC poison scanf -//#pragma GCC poison fscanf -//#pragma GCC poison sscanf -//#pragma GCC poison vscanf -//#pragma GCC poison vsscanf -//#pragma GCC poison vfscanf +# pragma GCC poison scanf +# pragma GCC poison fscanf +# pragma GCC poison sscanf +# pragma GCC poison vscanf +# pragma GCC poison vsscanf +# pragma GCC poison vfscanf # pragma GCC poison getcwd # pragma GCC poison get_current_dir_name @@ -119,5 +120,5 @@ # pragma GCC poison ifstream # pragma GCC poison ofstream # pragma GCC poison fstream - #endif // GENERATING_DEPENDENCIES +} // namespace tmwa diff --git a/src/proto2/any-user.hpp b/src/proto2/any-user.hpp new file mode 100644 index 0000000..aeb703b --- /dev/null +++ b/src/proto2/any-user.hpp @@ -0,0 +1,214 @@ +#pragma once +// any-user.hpp - TMWA network protocol: any/user +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "fwd.hpp" + +#include "types.hpp" + +namespace tmwa +{ +// This is a public protocol, and changes require client cooperation + +template<> +struct Packet_Fixed<0x0081> +{ + static const uint16_t PACKET_ID = 0x0081; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t error_code = {}; +}; + +template<> +struct Packet_Fixed<0x7530> +{ + static const uint16_t PACKET_ID = 0x7530; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x7531> +{ + static const uint16_t PACKET_ID = 0x7531; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + Version version = {}; +}; + +template<> +struct Packet_Fixed<0x7532> +{ + static const uint16_t PACKET_ID = 0x7532; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Payload<0x8000> +{ + static const uint16_t PACKET_ID = 0x8000; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; + + +template<> +struct NetPacket_Fixed<0x0081> +{ + Little16 magic_packet_id; + Byte error_code; +}; +static_assert(offsetof(NetPacket_Fixed<0x0081>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0081>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0081>, error_code) == 2, "offsetof(NetPacket_Fixed<0x0081>, error_code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0081>) == 3, "sizeof(NetPacket_Fixed<0x0081>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x0081>) == 1, "alignof(NetPacket_Fixed<0x0081>) == 1"); + +template<> +struct NetPacket_Fixed<0x7530> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x7530>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7530>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x7530>) == 2, "sizeof(NetPacket_Fixed<0x7530>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x7530>) == 1, "alignof(NetPacket_Fixed<0x7530>) == 1"); + +template<> +struct NetPacket_Fixed<0x7531> +{ + Little16 magic_packet_id; + NetVersion version; +}; +static_assert(offsetof(NetPacket_Fixed<0x7531>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7531>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7531>, version) == 2, "offsetof(NetPacket_Fixed<0x7531>, version) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x7531>) == 10, "sizeof(NetPacket_Fixed<0x7531>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x7531>) == 1, "alignof(NetPacket_Fixed<0x7531>) == 1"); + +template<> +struct NetPacket_Fixed<0x7532> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x7532>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7532>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x7532>) == 2, "sizeof(NetPacket_Fixed<0x7532>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x7532>) == 1, "alignof(NetPacket_Fixed<0x7532>) == 1"); + +template<> +struct NetPacket_Payload<0x8000> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Payload<0x8000>, magic_packet_id) == 0, "offsetof(NetPacket_Payload<0x8000>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Payload<0x8000>, magic_packet_length) == 2, "offsetof(NetPacket_Payload<0x8000>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Payload<0x8000>) == 4, "sizeof(NetPacket_Payload<0x8000>) == 4"); +static_assert(alignof(NetPacket_Payload<0x8000>) == 1, "alignof(NetPacket_Payload<0x8000>) == 1"); + + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0081> *network, Packet_Fixed<0x0081> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->error_code, native.error_code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0081> *native, NetPacket_Fixed<0x0081> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->error_code, network.error_code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7530> *network, Packet_Fixed<0x7530> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7530> *native, NetPacket_Fixed<0x7530> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7531> *network, Packet_Fixed<0x7531> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->version, native.version); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7531> *native, NetPacket_Fixed<0x7531> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->version, network.version); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7532> *network, Packet_Fixed<0x7532> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7532> *native, NetPacket_Fixed<0x7532> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Payload<0x8000> *network, Packet_Payload<0x8000> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Payload<0x8000> *native, NetPacket_Payload<0x8000> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} + +} // namespace tmwa diff --git a/src/proto2/any-user_test.cpp b/src/proto2/any-user_test.cpp new file mode 100644 index 0000000..3cf15bf --- /dev/null +++ b/src/proto2/any-user_test.cpp @@ -0,0 +1,27 @@ +#include "any-user.hpp" +// any-user_test.cpp - TMWA network protocol: any/user +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "../poison.hpp" + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/proto2/char-map.hpp b/src/proto2/char-map.hpp new file mode 100644 index 0000000..8a23be6 --- /dev/null +++ b/src/proto2/char-map.hpp @@ -0,0 +1,3498 @@ +#pragma once +// char-map.hpp - TMWA network protocol: char/map +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "fwd.hpp" + +#include "types.hpp" + +namespace tmwa +{ +// This is an internal protocol, and can be changed without notice + +template<> +struct Packet_Fixed<0x2af7> +{ + static const uint16_t PACKET_ID = 0x2af7; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x2af8> +{ + static const uint16_t PACKET_ID = 0x2af8; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + AccountPass account_pass = {}; + uint32_t unused = {}; + IP4Address ip = {}; + uint16_t port = {}; +}; + +template<> +struct Packet_Fixed<0x2af9> +{ + static const uint16_t PACKET_ID = 0x2af9; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t code = {}; +}; + +template<> +struct Packet_Head<0x2afa> +{ + static const uint16_t PACKET_ID = 0x2afa; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x2afa> +{ + static const uint16_t PACKET_ID = 0x2afa; + + MapName map_name = {}; +}; + +template<> +struct Packet_Fixed<0x2afa> +{ + static const uint16_t PACKET_ID = 0x2afa; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + ItemNameId source_item_id = {}; + ItemNameId dest_item_id = {}; +}; + +template<> +struct Packet_Fixed<0x2afb> +{ + static const uint16_t PACKET_ID = 0x2afb; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t unknown = {}; + CharName whisper_name = {}; +}; + +template<> +struct Packet_Fixed<0x2afc> +{ + static const uint16_t PACKET_ID = 0x2afc; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + CharId char_id = {}; + uint32_t login_id1 = {}; + uint32_t login_id2 = {}; + IP4Address ip = {}; +}; + +template<> +struct Packet_Payload<0x2afd> +{ + static const uint16_t PACKET_ID = 0x2afd; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; + uint32_t login_id2 = {}; + TimeT connect_until = {}; + uint16_t packet_tmw_version = {}; + CharKey char_key = {}; + CharData char_data = {}; +}; + +template<> +struct Packet_Fixed<0x2afe> +{ + static const uint16_t PACKET_ID = 0x2afe; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Head<0x2aff> +{ + static const uint16_t PACKET_ID = 0x2aff; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + uint16_t users = {}; +}; +template<> +struct Packet_Repeat<0x2aff> +{ + static const uint16_t PACKET_ID = 0x2aff; + + CharId char_id = {}; +}; + +template<> +struct Packet_Fixed<0x2b00> +{ + static const uint16_t PACKET_ID = 0x2b00; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint32_t users = {}; +}; + +template<> +struct Packet_Payload<0x2b01> +{ + static const uint16_t PACKET_ID = 0x2b01; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; + CharId char_id = {}; + CharKey char_key = {}; + CharData char_data = {}; +}; + +template<> +struct Packet_Fixed<0x2b02> +{ + static const uint16_t PACKET_ID = 0x2b02; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint32_t login_id1 = {}; + uint32_t login_id2 = {}; + IP4Address ip = {}; +}; + +template<> +struct Packet_Fixed<0x2b03> +{ + static const uint16_t PACKET_ID = 0x2b03; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint8_t unknown = {}; +}; + +template<> +struct Packet_Head<0x2b04> +{ + static const uint16_t PACKET_ID = 0x2b04; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + IP4Address ip = {}; + uint16_t port = {}; +}; +template<> +struct Packet_Repeat<0x2b04> +{ + static const uint16_t PACKET_ID = 0x2b04; + + MapName map_name = {}; +}; + +template<> +struct Packet_Fixed<0x2b05> +{ + static const uint16_t PACKET_ID = 0x2b05; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint32_t login_id1 = {}; + uint32_t login_id2 = {}; + CharId char_id = {}; + MapName map_name = {}; + uint16_t x = {}; + uint16_t y = {}; + IP4Address map_ip = {}; + uint16_t map_port = {}; + SEX sex = {}; + IP4Address client_ip = {}; +}; + +template<> +struct Packet_Fixed<0x2b06> +{ + static const uint16_t PACKET_ID = 0x2b06; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint32_t error = {}; + uint32_t unknown = {}; + CharId char_id = {}; + MapName map_name = {}; + uint16_t x = {}; + uint16_t y = {}; + IP4Address map_ip = {}; + uint16_t map_port = {}; +}; + +template<> +struct Packet_Head<0x2b0a> +{ + static const uint16_t PACKET_ID = 0x2b0a; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x2b0a> +{ + static const uint16_t PACKET_ID = 0x2b0a; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x2b0b> +{ + static const uint16_t PACKET_ID = 0x2b0b; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + GmLevel gm_level = {}; +}; + +template<> +struct Packet_Fixed<0x2b0c> +{ + static const uint16_t PACKET_ID = 0x2b0c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountEmail old_email = {}; + AccountEmail new_email = {}; +}; + +template<> +struct Packet_Fixed<0x2b0d> +{ + static const uint16_t PACKET_ID = 0x2b0d; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + SEX sex = {}; +}; + +template<> +struct Packet_Fixed<0x2b0e> +{ + static const uint16_t PACKET_ID = 0x2b0e; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + CharName char_name = {}; + uint16_t operation = {}; + HumanTimeDiff ban_add = {}; +}; + +template<> +struct Packet_Fixed<0x2b0f> +{ + static const uint16_t PACKET_ID = 0x2b0f; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + CharName char_name = {}; + uint16_t operation = {}; + uint16_t error = {}; +}; + +template<> +struct Packet_Head<0x2b10> +{ + static const uint16_t PACKET_ID = 0x2b10; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x2b10> +{ + static const uint16_t PACKET_ID = 0x2b10; + + VarName name = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Head<0x2b11> +{ + static const uint16_t PACKET_ID = 0x2b11; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x2b11> +{ + static const uint16_t PACKET_ID = 0x2b11; + + VarName name = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Fixed<0x2b12> +{ + static const uint16_t PACKET_ID = 0x2b12; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharId char_id = {}; + CharId partner_id = {}; +}; + +template<> +struct Packet_Fixed<0x2b13> +{ + static const uint16_t PACKET_ID = 0x2b13; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x2b14> +{ + static const uint16_t PACKET_ID = 0x2b14; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint8_t ban_not_status = {}; + TimeT status_or_ban_until = {}; +}; + +template<> +struct Packet_Head<0x2b15> +{ + static const uint16_t PACKET_ID = 0x2b15; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x2b15> +{ + static const uint16_t PACKET_ID = 0x2b15; + + AccountId account_id = {}; + GmLevel gm_level = {}; +}; + +template<> +struct Packet_Fixed<0x2b16> +{ + static const uint16_t PACKET_ID = 0x2b16; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharId char_id = {}; +}; + +template<> +struct Packet_Head<0x3000> +{ + static const uint16_t PACKET_ID = 0x3000; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x3000> +{ + static const uint16_t PACKET_ID = 0x3000; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x3001> +{ + static const uint16_t PACKET_ID = 0x3001; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + CharName from_char_name = {}; + CharName to_char_name = {}; +}; +template<> +struct Packet_Repeat<0x3001> +{ + static const uint16_t PACKET_ID = 0x3001; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x3002> +{ + static const uint16_t PACKET_ID = 0x3002; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharId char_id = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Head<0x3003> +{ + static const uint16_t PACKET_ID = 0x3003; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + CharName char_name = {}; + GmLevel min_gm_level = {}; +}; +template<> +struct Packet_Repeat<0x3003> +{ + static const uint16_t PACKET_ID = 0x3003; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x3004> +{ + static const uint16_t PACKET_ID = 0x3004; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x3004> +{ + static const uint16_t PACKET_ID = 0x3004; + + VarName name = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Fixed<0x3005> +{ + static const uint16_t PACKET_ID = 0x3005; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x3010> +{ + static const uint16_t PACKET_ID = 0x3010; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Payload<0x3011> +{ + static const uint16_t PACKET_ID = 0x3011; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; + Storage storage = {}; +}; + +template<> +struct Packet_Fixed<0x3020> +{ + static const uint16_t PACKET_ID = 0x3020; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + PartyName party_name = {}; + CharName char_name = {}; + MapName map_name = {}; + uint16_t level = {}; +}; + +template<> +struct Packet_Fixed<0x3021> +{ + static const uint16_t PACKET_ID = 0x3021; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; +}; + +template<> +struct Packet_Fixed<0x3022> +{ + static const uint16_t PACKET_ID = 0x3022; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + CharName char_name = {}; + MapName map_name = {}; + uint16_t level = {}; +}; + +template<> +struct Packet_Fixed<0x3023> +{ + static const uint16_t PACKET_ID = 0x3023; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + uint16_t exp = {}; + uint16_t item = {}; +}; + +template<> +struct Packet_Fixed<0x3024> +{ + static const uint16_t PACKET_ID = 0x3024; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x3025> +{ + static const uint16_t PACKET_ID = 0x3025; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + MapName map_name = {}; + uint8_t online = {}; + uint16_t level = {}; +}; + +template<> +struct Packet_Head<0x3027> +{ + static const uint16_t PACKET_ID = 0x3027; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + PartyId party_id = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x3027> +{ + static const uint16_t PACKET_ID = 0x3027; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x3028> +{ + static const uint16_t PACKET_ID = 0x3028; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + CharName char_name = {}; +}; + +template<> +struct Packet_Head<0x3800> +{ + static const uint16_t PACKET_ID = 0x3800; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x3800> +{ + static const uint16_t PACKET_ID = 0x3800; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x3801> +{ + static const uint16_t PACKET_ID = 0x3801; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + CharId whisper_id = {}; + CharName src_char_name = {}; + CharName dst_char_name = {}; +}; +template<> +struct Packet_Repeat<0x3801> +{ + static const uint16_t PACKET_ID = 0x3801; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x3802> +{ + static const uint16_t PACKET_ID = 0x3802; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharName sender_char_name = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Head<0x3803> +{ + static const uint16_t PACKET_ID = 0x3803; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + CharName char_name = {}; + GmLevel min_gm_level = {}; +}; +template<> +struct Packet_Repeat<0x3803> +{ + static const uint16_t PACKET_ID = 0x3803; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x3804> +{ + static const uint16_t PACKET_ID = 0x3804; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x3804> +{ + static const uint16_t PACKET_ID = 0x3804; + + VarName name = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Payload<0x3810> +{ + static const uint16_t PACKET_ID = 0x3810; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; + Storage storage = {}; +}; + +template<> +struct Packet_Fixed<0x3811> +{ + static const uint16_t PACKET_ID = 0x3811; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint8_t unknown = {}; +}; + +template<> +struct Packet_Fixed<0x3820> +{ + static const uint16_t PACKET_ID = 0x3820; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint8_t error = {}; + PartyId party_id = {}; + PartyName party_name = {}; +}; + +template<> +struct Packet_Head<0x3821> +{ + static const uint16_t PACKET_ID = 0x3821; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + PartyId party_id = {}; +}; +template<> +struct Packet_Option<0x3821> +{ + static const uint16_t PACKET_ID = 0x3821; + + PartyMost party_most = {}; +}; + +template<> +struct Packet_Fixed<0x3822> +{ + static const uint16_t PACKET_ID = 0x3822; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Fixed<0x3823> +{ + static const uint16_t PACKET_ID = 0x3823; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + uint16_t exp = {}; + uint16_t item = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Fixed<0x3824> +{ + static const uint16_t PACKET_ID = 0x3824; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + CharName char_name = {}; +}; + +template<> +struct Packet_Fixed<0x3825> +{ + static const uint16_t PACKET_ID = 0x3825; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + AccountId account_id = {}; + MapName map_name = {}; + uint8_t online = {}; + uint16_t level = {}; +}; + +template<> +struct Packet_Fixed<0x3826> +{ + static const uint16_t PACKET_ID = 0x3826; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyId party_id = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Head<0x3827> +{ + static const uint16_t PACKET_ID = 0x3827; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + PartyId party_id = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x3827> +{ + static const uint16_t PACKET_ID = 0x3827; + + uint8_t c = {}; +}; + + +template<> +struct NetPacket_Fixed<0x2af7> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2af7>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2af7>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x2af7>) == 2, "sizeof(NetPacket_Fixed<0x2af7>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x2af7>) == 1, "alignof(NetPacket_Fixed<0x2af7>) == 1"); + +template<> +struct NetPacket_Fixed<0x2af8> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + NetString<sizeof(AccountPass)> account_pass; + Little32 unused; + IP4Address ip; + Little16 port; +}; +static_assert(offsetof(NetPacket_Fixed<0x2af8>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2af8>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2af8>, account_name) == 2, "offsetof(NetPacket_Fixed<0x2af8>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2af8>, account_pass) == 26, "offsetof(NetPacket_Fixed<0x2af8>, account_pass) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x2af8>, unused) == 50, "offsetof(NetPacket_Fixed<0x2af8>, unused) == 50"); +static_assert(offsetof(NetPacket_Fixed<0x2af8>, ip) == 54, "offsetof(NetPacket_Fixed<0x2af8>, ip) == 54"); +static_assert(offsetof(NetPacket_Fixed<0x2af8>, port) == 58, "offsetof(NetPacket_Fixed<0x2af8>, port) == 58"); +static_assert(sizeof(NetPacket_Fixed<0x2af8>) == 60, "sizeof(NetPacket_Fixed<0x2af8>) == 60"); +static_assert(alignof(NetPacket_Fixed<0x2af8>) == 1, "alignof(NetPacket_Fixed<0x2af8>) == 1"); + +template<> +struct NetPacket_Fixed<0x2af9> +{ + Little16 magic_packet_id; + Byte code; +}; +static_assert(offsetof(NetPacket_Fixed<0x2af9>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2af9>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2af9>, code) == 2, "offsetof(NetPacket_Fixed<0x2af9>, code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2af9>) == 3, "sizeof(NetPacket_Fixed<0x2af9>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x2af9>) == 1, "alignof(NetPacket_Fixed<0x2af9>) == 1"); + +template<> +struct NetPacket_Head<0x2afa> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x2afa>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2afa>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2afa>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2afa>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x2afa>) == 4, "sizeof(NetPacket_Head<0x2afa>) == 4"); +static_assert(alignof(NetPacket_Head<0x2afa>) == 1, "alignof(NetPacket_Head<0x2afa>) == 1"); +template<> +struct NetPacket_Repeat<0x2afa> +{ + NetString<sizeof(MapName)> map_name; +}; +static_assert(offsetof(NetPacket_Repeat<0x2afa>, map_name) == 0, "offsetof(NetPacket_Repeat<0x2afa>, map_name) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x2afa>) == 16, "sizeof(NetPacket_Repeat<0x2afa>) == 16"); +static_assert(alignof(NetPacket_Repeat<0x2afa>) == 1, "alignof(NetPacket_Repeat<0x2afa>) == 1"); + +template<> +struct NetPacket_Fixed<0x2afa> +{ + Little16 magic_packet_id; + Little32 source_item_id; + Little32 dest_item_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2afa>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2afa>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2afa>, source_item_id) == 2, "offsetof(NetPacket_Fixed<0x2afa>, source_item_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2afa>, dest_item_id) == 6, "offsetof(NetPacket_Fixed<0x2afa>, dest_item_id) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2afa>) == 10, "sizeof(NetPacket_Fixed<0x2afa>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x2afa>) == 1, "alignof(NetPacket_Fixed<0x2afa>) == 1"); + +template<> +struct NetPacket_Fixed<0x2afb> +{ + Little16 magic_packet_id; + Byte unknown; + NetString<sizeof(CharName)> whisper_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x2afb>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2afb>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2afb>, unknown) == 2, "offsetof(NetPacket_Fixed<0x2afb>, unknown) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2afb>, whisper_name) == 3, "offsetof(NetPacket_Fixed<0x2afb>, whisper_name) == 3"); +static_assert(sizeof(NetPacket_Fixed<0x2afb>) == 27, "sizeof(NetPacket_Fixed<0x2afb>) == 27"); +static_assert(alignof(NetPacket_Fixed<0x2afb>) == 1, "alignof(NetPacket_Fixed<0x2afb>) == 1"); + +template<> +struct NetPacket_Fixed<0x2afc> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 char_id; + Little32 login_id1; + Little32 login_id2; + IP4Address ip; +}; +static_assert(offsetof(NetPacket_Fixed<0x2afc>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2afc>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2afc>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2afc>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2afc>, char_id) == 6, "offsetof(NetPacket_Fixed<0x2afc>, char_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2afc>, login_id1) == 10, "offsetof(NetPacket_Fixed<0x2afc>, login_id1) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x2afc>, login_id2) == 14, "offsetof(NetPacket_Fixed<0x2afc>, login_id2) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x2afc>, ip) == 18, "offsetof(NetPacket_Fixed<0x2afc>, ip) == 18"); +static_assert(sizeof(NetPacket_Fixed<0x2afc>) == 22, "sizeof(NetPacket_Fixed<0x2afc>) == 22"); +static_assert(alignof(NetPacket_Fixed<0x2afc>) == 1, "alignof(NetPacket_Fixed<0x2afc>) == 1"); + +template<> +struct NetPacket_Payload<0x2afd> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; + Little32 login_id2; + Little32 connect_until; + Little16 packet_tmw_version; + NetCharKey char_key; + NetCharData char_data; +}; +static_assert(offsetof(NetPacket_Payload<0x2afd>, magic_packet_id) == 0, "offsetof(NetPacket_Payload<0x2afd>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, magic_packet_length) == 2, "offsetof(NetPacket_Payload<0x2afd>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, account_id) == 4, "offsetof(NetPacket_Payload<0x2afd>, account_id) == 4"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, login_id2) == 8, "offsetof(NetPacket_Payload<0x2afd>, login_id2) == 8"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, connect_until) == 12, "offsetof(NetPacket_Payload<0x2afd>, connect_until) == 12"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, packet_tmw_version) == 16, "offsetof(NetPacket_Payload<0x2afd>, packet_tmw_version) == 16"); +static_assert(offsetof(NetPacket_Payload<0x2afd>, char_key) == 18, "offsetof(NetPacket_Payload<0x2afd>, char_key) == 18"); +static_assert(alignof(NetPacket_Payload<0x2afd>) == 1, "alignof(NetPacket_Payload<0x2afd>) == 1"); + +template<> +struct NetPacket_Fixed<0x2afe> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2afe>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2afe>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2afe>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2afe>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2afe>) == 6, "sizeof(NetPacket_Fixed<0x2afe>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x2afe>) == 1, "alignof(NetPacket_Fixed<0x2afe>) == 1"); + +template<> +struct NetPacket_Head<0x2aff> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little16 users; +}; +static_assert(offsetof(NetPacket_Head<0x2aff>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2aff>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2aff>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2aff>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2aff>, users) == 4, "offsetof(NetPacket_Head<0x2aff>, users) == 4"); +static_assert(sizeof(NetPacket_Head<0x2aff>) == 6, "sizeof(NetPacket_Head<0x2aff>) == 6"); +static_assert(alignof(NetPacket_Head<0x2aff>) == 1, "alignof(NetPacket_Head<0x2aff>) == 1"); +template<> +struct NetPacket_Repeat<0x2aff> +{ + Little32 char_id; +}; +static_assert(offsetof(NetPacket_Repeat<0x2aff>, char_id) == 0, "offsetof(NetPacket_Repeat<0x2aff>, char_id) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x2aff>) == 4, "sizeof(NetPacket_Repeat<0x2aff>) == 4"); +static_assert(alignof(NetPacket_Repeat<0x2aff>) == 1, "alignof(NetPacket_Repeat<0x2aff>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b00> +{ + Little16 magic_packet_id; + Little32 users; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b00>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b00>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b00>, users) == 2, "offsetof(NetPacket_Fixed<0x2b00>, users) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2b00>) == 6, "sizeof(NetPacket_Fixed<0x2b00>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x2b00>) == 1, "alignof(NetPacket_Fixed<0x2b00>) == 1"); + +template<> +struct NetPacket_Payload<0x2b01> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; + Little32 char_id; + NetCharKey char_key; + NetCharData char_data; +}; +static_assert(offsetof(NetPacket_Payload<0x2b01>, magic_packet_id) == 0, "offsetof(NetPacket_Payload<0x2b01>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Payload<0x2b01>, magic_packet_length) == 2, "offsetof(NetPacket_Payload<0x2b01>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Payload<0x2b01>, account_id) == 4, "offsetof(NetPacket_Payload<0x2b01>, account_id) == 4"); +static_assert(offsetof(NetPacket_Payload<0x2b01>, char_id) == 8, "offsetof(NetPacket_Payload<0x2b01>, char_id) == 8"); +static_assert(offsetof(NetPacket_Payload<0x2b01>, char_key) == 12, "offsetof(NetPacket_Payload<0x2b01>, char_key) == 12"); +static_assert(alignof(NetPacket_Payload<0x2b01>) == 1, "alignof(NetPacket_Payload<0x2b01>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b02> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 login_id1; + Little32 login_id2; + IP4Address ip; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b02>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b02>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b02>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b02>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b02>, login_id1) == 6, "offsetof(NetPacket_Fixed<0x2b02>, login_id1) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b02>, login_id2) == 10, "offsetof(NetPacket_Fixed<0x2b02>, login_id2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x2b02>, ip) == 14, "offsetof(NetPacket_Fixed<0x2b02>, ip) == 14"); +static_assert(sizeof(NetPacket_Fixed<0x2b02>) == 18, "sizeof(NetPacket_Fixed<0x2b02>) == 18"); +static_assert(alignof(NetPacket_Fixed<0x2b02>) == 1, "alignof(NetPacket_Fixed<0x2b02>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b03> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte unknown; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b03>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b03>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b03>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b03>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b03>, unknown) == 6, "offsetof(NetPacket_Fixed<0x2b03>, unknown) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2b03>) == 7, "sizeof(NetPacket_Fixed<0x2b03>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x2b03>) == 1, "alignof(NetPacket_Fixed<0x2b03>) == 1"); + +template<> +struct NetPacket_Head<0x2b04> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + IP4Address ip; + Little16 port; +}; +static_assert(offsetof(NetPacket_Head<0x2b04>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2b04>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2b04>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2b04>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2b04>, ip) == 4, "offsetof(NetPacket_Head<0x2b04>, ip) == 4"); +static_assert(offsetof(NetPacket_Head<0x2b04>, port) == 8, "offsetof(NetPacket_Head<0x2b04>, port) == 8"); +static_assert(sizeof(NetPacket_Head<0x2b04>) == 10, "sizeof(NetPacket_Head<0x2b04>) == 10"); +static_assert(alignof(NetPacket_Head<0x2b04>) == 1, "alignof(NetPacket_Head<0x2b04>) == 1"); +template<> +struct NetPacket_Repeat<0x2b04> +{ + NetString<sizeof(MapName)> map_name; +}; +static_assert(offsetof(NetPacket_Repeat<0x2b04>, map_name) == 0, "offsetof(NetPacket_Repeat<0x2b04>, map_name) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x2b04>) == 16, "sizeof(NetPacket_Repeat<0x2b04>) == 16"); +static_assert(alignof(NetPacket_Repeat<0x2b04>) == 1, "alignof(NetPacket_Repeat<0x2b04>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b05> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 login_id1; + Little32 login_id2; + Little32 char_id; + NetString<sizeof(MapName)> map_name; + Little16 x; + Little16 y; + IP4Address map_ip; + Little16 map_port; + Byte sex; + IP4Address client_ip; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b05>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b05>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b05>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, login_id1) == 6, "offsetof(NetPacket_Fixed<0x2b05>, login_id1) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, login_id2) == 10, "offsetof(NetPacket_Fixed<0x2b05>, login_id2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, char_id) == 14, "offsetof(NetPacket_Fixed<0x2b05>, char_id) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, map_name) == 18, "offsetof(NetPacket_Fixed<0x2b05>, map_name) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, x) == 34, "offsetof(NetPacket_Fixed<0x2b05>, x) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, y) == 36, "offsetof(NetPacket_Fixed<0x2b05>, y) == 36"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, map_ip) == 38, "offsetof(NetPacket_Fixed<0x2b05>, map_ip) == 38"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, map_port) == 42, "offsetof(NetPacket_Fixed<0x2b05>, map_port) == 42"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, sex) == 44, "offsetof(NetPacket_Fixed<0x2b05>, sex) == 44"); +static_assert(offsetof(NetPacket_Fixed<0x2b05>, client_ip) == 45, "offsetof(NetPacket_Fixed<0x2b05>, client_ip) == 45"); +static_assert(sizeof(NetPacket_Fixed<0x2b05>) == 49, "sizeof(NetPacket_Fixed<0x2b05>) == 49"); +static_assert(alignof(NetPacket_Fixed<0x2b05>) == 1, "alignof(NetPacket_Fixed<0x2b05>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b06> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 error; + Little32 unknown; + Little32 char_id; + NetString<sizeof(MapName)> map_name; + Little16 x; + Little16 y; + IP4Address map_ip; + Little16 map_port; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b06>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b06>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b06>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, error) == 6, "offsetof(NetPacket_Fixed<0x2b06>, error) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, unknown) == 10, "offsetof(NetPacket_Fixed<0x2b06>, unknown) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, char_id) == 14, "offsetof(NetPacket_Fixed<0x2b06>, char_id) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, map_name) == 18, "offsetof(NetPacket_Fixed<0x2b06>, map_name) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, x) == 34, "offsetof(NetPacket_Fixed<0x2b06>, x) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, y) == 36, "offsetof(NetPacket_Fixed<0x2b06>, y) == 36"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, map_ip) == 38, "offsetof(NetPacket_Fixed<0x2b06>, map_ip) == 38"); +static_assert(offsetof(NetPacket_Fixed<0x2b06>, map_port) == 42, "offsetof(NetPacket_Fixed<0x2b06>, map_port) == 42"); +static_assert(sizeof(NetPacket_Fixed<0x2b06>) == 44, "sizeof(NetPacket_Fixed<0x2b06>) == 44"); +static_assert(alignof(NetPacket_Fixed<0x2b06>) == 1, "alignof(NetPacket_Fixed<0x2b06>) == 1"); + +template<> +struct NetPacket_Head<0x2b0a> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x2b0a>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2b0a>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2b0a>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2b0a>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2b0a>, account_id) == 4, "offsetof(NetPacket_Head<0x2b0a>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x2b0a>) == 8, "sizeof(NetPacket_Head<0x2b0a>) == 8"); +static_assert(alignof(NetPacket_Head<0x2b0a>) == 1, "alignof(NetPacket_Head<0x2b0a>) == 1"); +template<> +struct NetPacket_Repeat<0x2b0a> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x2b0a>, c) == 0, "offsetof(NetPacket_Repeat<0x2b0a>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x2b0a>) == 1, "sizeof(NetPacket_Repeat<0x2b0a>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x2b0a>) == 1, "alignof(NetPacket_Repeat<0x2b0a>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b0b> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 gm_level; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b0b>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b0b>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b0b>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b0b>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b0b>, gm_level) == 6, "offsetof(NetPacket_Fixed<0x2b0b>, gm_level) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2b0b>) == 10, "sizeof(NetPacket_Fixed<0x2b0b>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x2b0b>) == 1, "alignof(NetPacket_Fixed<0x2b0b>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b0c> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountEmail)> old_email; + NetString<sizeof(AccountEmail)> new_email; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b0c>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b0c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b0c>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b0c>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b0c>, old_email) == 6, "offsetof(NetPacket_Fixed<0x2b0c>, old_email) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b0c>, new_email) == 46, "offsetof(NetPacket_Fixed<0x2b0c>, new_email) == 46"); +static_assert(sizeof(NetPacket_Fixed<0x2b0c>) == 86, "sizeof(NetPacket_Fixed<0x2b0c>) == 86"); +static_assert(alignof(NetPacket_Fixed<0x2b0c>) == 1, "alignof(NetPacket_Fixed<0x2b0c>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b0d> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte sex; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b0d>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b0d>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b0d>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b0d>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b0d>, sex) == 6, "offsetof(NetPacket_Fixed<0x2b0d>, sex) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2b0d>) == 7, "sizeof(NetPacket_Fixed<0x2b0d>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x2b0d>) == 1, "alignof(NetPacket_Fixed<0x2b0d>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b0e> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(CharName)> char_name; + Little16 operation; + NetHumanTimeDiff ban_add; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b0e>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b0e>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b0e>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b0e>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b0e>, char_name) == 6, "offsetof(NetPacket_Fixed<0x2b0e>, char_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b0e>, operation) == 30, "offsetof(NetPacket_Fixed<0x2b0e>, operation) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x2b0e>, ban_add) == 32, "offsetof(NetPacket_Fixed<0x2b0e>, ban_add) == 32"); +static_assert(sizeof(NetPacket_Fixed<0x2b0e>) == 44, "sizeof(NetPacket_Fixed<0x2b0e>) == 44"); +static_assert(alignof(NetPacket_Fixed<0x2b0e>) == 1, "alignof(NetPacket_Fixed<0x2b0e>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b0f> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(CharName)> char_name; + Little16 operation; + Little16 error; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b0f>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b0f>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b0f>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b0f>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b0f>, char_name) == 6, "offsetof(NetPacket_Fixed<0x2b0f>, char_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b0f>, operation) == 30, "offsetof(NetPacket_Fixed<0x2b0f>, operation) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x2b0f>, error) == 32, "offsetof(NetPacket_Fixed<0x2b0f>, error) == 32"); +static_assert(sizeof(NetPacket_Fixed<0x2b0f>) == 34, "sizeof(NetPacket_Fixed<0x2b0f>) == 34"); +static_assert(alignof(NetPacket_Fixed<0x2b0f>) == 1, "alignof(NetPacket_Fixed<0x2b0f>) == 1"); + +template<> +struct NetPacket_Head<0x2b10> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x2b10>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2b10>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2b10>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2b10>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2b10>, account_id) == 4, "offsetof(NetPacket_Head<0x2b10>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x2b10>) == 8, "sizeof(NetPacket_Head<0x2b10>) == 8"); +static_assert(alignof(NetPacket_Head<0x2b10>) == 1, "alignof(NetPacket_Head<0x2b10>) == 1"); +template<> +struct NetPacket_Repeat<0x2b10> +{ + NetString<sizeof(VarName)> name; + Little32 value; +}; +static_assert(offsetof(NetPacket_Repeat<0x2b10>, name) == 0, "offsetof(NetPacket_Repeat<0x2b10>, name) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x2b10>, value) == 32, "offsetof(NetPacket_Repeat<0x2b10>, value) == 32"); +static_assert(sizeof(NetPacket_Repeat<0x2b10>) == 36, "sizeof(NetPacket_Repeat<0x2b10>) == 36"); +static_assert(alignof(NetPacket_Repeat<0x2b10>) == 1, "alignof(NetPacket_Repeat<0x2b10>) == 1"); + +template<> +struct NetPacket_Head<0x2b11> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x2b11>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2b11>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2b11>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2b11>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2b11>, account_id) == 4, "offsetof(NetPacket_Head<0x2b11>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x2b11>) == 8, "sizeof(NetPacket_Head<0x2b11>) == 8"); +static_assert(alignof(NetPacket_Head<0x2b11>) == 1, "alignof(NetPacket_Head<0x2b11>) == 1"); +template<> +struct NetPacket_Repeat<0x2b11> +{ + NetString<sizeof(VarName)> name; + Little32 value; +}; +static_assert(offsetof(NetPacket_Repeat<0x2b11>, name) == 0, "offsetof(NetPacket_Repeat<0x2b11>, name) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x2b11>, value) == 32, "offsetof(NetPacket_Repeat<0x2b11>, value) == 32"); +static_assert(sizeof(NetPacket_Repeat<0x2b11>) == 36, "sizeof(NetPacket_Repeat<0x2b11>) == 36"); +static_assert(alignof(NetPacket_Repeat<0x2b11>) == 1, "alignof(NetPacket_Repeat<0x2b11>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b12> +{ + Little16 magic_packet_id; + Little32 char_id; + Little32 partner_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b12>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b12>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b12>, char_id) == 2, "offsetof(NetPacket_Fixed<0x2b12>, char_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b12>, partner_id) == 6, "offsetof(NetPacket_Fixed<0x2b12>, partner_id) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2b12>) == 10, "sizeof(NetPacket_Fixed<0x2b12>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x2b12>) == 1, "alignof(NetPacket_Fixed<0x2b12>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b13> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b13>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b13>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b13>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b13>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2b13>) == 6, "sizeof(NetPacket_Fixed<0x2b13>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x2b13>) == 1, "alignof(NetPacket_Fixed<0x2b13>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b14> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte ban_not_status; + Little32 status_or_ban_until; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b14>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b14>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b14>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2b14>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2b14>, ban_not_status) == 6, "offsetof(NetPacket_Fixed<0x2b14>, ban_not_status) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2b14>, status_or_ban_until) == 7, "offsetof(NetPacket_Fixed<0x2b14>, status_or_ban_until) == 7"); +static_assert(sizeof(NetPacket_Fixed<0x2b14>) == 11, "sizeof(NetPacket_Fixed<0x2b14>) == 11"); +static_assert(alignof(NetPacket_Fixed<0x2b14>) == 1, "alignof(NetPacket_Fixed<0x2b14>) == 1"); + +template<> +struct NetPacket_Head<0x2b15> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x2b15>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2b15>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2b15>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2b15>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x2b15>) == 4, "sizeof(NetPacket_Head<0x2b15>) == 4"); +static_assert(alignof(NetPacket_Head<0x2b15>) == 1, "alignof(NetPacket_Head<0x2b15>) == 1"); +template<> +struct NetPacket_Repeat<0x2b15> +{ + Little32 account_id; + Byte gm_level; +}; +static_assert(offsetof(NetPacket_Repeat<0x2b15>, account_id) == 0, "offsetof(NetPacket_Repeat<0x2b15>, account_id) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x2b15>, gm_level) == 4, "offsetof(NetPacket_Repeat<0x2b15>, gm_level) == 4"); +static_assert(sizeof(NetPacket_Repeat<0x2b15>) == 5, "sizeof(NetPacket_Repeat<0x2b15>) == 5"); +static_assert(alignof(NetPacket_Repeat<0x2b15>) == 1, "alignof(NetPacket_Repeat<0x2b15>) == 1"); + +template<> +struct NetPacket_Fixed<0x2b16> +{ + Little16 magic_packet_id; + Little32 char_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2b16>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2b16>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2b16>, char_id) == 2, "offsetof(NetPacket_Fixed<0x2b16>, char_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2b16>) == 6, "sizeof(NetPacket_Fixed<0x2b16>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x2b16>) == 1, "alignof(NetPacket_Fixed<0x2b16>) == 1"); + +template<> +struct NetPacket_Head<0x3000> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x3000>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3000>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3000>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3000>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x3000>) == 4, "sizeof(NetPacket_Head<0x3000>) == 4"); +static_assert(alignof(NetPacket_Head<0x3000>) == 1, "alignof(NetPacket_Head<0x3000>) == 1"); +template<> +struct NetPacket_Repeat<0x3000> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3000>, c) == 0, "offsetof(NetPacket_Repeat<0x3000>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3000>) == 1, "sizeof(NetPacket_Repeat<0x3000>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x3000>) == 1, "alignof(NetPacket_Repeat<0x3000>) == 1"); + +template<> +struct NetPacket_Head<0x3001> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + NetString<sizeof(CharName)> from_char_name; + NetString<sizeof(CharName)> to_char_name; +}; +static_assert(offsetof(NetPacket_Head<0x3001>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3001>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3001>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3001>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3001>, from_char_name) == 4, "offsetof(NetPacket_Head<0x3001>, from_char_name) == 4"); +static_assert(offsetof(NetPacket_Head<0x3001>, to_char_name) == 28, "offsetof(NetPacket_Head<0x3001>, to_char_name) == 28"); +static_assert(sizeof(NetPacket_Head<0x3001>) == 52, "sizeof(NetPacket_Head<0x3001>) == 52"); +static_assert(alignof(NetPacket_Head<0x3001>) == 1, "alignof(NetPacket_Head<0x3001>) == 1"); +template<> +struct NetPacket_Repeat<0x3001> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3001>, c) == 0, "offsetof(NetPacket_Repeat<0x3001>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3001>) == 1, "sizeof(NetPacket_Repeat<0x3001>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x3001>) == 1, "alignof(NetPacket_Repeat<0x3001>) == 1"); + +template<> +struct NetPacket_Fixed<0x3002> +{ + Little16 magic_packet_id; + Little32 char_id; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x3002>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3002>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3002>, char_id) == 2, "offsetof(NetPacket_Fixed<0x3002>, char_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3002>, flag) == 6, "offsetof(NetPacket_Fixed<0x3002>, flag) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x3002>) == 7, "sizeof(NetPacket_Fixed<0x3002>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x3002>) == 1, "alignof(NetPacket_Fixed<0x3002>) == 1"); + +template<> +struct NetPacket_Head<0x3003> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + NetString<sizeof(CharName)> char_name; + Little16 min_gm_level; +}; +static_assert(offsetof(NetPacket_Head<0x3003>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3003>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3003>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3003>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3003>, char_name) == 4, "offsetof(NetPacket_Head<0x3003>, char_name) == 4"); +static_assert(offsetof(NetPacket_Head<0x3003>, min_gm_level) == 28, "offsetof(NetPacket_Head<0x3003>, min_gm_level) == 28"); +static_assert(sizeof(NetPacket_Head<0x3003>) == 30, "sizeof(NetPacket_Head<0x3003>) == 30"); +static_assert(alignof(NetPacket_Head<0x3003>) == 1, "alignof(NetPacket_Head<0x3003>) == 1"); +template<> +struct NetPacket_Repeat<0x3003> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3003>, c) == 0, "offsetof(NetPacket_Repeat<0x3003>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3003>) == 1, "sizeof(NetPacket_Repeat<0x3003>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x3003>) == 1, "alignof(NetPacket_Repeat<0x3003>) == 1"); + +template<> +struct NetPacket_Head<0x3004> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x3004>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3004>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3004>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3004>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3004>, account_id) == 4, "offsetof(NetPacket_Head<0x3004>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x3004>) == 8, "sizeof(NetPacket_Head<0x3004>) == 8"); +static_assert(alignof(NetPacket_Head<0x3004>) == 1, "alignof(NetPacket_Head<0x3004>) == 1"); +template<> +struct NetPacket_Repeat<0x3004> +{ + NetString<sizeof(VarName)> name; + Little32 value; +}; +static_assert(offsetof(NetPacket_Repeat<0x3004>, name) == 0, "offsetof(NetPacket_Repeat<0x3004>, name) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x3004>, value) == 32, "offsetof(NetPacket_Repeat<0x3004>, value) == 32"); +static_assert(sizeof(NetPacket_Repeat<0x3004>) == 36, "sizeof(NetPacket_Repeat<0x3004>) == 36"); +static_assert(alignof(NetPacket_Repeat<0x3004>) == 1, "alignof(NetPacket_Repeat<0x3004>) == 1"); + +template<> +struct NetPacket_Fixed<0x3005> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x3005>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3005>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3005>, account_id) == 2, "offsetof(NetPacket_Fixed<0x3005>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x3005>) == 6, "sizeof(NetPacket_Fixed<0x3005>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x3005>) == 1, "alignof(NetPacket_Fixed<0x3005>) == 1"); + +template<> +struct NetPacket_Fixed<0x3010> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x3010>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3010>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3010>, account_id) == 2, "offsetof(NetPacket_Fixed<0x3010>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x3010>) == 6, "sizeof(NetPacket_Fixed<0x3010>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x3010>) == 1, "alignof(NetPacket_Fixed<0x3010>) == 1"); + +template<> +struct NetPacket_Payload<0x3011> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; + NetStorage storage; +}; +static_assert(offsetof(NetPacket_Payload<0x3011>, magic_packet_id) == 0, "offsetof(NetPacket_Payload<0x3011>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Payload<0x3011>, magic_packet_length) == 2, "offsetof(NetPacket_Payload<0x3011>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Payload<0x3011>, account_id) == 4, "offsetof(NetPacket_Payload<0x3011>, account_id) == 4"); +static_assert(offsetof(NetPacket_Payload<0x3011>, storage) == 8, "offsetof(NetPacket_Payload<0x3011>, storage) == 8"); +static_assert(alignof(NetPacket_Payload<0x3011>) == 1, "alignof(NetPacket_Payload<0x3011>) == 1"); + +template<> +struct NetPacket_Fixed<0x3020> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(PartyName)> party_name; + NetString<sizeof(CharName)> char_name; + NetString<sizeof(MapName)> map_name; + Little16 level; +}; +static_assert(offsetof(NetPacket_Fixed<0x3020>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3020>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3020>, account_id) == 2, "offsetof(NetPacket_Fixed<0x3020>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3020>, party_name) == 6, "offsetof(NetPacket_Fixed<0x3020>, party_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3020>, char_name) == 30, "offsetof(NetPacket_Fixed<0x3020>, char_name) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x3020>, map_name) == 54, "offsetof(NetPacket_Fixed<0x3020>, map_name) == 54"); +static_assert(offsetof(NetPacket_Fixed<0x3020>, level) == 70, "offsetof(NetPacket_Fixed<0x3020>, level) == 70"); +static_assert(sizeof(NetPacket_Fixed<0x3020>) == 72, "sizeof(NetPacket_Fixed<0x3020>) == 72"); +static_assert(alignof(NetPacket_Fixed<0x3020>) == 1, "alignof(NetPacket_Fixed<0x3020>) == 1"); + +template<> +struct NetPacket_Fixed<0x3021> +{ + Little16 magic_packet_id; + Little32 party_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x3021>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3021>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3021>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3021>, party_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x3021>) == 6, "sizeof(NetPacket_Fixed<0x3021>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x3021>) == 1, "alignof(NetPacket_Fixed<0x3021>) == 1"); + +template<> +struct NetPacket_Fixed<0x3022> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + NetString<sizeof(CharName)> char_name; + NetString<sizeof(MapName)> map_name; + Little16 level; +}; +static_assert(offsetof(NetPacket_Fixed<0x3022>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3022>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3022>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3022>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3022>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3022>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3022>, char_name) == 10, "offsetof(NetPacket_Fixed<0x3022>, char_name) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x3022>, map_name) == 34, "offsetof(NetPacket_Fixed<0x3022>, map_name) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x3022>, level) == 50, "offsetof(NetPacket_Fixed<0x3022>, level) == 50"); +static_assert(sizeof(NetPacket_Fixed<0x3022>) == 52, "sizeof(NetPacket_Fixed<0x3022>) == 52"); +static_assert(alignof(NetPacket_Fixed<0x3022>) == 1, "alignof(NetPacket_Fixed<0x3022>) == 1"); + +template<> +struct NetPacket_Fixed<0x3023> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + Little16 exp; + Little16 item; +}; +static_assert(offsetof(NetPacket_Fixed<0x3023>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3023>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3023>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3023>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3023>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3023>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3023>, exp) == 10, "offsetof(NetPacket_Fixed<0x3023>, exp) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x3023>, item) == 12, "offsetof(NetPacket_Fixed<0x3023>, item) == 12"); +static_assert(sizeof(NetPacket_Fixed<0x3023>) == 14, "sizeof(NetPacket_Fixed<0x3023>) == 14"); +static_assert(alignof(NetPacket_Fixed<0x3023>) == 1, "alignof(NetPacket_Fixed<0x3023>) == 1"); + +template<> +struct NetPacket_Fixed<0x3024> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x3024>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3024>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3024>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3024>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3024>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3024>, account_id) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x3024>) == 10, "sizeof(NetPacket_Fixed<0x3024>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x3024>) == 1, "alignof(NetPacket_Fixed<0x3024>) == 1"); + +template<> +struct NetPacket_Fixed<0x3025> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + NetString<sizeof(MapName)> map_name; + Byte online; + Little16 level; +}; +static_assert(offsetof(NetPacket_Fixed<0x3025>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3025>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3025>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3025>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3025>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3025>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3025>, map_name) == 10, "offsetof(NetPacket_Fixed<0x3025>, map_name) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x3025>, online) == 26, "offsetof(NetPacket_Fixed<0x3025>, online) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x3025>, level) == 27, "offsetof(NetPacket_Fixed<0x3025>, level) == 27"); +static_assert(sizeof(NetPacket_Fixed<0x3025>) == 29, "sizeof(NetPacket_Fixed<0x3025>) == 29"); +static_assert(alignof(NetPacket_Fixed<0x3025>) == 1, "alignof(NetPacket_Fixed<0x3025>) == 1"); + +template<> +struct NetPacket_Head<0x3027> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 party_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x3027>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3027>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3027>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3027>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3027>, party_id) == 4, "offsetof(NetPacket_Head<0x3027>, party_id) == 4"); +static_assert(offsetof(NetPacket_Head<0x3027>, account_id) == 8, "offsetof(NetPacket_Head<0x3027>, account_id) == 8"); +static_assert(sizeof(NetPacket_Head<0x3027>) == 12, "sizeof(NetPacket_Head<0x3027>) == 12"); +static_assert(alignof(NetPacket_Head<0x3027>) == 1, "alignof(NetPacket_Head<0x3027>) == 1"); +template<> +struct NetPacket_Repeat<0x3027> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3027>, c) == 0, "offsetof(NetPacket_Repeat<0x3027>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3027>) == 1, "sizeof(NetPacket_Repeat<0x3027>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x3027>) == 1, "alignof(NetPacket_Repeat<0x3027>) == 1"); + +template<> +struct NetPacket_Fixed<0x3028> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + NetString<sizeof(CharName)> char_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x3028>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3028>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3028>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3028>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3028>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3028>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3028>, char_name) == 10, "offsetof(NetPacket_Fixed<0x3028>, char_name) == 10"); +static_assert(sizeof(NetPacket_Fixed<0x3028>) == 34, "sizeof(NetPacket_Fixed<0x3028>) == 34"); +static_assert(alignof(NetPacket_Fixed<0x3028>) == 1, "alignof(NetPacket_Fixed<0x3028>) == 1"); + +template<> +struct NetPacket_Head<0x3800> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x3800>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3800>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3800>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3800>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x3800>) == 4, "sizeof(NetPacket_Head<0x3800>) == 4"); +static_assert(alignof(NetPacket_Head<0x3800>) == 1, "alignof(NetPacket_Head<0x3800>) == 1"); +template<> +struct NetPacket_Repeat<0x3800> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3800>, c) == 0, "offsetof(NetPacket_Repeat<0x3800>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3800>) == 1, "sizeof(NetPacket_Repeat<0x3800>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x3800>) == 1, "alignof(NetPacket_Repeat<0x3800>) == 1"); + +template<> +struct NetPacket_Head<0x3801> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 whisper_id; + NetString<sizeof(CharName)> src_char_name; + NetString<sizeof(CharName)> dst_char_name; +}; +static_assert(offsetof(NetPacket_Head<0x3801>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3801>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3801>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3801>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3801>, whisper_id) == 4, "offsetof(NetPacket_Head<0x3801>, whisper_id) == 4"); +static_assert(offsetof(NetPacket_Head<0x3801>, src_char_name) == 8, "offsetof(NetPacket_Head<0x3801>, src_char_name) == 8"); +static_assert(offsetof(NetPacket_Head<0x3801>, dst_char_name) == 32, "offsetof(NetPacket_Head<0x3801>, dst_char_name) == 32"); +static_assert(sizeof(NetPacket_Head<0x3801>) == 56, "sizeof(NetPacket_Head<0x3801>) == 56"); +static_assert(alignof(NetPacket_Head<0x3801>) == 1, "alignof(NetPacket_Head<0x3801>) == 1"); +template<> +struct NetPacket_Repeat<0x3801> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3801>, c) == 0, "offsetof(NetPacket_Repeat<0x3801>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3801>) == 1, "sizeof(NetPacket_Repeat<0x3801>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x3801>) == 1, "alignof(NetPacket_Repeat<0x3801>) == 1"); + +template<> +struct NetPacket_Fixed<0x3802> +{ + Little16 magic_packet_id; + NetString<sizeof(CharName)> sender_char_name; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x3802>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3802>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3802>, sender_char_name) == 2, "offsetof(NetPacket_Fixed<0x3802>, sender_char_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3802>, flag) == 26, "offsetof(NetPacket_Fixed<0x3802>, flag) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x3802>) == 27, "sizeof(NetPacket_Fixed<0x3802>) == 27"); +static_assert(alignof(NetPacket_Fixed<0x3802>) == 1, "alignof(NetPacket_Fixed<0x3802>) == 1"); + +template<> +struct NetPacket_Head<0x3803> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + NetString<sizeof(CharName)> char_name; + Little16 min_gm_level; +}; +static_assert(offsetof(NetPacket_Head<0x3803>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3803>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3803>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3803>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3803>, char_name) == 4, "offsetof(NetPacket_Head<0x3803>, char_name) == 4"); +static_assert(offsetof(NetPacket_Head<0x3803>, min_gm_level) == 28, "offsetof(NetPacket_Head<0x3803>, min_gm_level) == 28"); +static_assert(sizeof(NetPacket_Head<0x3803>) == 30, "sizeof(NetPacket_Head<0x3803>) == 30"); +static_assert(alignof(NetPacket_Head<0x3803>) == 1, "alignof(NetPacket_Head<0x3803>) == 1"); +template<> +struct NetPacket_Repeat<0x3803> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3803>, c) == 0, "offsetof(NetPacket_Repeat<0x3803>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3803>) == 1, "sizeof(NetPacket_Repeat<0x3803>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x3803>) == 1, "alignof(NetPacket_Repeat<0x3803>) == 1"); + +template<> +struct NetPacket_Head<0x3804> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x3804>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3804>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3804>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3804>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3804>, account_id) == 4, "offsetof(NetPacket_Head<0x3804>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x3804>) == 8, "sizeof(NetPacket_Head<0x3804>) == 8"); +static_assert(alignof(NetPacket_Head<0x3804>) == 1, "alignof(NetPacket_Head<0x3804>) == 1"); +template<> +struct NetPacket_Repeat<0x3804> +{ + NetString<sizeof(VarName)> name; + Little32 value; +}; +static_assert(offsetof(NetPacket_Repeat<0x3804>, name) == 0, "offsetof(NetPacket_Repeat<0x3804>, name) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x3804>, value) == 32, "offsetof(NetPacket_Repeat<0x3804>, value) == 32"); +static_assert(sizeof(NetPacket_Repeat<0x3804>) == 36, "sizeof(NetPacket_Repeat<0x3804>) == 36"); +static_assert(alignof(NetPacket_Repeat<0x3804>) == 1, "alignof(NetPacket_Repeat<0x3804>) == 1"); + +template<> +struct NetPacket_Payload<0x3810> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; + NetStorage storage; +}; +static_assert(offsetof(NetPacket_Payload<0x3810>, magic_packet_id) == 0, "offsetof(NetPacket_Payload<0x3810>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Payload<0x3810>, magic_packet_length) == 2, "offsetof(NetPacket_Payload<0x3810>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Payload<0x3810>, account_id) == 4, "offsetof(NetPacket_Payload<0x3810>, account_id) == 4"); +static_assert(offsetof(NetPacket_Payload<0x3810>, storage) == 8, "offsetof(NetPacket_Payload<0x3810>, storage) == 8"); +static_assert(alignof(NetPacket_Payload<0x3810>) == 1, "alignof(NetPacket_Payload<0x3810>) == 1"); + +template<> +struct NetPacket_Fixed<0x3811> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte unknown; +}; +static_assert(offsetof(NetPacket_Fixed<0x3811>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3811>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3811>, account_id) == 2, "offsetof(NetPacket_Fixed<0x3811>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3811>, unknown) == 6, "offsetof(NetPacket_Fixed<0x3811>, unknown) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x3811>) == 7, "sizeof(NetPacket_Fixed<0x3811>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x3811>) == 1, "alignof(NetPacket_Fixed<0x3811>) == 1"); + +template<> +struct NetPacket_Fixed<0x3820> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte error; + Little32 party_id; + NetString<sizeof(PartyName)> party_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x3820>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3820>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3820>, account_id) == 2, "offsetof(NetPacket_Fixed<0x3820>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3820>, error) == 6, "offsetof(NetPacket_Fixed<0x3820>, error) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3820>, party_id) == 7, "offsetof(NetPacket_Fixed<0x3820>, party_id) == 7"); +static_assert(offsetof(NetPacket_Fixed<0x3820>, party_name) == 11, "offsetof(NetPacket_Fixed<0x3820>, party_name) == 11"); +static_assert(sizeof(NetPacket_Fixed<0x3820>) == 35, "sizeof(NetPacket_Fixed<0x3820>) == 35"); +static_assert(alignof(NetPacket_Fixed<0x3820>) == 1, "alignof(NetPacket_Fixed<0x3820>) == 1"); + +template<> +struct NetPacket_Head<0x3821> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 party_id; +}; +static_assert(offsetof(NetPacket_Head<0x3821>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3821>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3821>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3821>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3821>, party_id) == 4, "offsetof(NetPacket_Head<0x3821>, party_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x3821>) == 8, "sizeof(NetPacket_Head<0x3821>) == 8"); +static_assert(alignof(NetPacket_Head<0x3821>) == 1, "alignof(NetPacket_Head<0x3821>) == 1"); +template<> +struct NetPacket_Option<0x3821> +{ + NetPartyMost party_most; +}; +static_assert(offsetof(NetPacket_Option<0x3821>, party_most) == 0, "offsetof(NetPacket_Option<0x3821>, party_most) == 0"); +static_assert(alignof(NetPacket_Option<0x3821>) == 1, "alignof(NetPacket_Option<0x3821>) == 1"); + +template<> +struct NetPacket_Fixed<0x3822> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x3822>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3822>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3822>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3822>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3822>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3822>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3822>, flag) == 10, "offsetof(NetPacket_Fixed<0x3822>, flag) == 10"); +static_assert(sizeof(NetPacket_Fixed<0x3822>) == 11, "sizeof(NetPacket_Fixed<0x3822>) == 11"); +static_assert(alignof(NetPacket_Fixed<0x3822>) == 1, "alignof(NetPacket_Fixed<0x3822>) == 1"); + +template<> +struct NetPacket_Fixed<0x3823> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + Little16 exp; + Little16 item; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x3823>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3823>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3823>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3823>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3823>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3823>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3823>, exp) == 10, "offsetof(NetPacket_Fixed<0x3823>, exp) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x3823>, item) == 12, "offsetof(NetPacket_Fixed<0x3823>, item) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x3823>, flag) == 14, "offsetof(NetPacket_Fixed<0x3823>, flag) == 14"); +static_assert(sizeof(NetPacket_Fixed<0x3823>) == 15, "sizeof(NetPacket_Fixed<0x3823>) == 15"); +static_assert(alignof(NetPacket_Fixed<0x3823>) == 1, "alignof(NetPacket_Fixed<0x3823>) == 1"); + +template<> +struct NetPacket_Fixed<0x3824> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + NetString<sizeof(CharName)> char_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x3824>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3824>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3824>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3824>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3824>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3824>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3824>, char_name) == 10, "offsetof(NetPacket_Fixed<0x3824>, char_name) == 10"); +static_assert(sizeof(NetPacket_Fixed<0x3824>) == 34, "sizeof(NetPacket_Fixed<0x3824>) == 34"); +static_assert(alignof(NetPacket_Fixed<0x3824>) == 1, "alignof(NetPacket_Fixed<0x3824>) == 1"); + +template<> +struct NetPacket_Fixed<0x3825> +{ + Little16 magic_packet_id; + Little32 party_id; + Little32 account_id; + NetString<sizeof(MapName)> map_name; + Byte online; + Little16 level; +}; +static_assert(offsetof(NetPacket_Fixed<0x3825>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3825>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3825>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3825>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3825>, account_id) == 6, "offsetof(NetPacket_Fixed<0x3825>, account_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x3825>, map_name) == 10, "offsetof(NetPacket_Fixed<0x3825>, map_name) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x3825>, online) == 26, "offsetof(NetPacket_Fixed<0x3825>, online) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x3825>, level) == 27, "offsetof(NetPacket_Fixed<0x3825>, level) == 27"); +static_assert(sizeof(NetPacket_Fixed<0x3825>) == 29, "sizeof(NetPacket_Fixed<0x3825>) == 29"); +static_assert(alignof(NetPacket_Fixed<0x3825>) == 1, "alignof(NetPacket_Fixed<0x3825>) == 1"); + +template<> +struct NetPacket_Fixed<0x3826> +{ + Little16 magic_packet_id; + Little32 party_id; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x3826>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x3826>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x3826>, party_id) == 2, "offsetof(NetPacket_Fixed<0x3826>, party_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x3826>, flag) == 6, "offsetof(NetPacket_Fixed<0x3826>, flag) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x3826>) == 7, "sizeof(NetPacket_Fixed<0x3826>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x3826>) == 1, "alignof(NetPacket_Fixed<0x3826>) == 1"); + +template<> +struct NetPacket_Head<0x3827> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 party_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x3827>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x3827>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x3827>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x3827>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x3827>, party_id) == 4, "offsetof(NetPacket_Head<0x3827>, party_id) == 4"); +static_assert(offsetof(NetPacket_Head<0x3827>, account_id) == 8, "offsetof(NetPacket_Head<0x3827>, account_id) == 8"); +static_assert(sizeof(NetPacket_Head<0x3827>) == 12, "sizeof(NetPacket_Head<0x3827>) == 12"); +static_assert(alignof(NetPacket_Head<0x3827>) == 1, "alignof(NetPacket_Head<0x3827>) == 1"); +template<> +struct NetPacket_Repeat<0x3827> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x3827>, c) == 0, "offsetof(NetPacket_Repeat<0x3827>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x3827>) == 1, "sizeof(NetPacket_Repeat<0x3827>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x3827>) == 1, "alignof(NetPacket_Repeat<0x3827>) == 1"); + + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2af7> *network, Packet_Fixed<0x2af7> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2af7> *native, NetPacket_Fixed<0x2af7> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2af8> *network, Packet_Fixed<0x2af8> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->account_pass, native.account_pass); + rv &= native_to_network(&network->unused, native.unused); + rv &= native_to_network(&network->ip, native.ip); + rv &= native_to_network(&network->port, native.port); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2af8> *native, NetPacket_Fixed<0x2af8> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->account_pass, network.account_pass); + rv &= network_to_native(&native->unused, network.unused); + rv &= network_to_native(&native->ip, network.ip); + rv &= network_to_native(&native->port, network.port); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2af9> *network, Packet_Fixed<0x2af9> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->code, native.code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2af9> *native, NetPacket_Fixed<0x2af9> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->code, network.code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2afa> *network, Packet_Head<0x2afa> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2afa> *native, NetPacket_Head<0x2afa> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2afa> *network, Packet_Repeat<0x2afa> native) +{ + bool rv = true; + rv &= native_to_network(&network->map_name, native.map_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2afa> *native, NetPacket_Repeat<0x2afa> network) +{ + bool rv = true; + rv &= network_to_native(&native->map_name, network.map_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2afa> *network, Packet_Fixed<0x2afa> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->source_item_id, native.source_item_id); + rv &= native_to_network(&network->dest_item_id, native.dest_item_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2afa> *native, NetPacket_Fixed<0x2afa> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->source_item_id, network.source_item_id); + rv &= network_to_native(&native->dest_item_id, network.dest_item_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2afb> *network, Packet_Fixed<0x2afb> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->unknown, native.unknown); + rv &= native_to_network(&network->whisper_name, native.whisper_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2afb> *native, NetPacket_Fixed<0x2afb> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->unknown, network.unknown); + rv &= network_to_native(&native->whisper_name, network.whisper_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2afc> *network, Packet_Fixed<0x2afc> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->login_id1, native.login_id1); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->ip, native.ip); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2afc> *native, NetPacket_Fixed<0x2afc> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->login_id1, network.login_id1); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->ip, network.ip); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Payload<0x2afd> *network, Packet_Payload<0x2afd> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->connect_until, native.connect_until); + rv &= native_to_network(&network->packet_tmw_version, native.packet_tmw_version); + rv &= native_to_network(&network->char_key, native.char_key); + rv &= native_to_network(&network->char_data, native.char_data); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Payload<0x2afd> *native, NetPacket_Payload<0x2afd> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->connect_until, network.connect_until); + rv &= network_to_native(&native->packet_tmw_version, network.packet_tmw_version); + rv &= network_to_native(&native->char_key, network.char_key); + rv &= network_to_native(&native->char_data, network.char_data); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2afe> *network, Packet_Fixed<0x2afe> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2afe> *native, NetPacket_Fixed<0x2afe> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2aff> *network, Packet_Head<0x2aff> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->users, native.users); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2aff> *native, NetPacket_Head<0x2aff> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->users, network.users); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2aff> *network, Packet_Repeat<0x2aff> native) +{ + bool rv = true; + rv &= native_to_network(&network->char_id, native.char_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2aff> *native, NetPacket_Repeat<0x2aff> network) +{ + bool rv = true; + rv &= network_to_native(&native->char_id, network.char_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b00> *network, Packet_Fixed<0x2b00> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->users, native.users); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b00> *native, NetPacket_Fixed<0x2b00> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->users, network.users); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Payload<0x2b01> *network, Packet_Payload<0x2b01> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->char_key, native.char_key); + rv &= native_to_network(&network->char_data, native.char_data); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Payload<0x2b01> *native, NetPacket_Payload<0x2b01> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->char_key, network.char_key); + rv &= network_to_native(&native->char_data, network.char_data); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b02> *network, Packet_Fixed<0x2b02> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->login_id1, native.login_id1); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->ip, native.ip); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b02> *native, NetPacket_Fixed<0x2b02> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->login_id1, network.login_id1); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->ip, network.ip); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b03> *network, Packet_Fixed<0x2b03> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->unknown, native.unknown); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b03> *native, NetPacket_Fixed<0x2b03> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->unknown, network.unknown); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2b04> *network, Packet_Head<0x2b04> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->ip, native.ip); + rv &= native_to_network(&network->port, native.port); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2b04> *native, NetPacket_Head<0x2b04> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->ip, network.ip); + rv &= network_to_native(&native->port, network.port); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2b04> *network, Packet_Repeat<0x2b04> native) +{ + bool rv = true; + rv &= native_to_network(&network->map_name, native.map_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2b04> *native, NetPacket_Repeat<0x2b04> network) +{ + bool rv = true; + rv &= network_to_native(&native->map_name, network.map_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b05> *network, Packet_Fixed<0x2b05> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->login_id1, native.login_id1); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + rv &= native_to_network(&network->map_ip, native.map_ip); + rv &= native_to_network(&network->map_port, native.map_port); + rv &= native_to_network(&network->sex, native.sex); + rv &= native_to_network(&network->client_ip, native.client_ip); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b05> *native, NetPacket_Fixed<0x2b05> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->login_id1, network.login_id1); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + rv &= network_to_native(&native->map_ip, network.map_ip); + rv &= network_to_native(&native->map_port, network.map_port); + rv &= network_to_native(&native->sex, network.sex); + rv &= network_to_native(&native->client_ip, network.client_ip); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b06> *network, Packet_Fixed<0x2b06> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->error, native.error); + rv &= native_to_network(&network->unknown, native.unknown); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + rv &= native_to_network(&network->map_ip, native.map_ip); + rv &= native_to_network(&network->map_port, native.map_port); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b06> *native, NetPacket_Fixed<0x2b06> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->error, network.error); + rv &= network_to_native(&native->unknown, network.unknown); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + rv &= network_to_native(&native->map_ip, network.map_ip); + rv &= network_to_native(&native->map_port, network.map_port); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2b0a> *network, Packet_Head<0x2b0a> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2b0a> *native, NetPacket_Head<0x2b0a> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2b0a> *network, Packet_Repeat<0x2b0a> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2b0a> *native, NetPacket_Repeat<0x2b0a> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b0b> *network, Packet_Fixed<0x2b0b> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->gm_level, native.gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b0b> *native, NetPacket_Fixed<0x2b0b> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->gm_level, network.gm_level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b0c> *network, Packet_Fixed<0x2b0c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->old_email, native.old_email); + rv &= native_to_network(&network->new_email, native.new_email); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b0c> *native, NetPacket_Fixed<0x2b0c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->old_email, network.old_email); + rv &= network_to_native(&native->new_email, network.new_email); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b0d> *network, Packet_Fixed<0x2b0d> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->sex, native.sex); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b0d> *native, NetPacket_Fixed<0x2b0d> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->sex, network.sex); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b0e> *network, Packet_Fixed<0x2b0e> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->operation, native.operation); + rv &= native_to_network(&network->ban_add, native.ban_add); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b0e> *native, NetPacket_Fixed<0x2b0e> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->operation, network.operation); + rv &= network_to_native(&native->ban_add, network.ban_add); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b0f> *network, Packet_Fixed<0x2b0f> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->operation, native.operation); + rv &= native_to_network(&network->error, native.error); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b0f> *native, NetPacket_Fixed<0x2b0f> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->operation, network.operation); + rv &= network_to_native(&native->error, network.error); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2b10> *network, Packet_Head<0x2b10> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2b10> *native, NetPacket_Head<0x2b10> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2b10> *network, Packet_Repeat<0x2b10> native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2b10> *native, NetPacket_Repeat<0x2b10> network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2b11> *network, Packet_Head<0x2b11> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2b11> *native, NetPacket_Head<0x2b11> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2b11> *network, Packet_Repeat<0x2b11> native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2b11> *native, NetPacket_Repeat<0x2b11> network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b12> *network, Packet_Fixed<0x2b12> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->partner_id, native.partner_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b12> *native, NetPacket_Fixed<0x2b12> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->partner_id, network.partner_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b13> *network, Packet_Fixed<0x2b13> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b13> *native, NetPacket_Fixed<0x2b13> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b14> *network, Packet_Fixed<0x2b14> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->ban_not_status, native.ban_not_status); + rv &= native_to_network(&network->status_or_ban_until, native.status_or_ban_until); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b14> *native, NetPacket_Fixed<0x2b14> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->ban_not_status, network.ban_not_status); + rv &= network_to_native(&native->status_or_ban_until, network.status_or_ban_until); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2b15> *network, Packet_Head<0x2b15> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2b15> *native, NetPacket_Head<0x2b15> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2b15> *network, Packet_Repeat<0x2b15> native) +{ + bool rv = true; + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->gm_level, native.gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2b15> *native, NetPacket_Repeat<0x2b15> network) +{ + bool rv = true; + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->gm_level, network.gm_level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2b16> *network, Packet_Fixed<0x2b16> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_id, native.char_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2b16> *native, NetPacket_Fixed<0x2b16> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_id, network.char_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3000> *network, Packet_Head<0x3000> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3000> *native, NetPacket_Head<0x3000> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3000> *network, Packet_Repeat<0x3000> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3000> *native, NetPacket_Repeat<0x3000> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3001> *network, Packet_Head<0x3001> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->from_char_name, native.from_char_name); + rv &= native_to_network(&network->to_char_name, native.to_char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3001> *native, NetPacket_Head<0x3001> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->from_char_name, network.from_char_name); + rv &= network_to_native(&native->to_char_name, network.to_char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3001> *network, Packet_Repeat<0x3001> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3001> *native, NetPacket_Repeat<0x3001> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3002> *network, Packet_Fixed<0x3002> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3002> *native, NetPacket_Fixed<0x3002> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3003> *network, Packet_Head<0x3003> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->min_gm_level, native.min_gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3003> *native, NetPacket_Head<0x3003> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->min_gm_level, network.min_gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3003> *network, Packet_Repeat<0x3003> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3003> *native, NetPacket_Repeat<0x3003> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3004> *network, Packet_Head<0x3004> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3004> *native, NetPacket_Head<0x3004> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3004> *network, Packet_Repeat<0x3004> native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3004> *native, NetPacket_Repeat<0x3004> network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3005> *network, Packet_Fixed<0x3005> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3005> *native, NetPacket_Fixed<0x3005> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3010> *network, Packet_Fixed<0x3010> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3010> *native, NetPacket_Fixed<0x3010> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Payload<0x3011> *network, Packet_Payload<0x3011> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->storage, native.storage); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Payload<0x3011> *native, NetPacket_Payload<0x3011> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->storage, network.storage); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3020> *network, Packet_Fixed<0x3020> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->party_name, native.party_name); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->level, native.level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3020> *native, NetPacket_Fixed<0x3020> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->party_name, network.party_name); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->level, network.level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3021> *network, Packet_Fixed<0x3021> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3021> *native, NetPacket_Fixed<0x3021> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3022> *network, Packet_Fixed<0x3022> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->level, native.level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3022> *native, NetPacket_Fixed<0x3022> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->level, network.level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3023> *network, Packet_Fixed<0x3023> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->exp, native.exp); + rv &= native_to_network(&network->item, native.item); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3023> *native, NetPacket_Fixed<0x3023> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->exp, network.exp); + rv &= network_to_native(&native->item, network.item); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3024> *network, Packet_Fixed<0x3024> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3024> *native, NetPacket_Fixed<0x3024> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3025> *network, Packet_Fixed<0x3025> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->online, native.online); + rv &= native_to_network(&network->level, native.level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3025> *native, NetPacket_Fixed<0x3025> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->online, network.online); + rv &= network_to_native(&native->level, network.level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3027> *network, Packet_Head<0x3027> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3027> *native, NetPacket_Head<0x3027> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3027> *network, Packet_Repeat<0x3027> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3027> *native, NetPacket_Repeat<0x3027> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3028> *network, Packet_Fixed<0x3028> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3028> *native, NetPacket_Fixed<0x3028> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3800> *network, Packet_Head<0x3800> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3800> *native, NetPacket_Head<0x3800> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3800> *network, Packet_Repeat<0x3800> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3800> *native, NetPacket_Repeat<0x3800> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3801> *network, Packet_Head<0x3801> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->whisper_id, native.whisper_id); + rv &= native_to_network(&network->src_char_name, native.src_char_name); + rv &= native_to_network(&network->dst_char_name, native.dst_char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3801> *native, NetPacket_Head<0x3801> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->whisper_id, network.whisper_id); + rv &= network_to_native(&native->src_char_name, network.src_char_name); + rv &= network_to_native(&native->dst_char_name, network.dst_char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3801> *network, Packet_Repeat<0x3801> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3801> *native, NetPacket_Repeat<0x3801> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3802> *network, Packet_Fixed<0x3802> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->sender_char_name, native.sender_char_name); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3802> *native, NetPacket_Fixed<0x3802> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->sender_char_name, network.sender_char_name); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3803> *network, Packet_Head<0x3803> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->min_gm_level, native.min_gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3803> *native, NetPacket_Head<0x3803> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->min_gm_level, network.min_gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3803> *network, Packet_Repeat<0x3803> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3803> *native, NetPacket_Repeat<0x3803> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3804> *network, Packet_Head<0x3804> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3804> *native, NetPacket_Head<0x3804> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3804> *network, Packet_Repeat<0x3804> native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3804> *native, NetPacket_Repeat<0x3804> network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Payload<0x3810> *network, Packet_Payload<0x3810> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->storage, native.storage); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Payload<0x3810> *native, NetPacket_Payload<0x3810> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->storage, network.storage); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3811> *network, Packet_Fixed<0x3811> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->unknown, native.unknown); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3811> *native, NetPacket_Fixed<0x3811> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->unknown, network.unknown); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3820> *network, Packet_Fixed<0x3820> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->error, native.error); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->party_name, native.party_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3820> *native, NetPacket_Fixed<0x3820> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->error, network.error); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->party_name, network.party_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3821> *network, Packet_Head<0x3821> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->party_id, native.party_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3821> *native, NetPacket_Head<0x3821> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->party_id, network.party_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Option<0x3821> *network, Packet_Option<0x3821> native) +{ + bool rv = true; + rv &= native_to_network(&network->party_most, native.party_most); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Option<0x3821> *native, NetPacket_Option<0x3821> network) +{ + bool rv = true; + rv &= network_to_native(&native->party_most, network.party_most); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3822> *network, Packet_Fixed<0x3822> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3822> *native, NetPacket_Fixed<0x3822> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3823> *network, Packet_Fixed<0x3823> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->exp, native.exp); + rv &= native_to_network(&network->item, native.item); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3823> *native, NetPacket_Fixed<0x3823> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->exp, network.exp); + rv &= network_to_native(&native->item, network.item); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3824> *network, Packet_Fixed<0x3824> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3824> *native, NetPacket_Fixed<0x3824> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3825> *network, Packet_Fixed<0x3825> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->online, native.online); + rv &= native_to_network(&network->level, native.level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3825> *native, NetPacket_Fixed<0x3825> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->online, network.online); + rv &= network_to_native(&native->level, network.level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x3826> *network, Packet_Fixed<0x3826> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x3826> *native, NetPacket_Fixed<0x3826> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x3827> *network, Packet_Head<0x3827> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x3827> *native, NetPacket_Head<0x3827> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x3827> *network, Packet_Repeat<0x3827> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x3827> *native, NetPacket_Repeat<0x3827> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +} // namespace tmwa diff --git a/src/proto2/char-map_test.cpp b/src/proto2/char-map_test.cpp new file mode 100644 index 0000000..b4ba642 --- /dev/null +++ b/src/proto2/char-map_test.cpp @@ -0,0 +1,27 @@ +#include "char-map.hpp" +// char-map_test.cpp - TMWA network protocol: char/map +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "../poison.hpp" + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/proto2/char-user.hpp b/src/proto2/char-user.hpp new file mode 100644 index 0000000..ed58d69 --- /dev/null +++ b/src/proto2/char-user.hpp @@ -0,0 +1,622 @@ +#pragma once +// char-user.hpp - TMWA network protocol: char/user +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "fwd.hpp" + +#include "types.hpp" + +namespace tmwa +{ +// This is a public protocol, and changes require client cooperation + +template<> +struct Packet_Fixed<0x0061> +{ + static const uint16_t PACKET_ID = 0x0061; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountPass old_pass = {}; + AccountPass new_pass = {}; +}; + +template<> +struct Packet_Fixed<0x0062> +{ + static const uint16_t PACKET_ID = 0x0062; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t status = {}; +}; + +template<> +struct Packet_Fixed<0x0065> +{ + static const uint16_t PACKET_ID = 0x0065; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint32_t login_id1 = {}; + uint32_t login_id2 = {}; + uint16_t packet_tmw_version = {}; + SEX sex = {}; +}; + +template<> +struct Packet_Fixed<0x0066> +{ + static const uint16_t PACKET_ID = 0x0066; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t code = {}; +}; + +template<> +struct Packet_Fixed<0x0067> +{ + static const uint16_t PACKET_ID = 0x0067; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharName char_name = {}; + Stats6 stats = {}; + uint8_t slot = {}; + uint16_t hair_color = {}; + uint16_t hair_style = {}; +}; + +template<> +struct Packet_Fixed<0x0068> +{ + static const uint16_t PACKET_ID = 0x0068; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharId char_id = {}; + AccountEmail email = {}; +}; + +template<> +struct Packet_Head<0x006b> +{ + static const uint16_t PACKET_ID = 0x006b; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + VString<19> unused = {}; +}; +template<> +struct Packet_Repeat<0x006b> +{ + static const uint16_t PACKET_ID = 0x006b; + + CharSelect char_select = {}; +}; + +template<> +struct Packet_Fixed<0x006c> +{ + static const uint16_t PACKET_ID = 0x006c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t code = {}; +}; + +template<> +struct Packet_Fixed<0x006d> +{ + static const uint16_t PACKET_ID = 0x006d; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharSelect char_select = {}; +}; + +template<> +struct Packet_Fixed<0x006e> +{ + static const uint16_t PACKET_ID = 0x006e; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t code = {}; +}; + +template<> +struct Packet_Fixed<0x006f> +{ + static const uint16_t PACKET_ID = 0x006f; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x0070> +{ + static const uint16_t PACKET_ID = 0x0070; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t code = {}; +}; + +template<> +struct Packet_Fixed<0x0071> +{ + static const uint16_t PACKET_ID = 0x0071; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharId char_id = {}; + MapName map_name = {}; + IP4Address ip = {}; + uint16_t port = {}; +}; + + +template<> +struct NetPacket_Fixed<0x0061> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountPass)> old_pass; + NetString<sizeof(AccountPass)> new_pass; +}; +static_assert(offsetof(NetPacket_Fixed<0x0061>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0061>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0061>, old_pass) == 2, "offsetof(NetPacket_Fixed<0x0061>, old_pass) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0061>, new_pass) == 26, "offsetof(NetPacket_Fixed<0x0061>, new_pass) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x0061>) == 50, "sizeof(NetPacket_Fixed<0x0061>) == 50"); +static_assert(alignof(NetPacket_Fixed<0x0061>) == 1, "alignof(NetPacket_Fixed<0x0061>) == 1"); + +template<> +struct NetPacket_Fixed<0x0062> +{ + Little16 magic_packet_id; + Byte status; +}; +static_assert(offsetof(NetPacket_Fixed<0x0062>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0062>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0062>, status) == 2, "offsetof(NetPacket_Fixed<0x0062>, status) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0062>) == 3, "sizeof(NetPacket_Fixed<0x0062>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x0062>) == 1, "alignof(NetPacket_Fixed<0x0062>) == 1"); + +template<> +struct NetPacket_Fixed<0x0065> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 login_id1; + Little32 login_id2; + Little16 packet_tmw_version; + Byte sex; +}; +static_assert(offsetof(NetPacket_Fixed<0x0065>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0065>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0065>, account_id) == 2, "offsetof(NetPacket_Fixed<0x0065>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0065>, login_id1) == 6, "offsetof(NetPacket_Fixed<0x0065>, login_id1) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0065>, login_id2) == 10, "offsetof(NetPacket_Fixed<0x0065>, login_id2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x0065>, packet_tmw_version) == 14, "offsetof(NetPacket_Fixed<0x0065>, packet_tmw_version) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x0065>, sex) == 16, "offsetof(NetPacket_Fixed<0x0065>, sex) == 16"); +static_assert(sizeof(NetPacket_Fixed<0x0065>) == 17, "sizeof(NetPacket_Fixed<0x0065>) == 17"); +static_assert(alignof(NetPacket_Fixed<0x0065>) == 1, "alignof(NetPacket_Fixed<0x0065>) == 1"); + +template<> +struct NetPacket_Fixed<0x0066> +{ + Little16 magic_packet_id; + Byte code; +}; +static_assert(offsetof(NetPacket_Fixed<0x0066>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0066>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0066>, code) == 2, "offsetof(NetPacket_Fixed<0x0066>, code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0066>) == 3, "sizeof(NetPacket_Fixed<0x0066>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x0066>) == 1, "alignof(NetPacket_Fixed<0x0066>) == 1"); + +template<> +struct NetPacket_Fixed<0x0067> +{ + Little16 magic_packet_id; + NetString<sizeof(CharName)> char_name; + NetStats6 stats; + Byte slot; + Little16 hair_color; + Little16 hair_style; +}; +static_assert(offsetof(NetPacket_Fixed<0x0067>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0067>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0067>, char_name) == 2, "offsetof(NetPacket_Fixed<0x0067>, char_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0067>, stats) == 26, "offsetof(NetPacket_Fixed<0x0067>, stats) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x0067>, slot) == 32, "offsetof(NetPacket_Fixed<0x0067>, slot) == 32"); +static_assert(offsetof(NetPacket_Fixed<0x0067>, hair_color) == 33, "offsetof(NetPacket_Fixed<0x0067>, hair_color) == 33"); +static_assert(offsetof(NetPacket_Fixed<0x0067>, hair_style) == 35, "offsetof(NetPacket_Fixed<0x0067>, hair_style) == 35"); +static_assert(sizeof(NetPacket_Fixed<0x0067>) == 37, "sizeof(NetPacket_Fixed<0x0067>) == 37"); +static_assert(alignof(NetPacket_Fixed<0x0067>) == 1, "alignof(NetPacket_Fixed<0x0067>) == 1"); + +template<> +struct NetPacket_Fixed<0x0068> +{ + Little16 magic_packet_id; + Little32 char_id; + NetString<sizeof(AccountEmail)> email; +}; +static_assert(offsetof(NetPacket_Fixed<0x0068>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0068>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0068>, char_id) == 2, "offsetof(NetPacket_Fixed<0x0068>, char_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0068>, email) == 6, "offsetof(NetPacket_Fixed<0x0068>, email) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x0068>) == 46, "sizeof(NetPacket_Fixed<0x0068>) == 46"); +static_assert(alignof(NetPacket_Fixed<0x0068>) == 1, "alignof(NetPacket_Fixed<0x0068>) == 1"); + +template<> +struct NetPacket_Head<0x006b> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + NetString<sizeof(VString<19>)> unused; +}; +static_assert(offsetof(NetPacket_Head<0x006b>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x006b>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x006b>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x006b>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x006b>, unused) == 4, "offsetof(NetPacket_Head<0x006b>, unused) == 4"); +static_assert(sizeof(NetPacket_Head<0x006b>) == 24, "sizeof(NetPacket_Head<0x006b>) == 24"); +static_assert(alignof(NetPacket_Head<0x006b>) == 1, "alignof(NetPacket_Head<0x006b>) == 1"); +template<> +struct NetPacket_Repeat<0x006b> +{ + NetCharSelect char_select; +}; +static_assert(offsetof(NetPacket_Repeat<0x006b>, char_select) == 0, "offsetof(NetPacket_Repeat<0x006b>, char_select) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x006b>) == 106, "sizeof(NetPacket_Repeat<0x006b>) == 106"); +static_assert(alignof(NetPacket_Repeat<0x006b>) == 1, "alignof(NetPacket_Repeat<0x006b>) == 1"); + +template<> +struct NetPacket_Fixed<0x006c> +{ + Little16 magic_packet_id; + Byte code; +}; +static_assert(offsetof(NetPacket_Fixed<0x006c>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x006c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x006c>, code) == 2, "offsetof(NetPacket_Fixed<0x006c>, code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x006c>) == 3, "sizeof(NetPacket_Fixed<0x006c>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x006c>) == 1, "alignof(NetPacket_Fixed<0x006c>) == 1"); + +template<> +struct NetPacket_Fixed<0x006d> +{ + Little16 magic_packet_id; + NetCharSelect char_select; +}; +static_assert(offsetof(NetPacket_Fixed<0x006d>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x006d>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x006d>, char_select) == 2, "offsetof(NetPacket_Fixed<0x006d>, char_select) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x006d>) == 108, "sizeof(NetPacket_Fixed<0x006d>) == 108"); +static_assert(alignof(NetPacket_Fixed<0x006d>) == 1, "alignof(NetPacket_Fixed<0x006d>) == 1"); + +template<> +struct NetPacket_Fixed<0x006e> +{ + Little16 magic_packet_id; + Byte code; +}; +static_assert(offsetof(NetPacket_Fixed<0x006e>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x006e>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x006e>, code) == 2, "offsetof(NetPacket_Fixed<0x006e>, code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x006e>) == 3, "sizeof(NetPacket_Fixed<0x006e>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x006e>) == 1, "alignof(NetPacket_Fixed<0x006e>) == 1"); + +template<> +struct NetPacket_Fixed<0x006f> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x006f>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x006f>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x006f>) == 2, "sizeof(NetPacket_Fixed<0x006f>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x006f>) == 1, "alignof(NetPacket_Fixed<0x006f>) == 1"); + +template<> +struct NetPacket_Fixed<0x0070> +{ + Little16 magic_packet_id; + Byte code; +}; +static_assert(offsetof(NetPacket_Fixed<0x0070>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0070>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0070>, code) == 2, "offsetof(NetPacket_Fixed<0x0070>, code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0070>) == 3, "sizeof(NetPacket_Fixed<0x0070>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x0070>) == 1, "alignof(NetPacket_Fixed<0x0070>) == 1"); + +template<> +struct NetPacket_Fixed<0x0071> +{ + Little16 magic_packet_id; + Little32 char_id; + NetString<sizeof(MapName)> map_name; + IP4Address ip; + Little16 port; +}; +static_assert(offsetof(NetPacket_Fixed<0x0071>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0071>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0071>, char_id) == 2, "offsetof(NetPacket_Fixed<0x0071>, char_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0071>, map_name) == 6, "offsetof(NetPacket_Fixed<0x0071>, map_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0071>, ip) == 22, "offsetof(NetPacket_Fixed<0x0071>, ip) == 22"); +static_assert(offsetof(NetPacket_Fixed<0x0071>, port) == 26, "offsetof(NetPacket_Fixed<0x0071>, port) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x0071>) == 28, "sizeof(NetPacket_Fixed<0x0071>) == 28"); +static_assert(alignof(NetPacket_Fixed<0x0071>) == 1, "alignof(NetPacket_Fixed<0x0071>) == 1"); + + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0061> *network, Packet_Fixed<0x0061> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->old_pass, native.old_pass); + rv &= native_to_network(&network->new_pass, native.new_pass); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0061> *native, NetPacket_Fixed<0x0061> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->old_pass, network.old_pass); + rv &= network_to_native(&native->new_pass, network.new_pass); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0062> *network, Packet_Fixed<0x0062> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->status, native.status); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0062> *native, NetPacket_Fixed<0x0062> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->status, network.status); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0065> *network, Packet_Fixed<0x0065> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->login_id1, native.login_id1); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->packet_tmw_version, native.packet_tmw_version); + rv &= native_to_network(&network->sex, native.sex); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0065> *native, NetPacket_Fixed<0x0065> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->login_id1, network.login_id1); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->packet_tmw_version, network.packet_tmw_version); + rv &= network_to_native(&native->sex, network.sex); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0066> *network, Packet_Fixed<0x0066> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->code, native.code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0066> *native, NetPacket_Fixed<0x0066> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->code, network.code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0067> *network, Packet_Fixed<0x0067> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->stats, native.stats); + rv &= native_to_network(&network->slot, native.slot); + rv &= native_to_network(&network->hair_color, native.hair_color); + rv &= native_to_network(&network->hair_style, native.hair_style); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0067> *native, NetPacket_Fixed<0x0067> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->stats, network.stats); + rv &= network_to_native(&native->slot, network.slot); + rv &= network_to_native(&native->hair_color, network.hair_color); + rv &= network_to_native(&native->hair_style, network.hair_style); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0068> *network, Packet_Fixed<0x0068> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->email, native.email); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0068> *native, NetPacket_Fixed<0x0068> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->email, network.email); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x006b> *network, Packet_Head<0x006b> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->unused, native.unused); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x006b> *native, NetPacket_Head<0x006b> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->unused, network.unused); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x006b> *network, Packet_Repeat<0x006b> native) +{ + bool rv = true; + rv &= native_to_network(&network->char_select, native.char_select); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x006b> *native, NetPacket_Repeat<0x006b> network) +{ + bool rv = true; + rv &= network_to_native(&native->char_select, network.char_select); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x006c> *network, Packet_Fixed<0x006c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->code, native.code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x006c> *native, NetPacket_Fixed<0x006c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->code, network.code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x006d> *network, Packet_Fixed<0x006d> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_select, native.char_select); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x006d> *native, NetPacket_Fixed<0x006d> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_select, network.char_select); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x006e> *network, Packet_Fixed<0x006e> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->code, native.code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x006e> *native, NetPacket_Fixed<0x006e> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->code, network.code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x006f> *network, Packet_Fixed<0x006f> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x006f> *native, NetPacket_Fixed<0x006f> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0070> *network, Packet_Fixed<0x0070> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->code, native.code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0070> *native, NetPacket_Fixed<0x0070> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->code, network.code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0071> *network, Packet_Fixed<0x0071> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->ip, native.ip); + rv &= native_to_network(&network->port, native.port); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0071> *native, NetPacket_Fixed<0x0071> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->ip, network.ip); + rv &= network_to_native(&native->port, network.port); + return rv; +} + +} // namespace tmwa diff --git a/src/proto2/char-user_test.cpp b/src/proto2/char-user_test.cpp new file mode 100644 index 0000000..ade1843 --- /dev/null +++ b/src/proto2/char-user_test.cpp @@ -0,0 +1,27 @@ +#include "char-user.hpp" +// char-user_test.cpp - TMWA network protocol: char/user +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "../poison.hpp" + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/proto2/fwd.hpp b/src/proto2/fwd.hpp new file mode 100644 index 0000000..e1e0161 --- /dev/null +++ b/src/proto2/fwd.hpp @@ -0,0 +1,1713 @@ +#pragma once +// proto2/fwd.hpp - Forward declarations of network packets +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + +#include <cstdint> + +namespace tmwa +{ +template<uint16_t PACKET_ID> class Packet_Fixed; +template<uint16_t PACKET_ID> class NetPacket_Fixed; +template<uint16_t PACKET_ID> class Packet_Payload; +template<uint16_t PACKET_ID> class NetPacket_Payload; +template<uint16_t PACKET_ID> class Packet_Head; +template<uint16_t PACKET_ID> class NetPacket_Head; +template<uint16_t PACKET_ID> class Packet_Repeat; +template<uint16_t PACKET_ID> class NetPacket_Repeat; +template<uint16_t PACKET_ID> class Packet_Option; +template<uint16_t PACKET_ID> class NetPacket_Option; + +template<> +struct Packet_Fixed<0x2709>; +template<> +struct NetPacket_Fixed<0x2709>; + +template<> +struct Packet_Fixed<0x2710>; +template<> +struct NetPacket_Fixed<0x2710>; + +template<> +struct Packet_Fixed<0x2711>; +template<> +struct NetPacket_Fixed<0x2711>; + +template<> +struct Packet_Fixed<0x2712>; +template<> +struct NetPacket_Fixed<0x2712>; + +template<> +struct Packet_Fixed<0x2713>; +template<> +struct NetPacket_Fixed<0x2713>; + +template<> +struct Packet_Fixed<0x2714>; +template<> +struct NetPacket_Fixed<0x2714>; + +template<> +struct Packet_Fixed<0x2716>; +template<> +struct NetPacket_Fixed<0x2716>; + +template<> +struct Packet_Fixed<0x2717>; +template<> +struct NetPacket_Fixed<0x2717>; + +template<> +struct Packet_Head<0x2720>; +template<> +struct NetPacket_Head<0x2720>; +template<> +struct Packet_Repeat<0x2720>; +template<> +struct NetPacket_Repeat<0x2720>; + +template<> +struct Packet_Fixed<0x2721>; +template<> +struct NetPacket_Fixed<0x2721>; + +template<> +struct Packet_Fixed<0x2722>; +template<> +struct NetPacket_Fixed<0x2722>; + +template<> +struct Packet_Fixed<0x2723>; +template<> +struct NetPacket_Fixed<0x2723>; + +template<> +struct Packet_Fixed<0x2724>; +template<> +struct NetPacket_Fixed<0x2724>; + +template<> +struct Packet_Fixed<0x2725>; +template<> +struct NetPacket_Fixed<0x2725>; + +template<> +struct Packet_Fixed<0x2727>; +template<> +struct NetPacket_Fixed<0x2727>; + +template<> +struct Packet_Head<0x2728>; +template<> +struct NetPacket_Head<0x2728>; +template<> +struct Packet_Repeat<0x2728>; +template<> +struct NetPacket_Repeat<0x2728>; + +template<> +struct Packet_Head<0x2729>; +template<> +struct NetPacket_Head<0x2729>; +template<> +struct Packet_Repeat<0x2729>; +template<> +struct NetPacket_Repeat<0x2729>; + +template<> +struct Packet_Fixed<0x272a>; +template<> +struct NetPacket_Fixed<0x272a>; + +template<> +struct Packet_Fixed<0x2730>; +template<> +struct NetPacket_Fixed<0x2730>; + +template<> +struct Packet_Fixed<0x2731>; +template<> +struct NetPacket_Fixed<0x2731>; + +template<> +struct Packet_Head<0x2732>; +template<> +struct NetPacket_Head<0x2732>; +template<> +struct Packet_Repeat<0x2732>; +template<> +struct NetPacket_Repeat<0x2732>; + +template<> +struct Packet_Fixed<0x2740>; +template<> +struct NetPacket_Fixed<0x2740>; + +template<> +struct Packet_Fixed<0x2741>; +template<> +struct NetPacket_Fixed<0x2741>; + + +template<> +struct Packet_Head<0x2726>; +template<> +struct NetPacket_Head<0x2726>; +template<> +struct Packet_Repeat<0x2726>; +template<> +struct NetPacket_Repeat<0x2726>; + +template<> +struct Packet_Fixed<0x7918>; +template<> +struct NetPacket_Fixed<0x7918>; + +template<> +struct Packet_Fixed<0x7919>; +template<> +struct NetPacket_Fixed<0x7919>; + +template<> +struct Packet_Fixed<0x7920>; +template<> +struct NetPacket_Fixed<0x7920>; + +template<> +struct Packet_Head<0x7921>; +template<> +struct NetPacket_Head<0x7921>; +template<> +struct Packet_Repeat<0x7921>; +template<> +struct NetPacket_Repeat<0x7921>; + +template<> +struct Packet_Fixed<0x7924>; +template<> +struct NetPacket_Fixed<0x7924>; + +template<> +struct Packet_Fixed<0x7925>; +template<> +struct NetPacket_Fixed<0x7925>; + +template<> +struct Packet_Fixed<0x7930>; +template<> +struct NetPacket_Fixed<0x7930>; + +template<> +struct Packet_Fixed<0x7931>; +template<> +struct NetPacket_Fixed<0x7931>; + +template<> +struct Packet_Fixed<0x7932>; +template<> +struct NetPacket_Fixed<0x7932>; + +template<> +struct Packet_Fixed<0x7933>; +template<> +struct NetPacket_Fixed<0x7933>; + +template<> +struct Packet_Fixed<0x7934>; +template<> +struct NetPacket_Fixed<0x7934>; + +template<> +struct Packet_Fixed<0x7935>; +template<> +struct NetPacket_Fixed<0x7935>; + +template<> +struct Packet_Fixed<0x7936>; +template<> +struct NetPacket_Fixed<0x7936>; + +template<> +struct Packet_Fixed<0x7937>; +template<> +struct NetPacket_Fixed<0x7937>; + +template<> +struct Packet_Fixed<0x7938>; +template<> +struct NetPacket_Fixed<0x7938>; + +template<> +struct Packet_Head<0x7939>; +template<> +struct NetPacket_Head<0x7939>; +template<> +struct Packet_Repeat<0x7939>; +template<> +struct NetPacket_Repeat<0x7939>; + +template<> +struct Packet_Fixed<0x793a>; +template<> +struct NetPacket_Fixed<0x793a>; + +template<> +struct Packet_Fixed<0x793b>; +template<> +struct NetPacket_Fixed<0x793b>; + +template<> +struct Packet_Fixed<0x793c>; +template<> +struct NetPacket_Fixed<0x793c>; + +template<> +struct Packet_Fixed<0x793d>; +template<> +struct NetPacket_Fixed<0x793d>; + +template<> +struct Packet_Fixed<0x793e>; +template<> +struct NetPacket_Fixed<0x793e>; + +template<> +struct Packet_Fixed<0x793f>; +template<> +struct NetPacket_Fixed<0x793f>; + +template<> +struct Packet_Fixed<0x7940>; +template<> +struct NetPacket_Fixed<0x7940>; + +template<> +struct Packet_Fixed<0x7941>; +template<> +struct NetPacket_Fixed<0x7941>; + +template<> +struct Packet_Head<0x7942>; +template<> +struct NetPacket_Head<0x7942>; +template<> +struct Packet_Repeat<0x7942>; +template<> +struct NetPacket_Repeat<0x7942>; + +template<> +struct Packet_Fixed<0x7943>; +template<> +struct NetPacket_Fixed<0x7943>; + +template<> +struct Packet_Fixed<0x7944>; +template<> +struct NetPacket_Fixed<0x7944>; + +template<> +struct Packet_Fixed<0x7945>; +template<> +struct NetPacket_Fixed<0x7945>; + +template<> +struct Packet_Fixed<0x7946>; +template<> +struct NetPacket_Fixed<0x7946>; + +template<> +struct Packet_Fixed<0x7947>; +template<> +struct NetPacket_Fixed<0x7947>; + +template<> +struct Packet_Fixed<0x7948>; +template<> +struct NetPacket_Fixed<0x7948>; + +template<> +struct Packet_Fixed<0x7949>; +template<> +struct NetPacket_Fixed<0x7949>; + +template<> +struct Packet_Fixed<0x794a>; +template<> +struct NetPacket_Fixed<0x794a>; + +template<> +struct Packet_Fixed<0x794b>; +template<> +struct NetPacket_Fixed<0x794b>; + +template<> +struct Packet_Fixed<0x794c>; +template<> +struct NetPacket_Fixed<0x794c>; + +template<> +struct Packet_Fixed<0x794d>; +template<> +struct NetPacket_Fixed<0x794d>; + +template<> +struct Packet_Head<0x794e>; +template<> +struct NetPacket_Head<0x794e>; +template<> +struct Packet_Repeat<0x794e>; +template<> +struct NetPacket_Repeat<0x794e>; + +template<> +struct Packet_Fixed<0x794f>; +template<> +struct NetPacket_Fixed<0x794f>; + +template<> +struct Packet_Fixed<0x7950>; +template<> +struct NetPacket_Fixed<0x7950>; + +template<> +struct Packet_Fixed<0x7951>; +template<> +struct NetPacket_Fixed<0x7951>; + +template<> +struct Packet_Fixed<0x7952>; +template<> +struct NetPacket_Fixed<0x7952>; + +template<> +struct Packet_Head<0x7953>; +template<> +struct NetPacket_Head<0x7953>; +template<> +struct Packet_Repeat<0x7953>; +template<> +struct NetPacket_Repeat<0x7953>; + +template<> +struct Packet_Fixed<0x7954>; +template<> +struct NetPacket_Fixed<0x7954>; + +template<> +struct Packet_Fixed<0x7955>; +template<> +struct NetPacket_Fixed<0x7955>; + + +template<> +struct Packet_Head<0x0063>; +template<> +struct NetPacket_Head<0x0063>; +template<> +struct Packet_Repeat<0x0063>; +template<> +struct NetPacket_Repeat<0x0063>; + +template<> +struct Packet_Fixed<0x0064>; +template<> +struct NetPacket_Fixed<0x0064>; + +template<> +struct Packet_Head<0x0069>; +template<> +struct NetPacket_Head<0x0069>; +template<> +struct Packet_Repeat<0x0069>; +template<> +struct NetPacket_Repeat<0x0069>; + +template<> +struct Packet_Fixed<0x006a>; +template<> +struct NetPacket_Fixed<0x006a>; + + +template<> +struct Packet_Fixed<0x2af7>; +template<> +struct NetPacket_Fixed<0x2af7>; + +template<> +struct Packet_Fixed<0x2af8>; +template<> +struct NetPacket_Fixed<0x2af8>; + +template<> +struct Packet_Fixed<0x2af9>; +template<> +struct NetPacket_Fixed<0x2af9>; + +template<> +struct Packet_Head<0x2afa>; +template<> +struct NetPacket_Head<0x2afa>; +template<> +struct Packet_Repeat<0x2afa>; +template<> +struct NetPacket_Repeat<0x2afa>; + +template<> +struct Packet_Fixed<0x2afa>; +template<> +struct NetPacket_Fixed<0x2afa>; + +template<> +struct Packet_Fixed<0x2afb>; +template<> +struct NetPacket_Fixed<0x2afb>; + +template<> +struct Packet_Fixed<0x2afc>; +template<> +struct NetPacket_Fixed<0x2afc>; + +template<> +struct Packet_Payload<0x2afd>; +template<> +struct NetPacket_Payload<0x2afd>; + +template<> +struct Packet_Fixed<0x2afe>; +template<> +struct NetPacket_Fixed<0x2afe>; + +template<> +struct Packet_Head<0x2aff>; +template<> +struct NetPacket_Head<0x2aff>; +template<> +struct Packet_Repeat<0x2aff>; +template<> +struct NetPacket_Repeat<0x2aff>; + +template<> +struct Packet_Fixed<0x2b00>; +template<> +struct NetPacket_Fixed<0x2b00>; + +template<> +struct Packet_Payload<0x2b01>; +template<> +struct NetPacket_Payload<0x2b01>; + +template<> +struct Packet_Fixed<0x2b02>; +template<> +struct NetPacket_Fixed<0x2b02>; + +template<> +struct Packet_Fixed<0x2b03>; +template<> +struct NetPacket_Fixed<0x2b03>; + +template<> +struct Packet_Head<0x2b04>; +template<> +struct NetPacket_Head<0x2b04>; +template<> +struct Packet_Repeat<0x2b04>; +template<> +struct NetPacket_Repeat<0x2b04>; + +template<> +struct Packet_Fixed<0x2b05>; +template<> +struct NetPacket_Fixed<0x2b05>; + +template<> +struct Packet_Fixed<0x2b06>; +template<> +struct NetPacket_Fixed<0x2b06>; + +template<> +struct Packet_Head<0x2b0a>; +template<> +struct NetPacket_Head<0x2b0a>; +template<> +struct Packet_Repeat<0x2b0a>; +template<> +struct NetPacket_Repeat<0x2b0a>; + +template<> +struct Packet_Fixed<0x2b0b>; +template<> +struct NetPacket_Fixed<0x2b0b>; + +template<> +struct Packet_Fixed<0x2b0c>; +template<> +struct NetPacket_Fixed<0x2b0c>; + +template<> +struct Packet_Fixed<0x2b0d>; +template<> +struct NetPacket_Fixed<0x2b0d>; + +template<> +struct Packet_Fixed<0x2b0e>; +template<> +struct NetPacket_Fixed<0x2b0e>; + +template<> +struct Packet_Fixed<0x2b0f>; +template<> +struct NetPacket_Fixed<0x2b0f>; + +template<> +struct Packet_Head<0x2b10>; +template<> +struct NetPacket_Head<0x2b10>; +template<> +struct Packet_Repeat<0x2b10>; +template<> +struct NetPacket_Repeat<0x2b10>; + +template<> +struct Packet_Head<0x2b11>; +template<> +struct NetPacket_Head<0x2b11>; +template<> +struct Packet_Repeat<0x2b11>; +template<> +struct NetPacket_Repeat<0x2b11>; + +template<> +struct Packet_Fixed<0x2b12>; +template<> +struct NetPacket_Fixed<0x2b12>; + +template<> +struct Packet_Fixed<0x2b13>; +template<> +struct NetPacket_Fixed<0x2b13>; + +template<> +struct Packet_Fixed<0x2b14>; +template<> +struct NetPacket_Fixed<0x2b14>; + +template<> +struct Packet_Head<0x2b15>; +template<> +struct NetPacket_Head<0x2b15>; +template<> +struct Packet_Repeat<0x2b15>; +template<> +struct NetPacket_Repeat<0x2b15>; + +template<> +struct Packet_Fixed<0x2b16>; +template<> +struct NetPacket_Fixed<0x2b16>; + +template<> +struct Packet_Head<0x3000>; +template<> +struct NetPacket_Head<0x3000>; +template<> +struct Packet_Repeat<0x3000>; +template<> +struct NetPacket_Repeat<0x3000>; + +template<> +struct Packet_Head<0x3001>; +template<> +struct NetPacket_Head<0x3001>; +template<> +struct Packet_Repeat<0x3001>; +template<> +struct NetPacket_Repeat<0x3001>; + +template<> +struct Packet_Fixed<0x3002>; +template<> +struct NetPacket_Fixed<0x3002>; + +template<> +struct Packet_Head<0x3003>; +template<> +struct NetPacket_Head<0x3003>; +template<> +struct Packet_Repeat<0x3003>; +template<> +struct NetPacket_Repeat<0x3003>; + +template<> +struct Packet_Head<0x3004>; +template<> +struct NetPacket_Head<0x3004>; +template<> +struct Packet_Repeat<0x3004>; +template<> +struct NetPacket_Repeat<0x3004>; + +template<> +struct Packet_Fixed<0x3005>; +template<> +struct NetPacket_Fixed<0x3005>; + +template<> +struct Packet_Fixed<0x3010>; +template<> +struct NetPacket_Fixed<0x3010>; + +template<> +struct Packet_Payload<0x3011>; +template<> +struct NetPacket_Payload<0x3011>; + +template<> +struct Packet_Fixed<0x3020>; +template<> +struct NetPacket_Fixed<0x3020>; + +template<> +struct Packet_Fixed<0x3021>; +template<> +struct NetPacket_Fixed<0x3021>; + +template<> +struct Packet_Fixed<0x3022>; +template<> +struct NetPacket_Fixed<0x3022>; + +template<> +struct Packet_Fixed<0x3023>; +template<> +struct NetPacket_Fixed<0x3023>; + +template<> +struct Packet_Fixed<0x3024>; +template<> +struct NetPacket_Fixed<0x3024>; + +template<> +struct Packet_Fixed<0x3025>; +template<> +struct NetPacket_Fixed<0x3025>; + +template<> +struct Packet_Head<0x3027>; +template<> +struct NetPacket_Head<0x3027>; +template<> +struct Packet_Repeat<0x3027>; +template<> +struct NetPacket_Repeat<0x3027>; + +template<> +struct Packet_Fixed<0x3028>; +template<> +struct NetPacket_Fixed<0x3028>; + +template<> +struct Packet_Head<0x3800>; +template<> +struct NetPacket_Head<0x3800>; +template<> +struct Packet_Repeat<0x3800>; +template<> +struct NetPacket_Repeat<0x3800>; + +template<> +struct Packet_Head<0x3801>; +template<> +struct NetPacket_Head<0x3801>; +template<> +struct Packet_Repeat<0x3801>; +template<> +struct NetPacket_Repeat<0x3801>; + +template<> +struct Packet_Fixed<0x3802>; +template<> +struct NetPacket_Fixed<0x3802>; + +template<> +struct Packet_Head<0x3803>; +template<> +struct NetPacket_Head<0x3803>; +template<> +struct Packet_Repeat<0x3803>; +template<> +struct NetPacket_Repeat<0x3803>; + +template<> +struct Packet_Head<0x3804>; +template<> +struct NetPacket_Head<0x3804>; +template<> +struct Packet_Repeat<0x3804>; +template<> +struct NetPacket_Repeat<0x3804>; + +template<> +struct Packet_Payload<0x3810>; +template<> +struct NetPacket_Payload<0x3810>; + +template<> +struct Packet_Fixed<0x3811>; +template<> +struct NetPacket_Fixed<0x3811>; + +template<> +struct Packet_Fixed<0x3820>; +template<> +struct NetPacket_Fixed<0x3820>; + +template<> +struct Packet_Head<0x3821>; +template<> +struct NetPacket_Head<0x3821>; +template<> +struct Packet_Option<0x3821>; +template<> +struct NetPacket_Option<0x3821>; + +template<> +struct Packet_Fixed<0x3822>; +template<> +struct NetPacket_Fixed<0x3822>; + +template<> +struct Packet_Fixed<0x3823>; +template<> +struct NetPacket_Fixed<0x3823>; + +template<> +struct Packet_Fixed<0x3824>; +template<> +struct NetPacket_Fixed<0x3824>; + +template<> +struct Packet_Fixed<0x3825>; +template<> +struct NetPacket_Fixed<0x3825>; + +template<> +struct Packet_Fixed<0x3826>; +template<> +struct NetPacket_Fixed<0x3826>; + +template<> +struct Packet_Head<0x3827>; +template<> +struct NetPacket_Head<0x3827>; +template<> +struct Packet_Repeat<0x3827>; +template<> +struct NetPacket_Repeat<0x3827>; + + +template<> +struct Packet_Fixed<0x0061>; +template<> +struct NetPacket_Fixed<0x0061>; + +template<> +struct Packet_Fixed<0x0062>; +template<> +struct NetPacket_Fixed<0x0062>; + +template<> +struct Packet_Fixed<0x0065>; +template<> +struct NetPacket_Fixed<0x0065>; + +template<> +struct Packet_Fixed<0x0066>; +template<> +struct NetPacket_Fixed<0x0066>; + +template<> +struct Packet_Fixed<0x0067>; +template<> +struct NetPacket_Fixed<0x0067>; + +template<> +struct Packet_Fixed<0x0068>; +template<> +struct NetPacket_Fixed<0x0068>; + +template<> +struct Packet_Head<0x006b>; +template<> +struct NetPacket_Head<0x006b>; +template<> +struct Packet_Repeat<0x006b>; +template<> +struct NetPacket_Repeat<0x006b>; + +template<> +struct Packet_Fixed<0x006c>; +template<> +struct NetPacket_Fixed<0x006c>; + +template<> +struct Packet_Fixed<0x006d>; +template<> +struct NetPacket_Fixed<0x006d>; + +template<> +struct Packet_Fixed<0x006e>; +template<> +struct NetPacket_Fixed<0x006e>; + +template<> +struct Packet_Fixed<0x006f>; +template<> +struct NetPacket_Fixed<0x006f>; + +template<> +struct Packet_Fixed<0x0070>; +template<> +struct NetPacket_Fixed<0x0070>; + +template<> +struct Packet_Fixed<0x0071>; +template<> +struct NetPacket_Fixed<0x0071>; + + +template<> +struct Packet_Fixed<0x0072>; +template<> +struct NetPacket_Fixed<0x0072>; + +template<> +struct Packet_Fixed<0x0073>; +template<> +struct NetPacket_Fixed<0x0073>; + +template<> +struct Packet_Fixed<0x0078>; +template<> +struct NetPacket_Fixed<0x0078>; + +template<> +struct Packet_Fixed<0x007b>; +template<> +struct NetPacket_Fixed<0x007b>; + +template<> +struct Packet_Fixed<0x007c>; +template<> +struct NetPacket_Fixed<0x007c>; + +template<> +struct Packet_Fixed<0x007d>; +template<> +struct NetPacket_Fixed<0x007d>; + +template<> +struct Packet_Fixed<0x007e>; +template<> +struct NetPacket_Fixed<0x007e>; + +template<> +struct Packet_Fixed<0x007f>; +template<> +struct NetPacket_Fixed<0x007f>; + +template<> +struct Packet_Fixed<0x0080>; +template<> +struct NetPacket_Fixed<0x0080>; + +template<> +struct Packet_Fixed<0x0085>; +template<> +struct NetPacket_Fixed<0x0085>; + +template<> +struct Packet_Fixed<0x0087>; +template<> +struct NetPacket_Fixed<0x0087>; + +template<> +struct Packet_Fixed<0x0088>; +template<> +struct NetPacket_Fixed<0x0088>; + +template<> +struct Packet_Fixed<0x0089>; +template<> +struct NetPacket_Fixed<0x0089>; + +template<> +struct Packet_Fixed<0x008a>; +template<> +struct NetPacket_Fixed<0x008a>; + +template<> +struct Packet_Head<0x008c>; +template<> +struct NetPacket_Head<0x008c>; +template<> +struct Packet_Repeat<0x008c>; +template<> +struct NetPacket_Repeat<0x008c>; + +template<> +struct Packet_Head<0x008d>; +template<> +struct NetPacket_Head<0x008d>; +template<> +struct Packet_Repeat<0x008d>; +template<> +struct NetPacket_Repeat<0x008d>; + +template<> +struct Packet_Head<0x008e>; +template<> +struct NetPacket_Head<0x008e>; +template<> +struct Packet_Repeat<0x008e>; +template<> +struct NetPacket_Repeat<0x008e>; + +template<> +struct Packet_Fixed<0x0090>; +template<> +struct NetPacket_Fixed<0x0090>; + +template<> +struct Packet_Fixed<0x0091>; +template<> +struct NetPacket_Fixed<0x0091>; + +template<> +struct Packet_Fixed<0x0092>; +template<> +struct NetPacket_Fixed<0x0092>; + +template<> +struct Packet_Fixed<0x0094>; +template<> +struct NetPacket_Fixed<0x0094>; + +template<> +struct Packet_Fixed<0x0095>; +template<> +struct NetPacket_Fixed<0x0095>; + +template<> +struct Packet_Head<0x0096>; +template<> +struct NetPacket_Head<0x0096>; +template<> +struct Packet_Repeat<0x0096>; +template<> +struct NetPacket_Repeat<0x0096>; + +template<> +struct Packet_Head<0x0097>; +template<> +struct NetPacket_Head<0x0097>; +template<> +struct Packet_Repeat<0x0097>; +template<> +struct NetPacket_Repeat<0x0097>; + +template<> +struct Packet_Fixed<0x0098>; +template<> +struct NetPacket_Fixed<0x0098>; + +template<> +struct Packet_Head<0x009a>; +template<> +struct NetPacket_Head<0x009a>; +template<> +struct Packet_Repeat<0x009a>; +template<> +struct NetPacket_Repeat<0x009a>; + +template<> +struct Packet_Fixed<0x009b>; +template<> +struct NetPacket_Fixed<0x009b>; + +template<> +struct Packet_Fixed<0x009c>; +template<> +struct NetPacket_Fixed<0x009c>; + +template<> +struct Packet_Fixed<0x009d>; +template<> +struct NetPacket_Fixed<0x009d>; + +template<> +struct Packet_Fixed<0x009e>; +template<> +struct NetPacket_Fixed<0x009e>; + +template<> +struct Packet_Fixed<0x009f>; +template<> +struct NetPacket_Fixed<0x009f>; + +template<> +struct Packet_Fixed<0x00a0>; +template<> +struct NetPacket_Fixed<0x00a0>; + +template<> +struct Packet_Fixed<0x00a1>; +template<> +struct NetPacket_Fixed<0x00a1>; + +template<> +struct Packet_Fixed<0x00a2>; +template<> +struct NetPacket_Fixed<0x00a2>; + +template<> +struct Packet_Head<0x00a4>; +template<> +struct NetPacket_Head<0x00a4>; +template<> +struct Packet_Repeat<0x00a4>; +template<> +struct NetPacket_Repeat<0x00a4>; + +template<> +struct Packet_Head<0x00a6>; +template<> +struct NetPacket_Head<0x00a6>; +template<> +struct Packet_Repeat<0x00a6>; +template<> +struct NetPacket_Repeat<0x00a6>; + +template<> +struct Packet_Fixed<0x00a7>; +template<> +struct NetPacket_Fixed<0x00a7>; + +template<> +struct Packet_Fixed<0x00a8>; +template<> +struct NetPacket_Fixed<0x00a8>; + +template<> +struct Packet_Fixed<0x00a9>; +template<> +struct NetPacket_Fixed<0x00a9>; + +template<> +struct Packet_Fixed<0x00aa>; +template<> +struct NetPacket_Fixed<0x00aa>; + +template<> +struct Packet_Fixed<0x00ab>; +template<> +struct NetPacket_Fixed<0x00ab>; + +template<> +struct Packet_Fixed<0x00ac>; +template<> +struct NetPacket_Fixed<0x00ac>; + +template<> +struct Packet_Fixed<0x00af>; +template<> +struct NetPacket_Fixed<0x00af>; + +template<> +struct Packet_Fixed<0x00b0>; +template<> +struct NetPacket_Fixed<0x00b0>; + +template<> +struct Packet_Fixed<0x00b1>; +template<> +struct NetPacket_Fixed<0x00b1>; + +template<> +struct Packet_Fixed<0x00b2>; +template<> +struct NetPacket_Fixed<0x00b2>; + +template<> +struct Packet_Fixed<0x00b3>; +template<> +struct NetPacket_Fixed<0x00b3>; + +template<> +struct Packet_Head<0x00b4>; +template<> +struct NetPacket_Head<0x00b4>; +template<> +struct Packet_Repeat<0x00b4>; +template<> +struct NetPacket_Repeat<0x00b4>; + +template<> +struct Packet_Fixed<0x00b5>; +template<> +struct NetPacket_Fixed<0x00b5>; + +template<> +struct Packet_Fixed<0x00b6>; +template<> +struct NetPacket_Fixed<0x00b6>; + +template<> +struct Packet_Head<0x00b7>; +template<> +struct NetPacket_Head<0x00b7>; +template<> +struct Packet_Repeat<0x00b7>; +template<> +struct NetPacket_Repeat<0x00b7>; + +template<> +struct Packet_Fixed<0x00b8>; +template<> +struct NetPacket_Fixed<0x00b8>; + +template<> +struct Packet_Fixed<0x00b9>; +template<> +struct NetPacket_Fixed<0x00b9>; + +template<> +struct Packet_Fixed<0x00bb>; +template<> +struct NetPacket_Fixed<0x00bb>; + +template<> +struct Packet_Fixed<0x00bc>; +template<> +struct NetPacket_Fixed<0x00bc>; + +template<> +struct Packet_Fixed<0x00bd>; +template<> +struct NetPacket_Fixed<0x00bd>; + +template<> +struct Packet_Fixed<0x00be>; +template<> +struct NetPacket_Fixed<0x00be>; + +template<> +struct Packet_Fixed<0x00bf>; +template<> +struct NetPacket_Fixed<0x00bf>; + +template<> +struct Packet_Fixed<0x00c0>; +template<> +struct NetPacket_Fixed<0x00c0>; + +template<> +struct Packet_Fixed<0x00c1>; +template<> +struct NetPacket_Fixed<0x00c1>; + +template<> +struct Packet_Fixed<0x00c2>; +template<> +struct NetPacket_Fixed<0x00c2>; + +template<> +struct Packet_Fixed<0x00c4>; +template<> +struct NetPacket_Fixed<0x00c4>; + +template<> +struct Packet_Fixed<0x00c5>; +template<> +struct NetPacket_Fixed<0x00c5>; + +template<> +struct Packet_Head<0x00c6>; +template<> +struct NetPacket_Head<0x00c6>; +template<> +struct Packet_Repeat<0x00c6>; +template<> +struct NetPacket_Repeat<0x00c6>; + +template<> +struct Packet_Head<0x00c7>; +template<> +struct NetPacket_Head<0x00c7>; +template<> +struct Packet_Repeat<0x00c7>; +template<> +struct NetPacket_Repeat<0x00c7>; + +template<> +struct Packet_Head<0x00c8>; +template<> +struct NetPacket_Head<0x00c8>; +template<> +struct Packet_Repeat<0x00c8>; +template<> +struct NetPacket_Repeat<0x00c8>; + +template<> +struct Packet_Head<0x00c9>; +template<> +struct NetPacket_Head<0x00c9>; +template<> +struct Packet_Repeat<0x00c9>; +template<> +struct NetPacket_Repeat<0x00c9>; + +template<> +struct Packet_Fixed<0x00ca>; +template<> +struct NetPacket_Fixed<0x00ca>; + +template<> +struct Packet_Fixed<0x00cb>; +template<> +struct NetPacket_Fixed<0x00cb>; + +template<> +struct Packet_Fixed<0x00cd>; +template<> +struct NetPacket_Fixed<0x00cd>; + +template<> +struct Packet_Fixed<0x00e4>; +template<> +struct NetPacket_Fixed<0x00e4>; + +template<> +struct Packet_Fixed<0x00e5>; +template<> +struct NetPacket_Fixed<0x00e5>; + +template<> +struct Packet_Fixed<0x00e6>; +template<> +struct NetPacket_Fixed<0x00e6>; + +template<> +struct Packet_Fixed<0x00e7>; +template<> +struct NetPacket_Fixed<0x00e7>; + +template<> +struct Packet_Fixed<0x00e8>; +template<> +struct NetPacket_Fixed<0x00e8>; + +template<> +struct Packet_Fixed<0x00e9>; +template<> +struct NetPacket_Fixed<0x00e9>; + +template<> +struct Packet_Fixed<0x00eb>; +template<> +struct NetPacket_Fixed<0x00eb>; + +template<> +struct Packet_Fixed<0x00ec>; +template<> +struct NetPacket_Fixed<0x00ec>; + +template<> +struct Packet_Fixed<0x00ed>; +template<> +struct NetPacket_Fixed<0x00ed>; + +template<> +struct Packet_Fixed<0x00ee>; +template<> +struct NetPacket_Fixed<0x00ee>; + +template<> +struct Packet_Fixed<0x00ef>; +template<> +struct NetPacket_Fixed<0x00ef>; + +template<> +struct Packet_Fixed<0x00f0>; +template<> +struct NetPacket_Fixed<0x00f0>; + +template<> +struct Packet_Fixed<0x00f2>; +template<> +struct NetPacket_Fixed<0x00f2>; + +template<> +struct Packet_Fixed<0x00f3>; +template<> +struct NetPacket_Fixed<0x00f3>; + +template<> +struct Packet_Fixed<0x00f4>; +template<> +struct NetPacket_Fixed<0x00f4>; + +template<> +struct Packet_Fixed<0x00f5>; +template<> +struct NetPacket_Fixed<0x00f5>; + +template<> +struct Packet_Fixed<0x00f6>; +template<> +struct NetPacket_Fixed<0x00f6>; + +template<> +struct Packet_Fixed<0x00f7>; +template<> +struct NetPacket_Fixed<0x00f7>; + +template<> +struct Packet_Fixed<0x00f8>; +template<> +struct NetPacket_Fixed<0x00f8>; + +template<> +struct Packet_Fixed<0x00f9>; +template<> +struct NetPacket_Fixed<0x00f9>; + +template<> +struct Packet_Fixed<0x00fa>; +template<> +struct NetPacket_Fixed<0x00fa>; + +template<> +struct Packet_Head<0x00fb>; +template<> +struct NetPacket_Head<0x00fb>; +template<> +struct Packet_Repeat<0x00fb>; +template<> +struct NetPacket_Repeat<0x00fb>; + +template<> +struct Packet_Fixed<0x00fc>; +template<> +struct NetPacket_Fixed<0x00fc>; + +template<> +struct Packet_Fixed<0x00fd>; +template<> +struct NetPacket_Fixed<0x00fd>; + +template<> +struct Packet_Fixed<0x00fe>; +template<> +struct NetPacket_Fixed<0x00fe>; + +template<> +struct Packet_Fixed<0x00ff>; +template<> +struct NetPacket_Fixed<0x00ff>; + +template<> +struct Packet_Fixed<0x0100>; +template<> +struct NetPacket_Fixed<0x0100>; + +template<> +struct Packet_Fixed<0x0101>; +template<> +struct NetPacket_Fixed<0x0101>; + +template<> +struct Packet_Fixed<0x0102>; +template<> +struct NetPacket_Fixed<0x0102>; + +template<> +struct Packet_Fixed<0x0103>; +template<> +struct NetPacket_Fixed<0x0103>; + +template<> +struct Packet_Fixed<0x0105>; +template<> +struct NetPacket_Fixed<0x0105>; + +template<> +struct Packet_Fixed<0x0106>; +template<> +struct NetPacket_Fixed<0x0106>; + +template<> +struct Packet_Fixed<0x0107>; +template<> +struct NetPacket_Fixed<0x0107>; + +template<> +struct Packet_Head<0x0108>; +template<> +struct NetPacket_Head<0x0108>; +template<> +struct Packet_Repeat<0x0108>; +template<> +struct NetPacket_Repeat<0x0108>; + +template<> +struct Packet_Head<0x0109>; +template<> +struct NetPacket_Head<0x0109>; +template<> +struct Packet_Repeat<0x0109>; +template<> +struct NetPacket_Repeat<0x0109>; + +template<> +struct Packet_Fixed<0x010c>; +template<> +struct NetPacket_Fixed<0x010c>; + +template<> +struct Packet_Fixed<0x010e>; +template<> +struct NetPacket_Fixed<0x010e>; + +template<> +struct Packet_Head<0x010f>; +template<> +struct NetPacket_Head<0x010f>; +template<> +struct Packet_Repeat<0x010f>; +template<> +struct NetPacket_Repeat<0x010f>; + +template<> +struct Packet_Fixed<0x0110>; +template<> +struct NetPacket_Fixed<0x0110>; + +template<> +struct Packet_Fixed<0x0112>; +template<> +struct NetPacket_Fixed<0x0112>; + +template<> +struct Packet_Fixed<0x0118>; +template<> +struct NetPacket_Fixed<0x0118>; + +template<> +struct Packet_Fixed<0x0119>; +template<> +struct NetPacket_Fixed<0x0119>; + +template<> +struct Packet_Fixed<0x0139>; +template<> +struct NetPacket_Fixed<0x0139>; + +template<> +struct Packet_Fixed<0x013a>; +template<> +struct NetPacket_Fixed<0x013a>; + +template<> +struct Packet_Fixed<0x013b>; +template<> +struct NetPacket_Fixed<0x013b>; + +template<> +struct Packet_Fixed<0x013c>; +template<> +struct NetPacket_Fixed<0x013c>; + +template<> +struct Packet_Fixed<0x0141>; +template<> +struct NetPacket_Fixed<0x0141>; + +template<> +struct Packet_Fixed<0x0142>; +template<> +struct NetPacket_Fixed<0x0142>; + +template<> +struct Packet_Fixed<0x0143>; +template<> +struct NetPacket_Fixed<0x0143>; + +template<> +struct Packet_Fixed<0x0146>; +template<> +struct NetPacket_Fixed<0x0146>; + +template<> +struct Packet_Fixed<0x0147>; +template<> +struct NetPacket_Fixed<0x0147>; + +template<> +struct Packet_Fixed<0x0148>; +template<> +struct NetPacket_Fixed<0x0148>; + +template<> +struct Packet_Fixed<0x014d>; +template<> +struct NetPacket_Fixed<0x014d>; + +template<> +struct Packet_Fixed<0x018a>; +template<> +struct NetPacket_Fixed<0x018a>; + +template<> +struct Packet_Fixed<0x018b>; +template<> +struct NetPacket_Fixed<0x018b>; + +template<> +struct Packet_Fixed<0x0195>; +template<> +struct NetPacket_Fixed<0x0195>; + +template<> +struct Packet_Fixed<0x0196>; +template<> +struct NetPacket_Fixed<0x0196>; + +template<> +struct Packet_Fixed<0x019b>; +template<> +struct NetPacket_Fixed<0x019b>; + +template<> +struct Packet_Fixed<0x01b1>; +template<> +struct NetPacket_Fixed<0x01b1>; + +template<> +struct Packet_Fixed<0x01c8>; +template<> +struct NetPacket_Fixed<0x01c8>; + +template<> +struct Packet_Fixed<0x01d4>; +template<> +struct NetPacket_Fixed<0x01d4>; + +template<> +struct Packet_Head<0x01d5>; +template<> +struct NetPacket_Head<0x01d5>; +template<> +struct Packet_Repeat<0x01d5>; +template<> +struct NetPacket_Repeat<0x01d5>; + +template<> +struct Packet_Fixed<0x01d7>; +template<> +struct NetPacket_Fixed<0x01d7>; + +template<> +struct Packet_Fixed<0x01d8>; +template<> +struct NetPacket_Fixed<0x01d8>; + +template<> +struct Packet_Fixed<0x01d9>; +template<> +struct NetPacket_Fixed<0x01d9>; + +template<> +struct Packet_Fixed<0x01da>; +template<> +struct NetPacket_Fixed<0x01da>; + +template<> +struct Packet_Fixed<0x01de>; +template<> +struct NetPacket_Fixed<0x01de>; + +template<> +struct Packet_Head<0x01ee>; +template<> +struct NetPacket_Head<0x01ee>; +template<> +struct Packet_Repeat<0x01ee>; +template<> +struct NetPacket_Repeat<0x01ee>; + +template<> +struct Packet_Head<0x01f0>; +template<> +struct NetPacket_Head<0x01f0>; +template<> +struct Packet_Repeat<0x01f0>; +template<> +struct NetPacket_Repeat<0x01f0>; + +template<> +struct Packet_Fixed<0x020c>; +template<> +struct NetPacket_Fixed<0x020c>; + +template<> +struct Packet_Fixed<0x0212>; +template<> +struct NetPacket_Fixed<0x0212>; + + +template<> +struct Packet_Fixed<0x0081>; +template<> +struct NetPacket_Fixed<0x0081>; + +template<> +struct Packet_Fixed<0x7530>; +template<> +struct NetPacket_Fixed<0x7530>; + +template<> +struct Packet_Fixed<0x7531>; +template<> +struct NetPacket_Fixed<0x7531>; + +template<> +struct Packet_Fixed<0x7532>; +template<> +struct NetPacket_Fixed<0x7532>; + +template<> +struct Packet_Payload<0x8000>; +template<> +struct NetPacket_Payload<0x8000>; + + +} // namespace tmwa diff --git a/src/proto2/include_clif_t_test.cpp b/src/proto2/include_clif_t_test.cpp new file mode 100644 index 0000000..f0125fe --- /dev/null +++ b/src/proto2/include_clif_t_test.cpp @@ -0,0 +1,41 @@ +#include "../map/clif.t.hpp" +// include_clif_t_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_Position1 = Position1; +using Test_NetPosition1 = NetPosition1; +using Test_Position2 = Position2; +using Test_NetPosition2 = NetPosition2; +using Test_BeingRemoveWhy = BeingRemoveWhy; +using Test_DIR = DIR; +using Test_Opt1 = Opt1; +using Test_Opt2 = Opt2; +using Test_Opt3 = Opt3; +using Test_ItemType = ItemType; +using Test_PickupFail = PickupFail; +using Test_DamageType = DamageType; +using Test_SP = SP; +using Test_LOOK = LOOK; +using Test_IOff2 = IOff2; +using Test_SOff1 = SOff1; +} // namespace tmwa diff --git a/src/proto2/include_consts_test.cpp b/src/proto2/include_consts_test.cpp new file mode 100644 index 0000000..634c0e9 --- /dev/null +++ b/src/proto2/include_consts_test.cpp @@ -0,0 +1,26 @@ +#include "../mmo/consts.hpp" +// include_consts_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_PartyMember = PartyMember; +} // namespace tmwa diff --git a/src/proto2/include_cstdint_test.cpp b/src/proto2/include_cstdint_test.cpp new file mode 100644 index 0000000..85bab61 --- /dev/null +++ b/src/proto2/include_cstdint_test.cpp @@ -0,0 +1,33 @@ +#include <cstdint> +// include_cstdint_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_uint8_t = uint8_t; +using Test_uint16_t = uint16_t; +using Test_uint32_t = uint32_t; +using Test_uint64_t = uint64_t; +using Test_int8_t = int8_t; +using Test_int16_t = int16_t; +using Test_int32_t = int32_t; +using Test_int64_t = int64_t; +} // namespace tmwa diff --git a/src/proto2/include_enums_test.cpp b/src/proto2/include_enums_test.cpp new file mode 100644 index 0000000..f409d28 --- /dev/null +++ b/src/proto2/include_enums_test.cpp @@ -0,0 +1,29 @@ +#include "../mmo/enums.hpp" +// include_enums_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_SEX = SEX; +using Test_Option = Option; +using Test_EPOS = EPOS; +using Test_ItemLook = ItemLook; +} // namespace tmwa diff --git a/src/proto2/include_human_time_diff_test.cpp b/src/proto2/include_human_time_diff_test.cpp new file mode 100644 index 0000000..2e16c99 --- /dev/null +++ b/src/proto2/include_human_time_diff_test.cpp @@ -0,0 +1,26 @@ +#include "../mmo/human_time_diff.hpp" +// include_human_time_diff_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_HumanTimeDiff = HumanTimeDiff; +} // namespace tmwa diff --git a/src/proto2/include_ids_test.cpp b/src/proto2/include_ids_test.cpp new file mode 100644 index 0000000..1c1eeca --- /dev/null +++ b/src/proto2/include_ids_test.cpp @@ -0,0 +1,32 @@ +#include "../mmo/ids.hpp" +// include_ids_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_Species = Species; +using Test_AccountId = AccountId; +using Test_CharId = CharId; +using Test_PartyId = PartyId; +using Test_ItemNameId = ItemNameId; +using Test_BlockId = BlockId; +using Test_GmLevel = GmLevel; +} // namespace tmwa diff --git a/src/proto2/include_ip_test.cpp b/src/proto2/include_ip_test.cpp new file mode 100644 index 0000000..d380651 --- /dev/null +++ b/src/proto2/include_ip_test.cpp @@ -0,0 +1,26 @@ +#include "../net/ip.hpp" +// include_ip_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_IP4Address = IP4Address; +} // namespace tmwa diff --git a/src/proto2/include_little_test.cpp b/src/proto2/include_little_test.cpp new file mode 100644 index 0000000..08a4fbd --- /dev/null +++ b/src/proto2/include_little_test.cpp @@ -0,0 +1,29 @@ +#include "../ints/little.hpp" +// include_little_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_Byte = Byte; +using Test_Little16 = Little16; +using Test_Little32 = Little32; +using Test_Little64 = Little64; +} // namespace tmwa diff --git a/src/proto2/include_login_t_test.cpp b/src/proto2/include_login_t_test.cpp new file mode 100644 index 0000000..808e02e --- /dev/null +++ b/src/proto2/include_login_t_test.cpp @@ -0,0 +1,26 @@ +#include "../login/login.t.hpp" +// include_login_t_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_VERSION_2 = VERSION_2; +} // namespace tmwa diff --git a/src/proto2/include_skill_t_test.cpp b/src/proto2/include_skill_t_test.cpp new file mode 100644 index 0000000..4bd944f --- /dev/null +++ b/src/proto2/include_skill_t_test.cpp @@ -0,0 +1,28 @@ +#include "../map/skill.t.hpp" +// include_skill_t_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_SkillID = SkillID; +using Test_StatusChange = StatusChange; +using Test_SkillFlags = SkillFlags; +} // namespace tmwa diff --git a/src/proto2/include_strs_test.cpp b/src/proto2/include_strs_test.cpp new file mode 100644 index 0000000..67b41f4 --- /dev/null +++ b/src/proto2/include_strs_test.cpp @@ -0,0 +1,33 @@ +#include "../mmo/strs.hpp" +// include_strs_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_AccountName = AccountName; +using Test_AccountPass = AccountPass; +using Test_AccountEmail = AccountEmail; +using Test_ServerName = ServerName; +using Test_PartyName = PartyName; +using Test_VarName = VarName; +using Test_CharName = CharName; +using Test_MapName = MapName; +} // namespace tmwa diff --git a/src/proto2/include_timer_t_test.cpp b/src/proto2/include_timer_t_test.cpp new file mode 100644 index 0000000..a936021 --- /dev/null +++ b/src/proto2/include_timer_t_test.cpp @@ -0,0 +1,27 @@ +#include "../net/timer.t.hpp" +// include_timer_t_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_tick_t = tick_t; +using Test_interval_t = interval_t; +} // namespace tmwa diff --git a/src/proto2/include_utils_test.cpp b/src/proto2/include_utils_test.cpp new file mode 100644 index 0000000..5b6c92d --- /dev/null +++ b/src/proto2/include_utils_test.cpp @@ -0,0 +1,28 @@ +#include "../mmo/utils.hpp" +// include_utils_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_TimeT = TimeT; +using Test_timestamp_seconds_buffer = timestamp_seconds_buffer; +using Test_timestamp_milliseconds_buffer = timestamp_milliseconds_buffer; +} // namespace tmwa diff --git a/src/proto2/include_version_test.cpp b/src/proto2/include_version_test.cpp new file mode 100644 index 0000000..13856b9 --- /dev/null +++ b/src/proto2/include_version_test.cpp @@ -0,0 +1,26 @@ +#include "../mmo/version.hpp" +// include_version_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_Version = Version; +} // namespace tmwa diff --git a/src/proto2/include_vstring_test.cpp b/src/proto2/include_vstring_test.cpp new file mode 100644 index 0000000..3570a29 --- /dev/null +++ b/src/proto2/include_vstring_test.cpp @@ -0,0 +1,30 @@ +#include "../strings/vstring.hpp" +// include_vstring_test.cpp - testsuite for protocol includes +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + +namespace tmwa +{ +using Test_VString_15_ = VString<15>; +using Test_VString_19_ = VString<19>; +using Test_VString_23_ = VString<23>; +using Test_VString_31_ = VString<31>; +using Test_VString_39_ = VString<39>; +} // namespace tmwa diff --git a/src/proto2/login-admin.hpp b/src/proto2/login-admin.hpp new file mode 100644 index 0000000..9d5fb5e --- /dev/null +++ b/src/proto2/login-admin.hpp @@ -0,0 +1,2218 @@ +#pragma once +// login-admin.hpp - TMWA network protocol: login/admin +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "fwd.hpp" + +#include "types.hpp" + +namespace tmwa +{ +// This is an internal protocol, and can be changed without notice + +template<> +struct Packet_Head<0x2726> +{ + static const uint16_t PACKET_ID = 0x2726; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t unused = {}; + // TODO remove this + uint32_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x2726> +{ + static const uint16_t PACKET_ID = 0x2726; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x7918> +{ + static const uint16_t PACKET_ID = 0x7918; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t encryption_zero = {}; + AccountPass account_pass = {}; +}; + +template<> +struct Packet_Fixed<0x7919> +{ + static const uint16_t PACKET_ID = 0x7919; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t error = {}; +}; + +template<> +struct Packet_Fixed<0x7920> +{ + static const uint16_t PACKET_ID = 0x7920; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId start_account_id = {}; + AccountId end_account_id = {}; +}; + +template<> +struct Packet_Head<0x7921> +{ + static const uint16_t PACKET_ID = 0x7921; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x7921> +{ + static const uint16_t PACKET_ID = 0x7921; + + AccountId account_id = {}; + GmLevel gm_level = {}; + AccountName account_name = {}; + SEX sex = {}; + uint32_t login_count = {}; + uint32_t status = {}; +}; + +template<> +struct Packet_Fixed<0x7924> +{ + static const uint16_t PACKET_ID = 0x7924; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + ItemNameId source_item_id = {}; + ItemNameId dest_item_id = {}; +}; + +template<> +struct Packet_Fixed<0x7925> +{ + static const uint16_t PACKET_ID = 0x7925; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x7930> +{ + static const uint16_t PACKET_ID = 0x7930; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + AccountPass password = {}; + SEX sex = {}; + AccountEmail email = {}; +}; + +template<> +struct Packet_Fixed<0x7931> +{ + static const uint16_t PACKET_ID = 0x7931; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; +}; + +template<> +struct Packet_Fixed<0x7932> +{ + static const uint16_t PACKET_ID = 0x7932; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; +}; + +template<> +struct Packet_Fixed<0x7933> +{ + static const uint16_t PACKET_ID = 0x7933; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; +}; + +template<> +struct Packet_Fixed<0x7934> +{ + static const uint16_t PACKET_ID = 0x7934; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + AccountPass password = {}; +}; + +template<> +struct Packet_Fixed<0x7935> +{ + static const uint16_t PACKET_ID = 0x7935; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; +}; + +template<> +struct Packet_Fixed<0x7936> +{ + static const uint16_t PACKET_ID = 0x7936; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + uint32_t status = {}; + timestamp_seconds_buffer error_message = {}; +}; + +template<> +struct Packet_Fixed<0x7937> +{ + static const uint16_t PACKET_ID = 0x7937; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; + uint32_t status = {}; +}; + +template<> +struct Packet_Fixed<0x7938> +{ + static const uint16_t PACKET_ID = 0x7938; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Head<0x7939> +{ + static const uint16_t PACKET_ID = 0x7939; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x7939> +{ + static const uint16_t PACKET_ID = 0x7939; + + IP4Address ip = {}; + uint16_t port = {}; + ServerName name = {}; + uint16_t users = {}; + uint16_t maintenance = {}; + uint16_t is_new = {}; +}; + +template<> +struct Packet_Fixed<0x793a> +{ + static const uint16_t PACKET_ID = 0x793a; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + AccountPass password = {}; +}; + +template<> +struct Packet_Fixed<0x793b> +{ + static const uint16_t PACKET_ID = 0x793b; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; +}; + +template<> +struct Packet_Fixed<0x793c> +{ + static const uint16_t PACKET_ID = 0x793c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + SEX sex = {}; +}; + +template<> +struct Packet_Fixed<0x793d> +{ + static const uint16_t PACKET_ID = 0x793d; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; +}; + +template<> +struct Packet_Fixed<0x793e> +{ + static const uint16_t PACKET_ID = 0x793e; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + GmLevel gm_level = {}; +}; + +template<> +struct Packet_Fixed<0x793f> +{ + static const uint16_t PACKET_ID = 0x793f; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; +}; + +template<> +struct Packet_Fixed<0x7940> +{ + static const uint16_t PACKET_ID = 0x7940; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + AccountEmail email = {}; +}; + +template<> +struct Packet_Fixed<0x7941> +{ + static const uint16_t PACKET_ID = 0x7941; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; +}; + +template<> +struct Packet_Head<0x7942> +{ + static const uint16_t PACKET_ID = 0x7942; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x7942> +{ + static const uint16_t PACKET_ID = 0x7942; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x7943> +{ + static const uint16_t PACKET_ID = 0x7943; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; +}; + +template<> +struct Packet_Fixed<0x7944> +{ + static const uint16_t PACKET_ID = 0x7944; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; +}; + +template<> +struct Packet_Fixed<0x7945> +{ + static const uint16_t PACKET_ID = 0x7945; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; +}; + +template<> +struct Packet_Fixed<0x7946> +{ + static const uint16_t PACKET_ID = 0x7946; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x7947> +{ + static const uint16_t PACKET_ID = 0x7947; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; +}; + +template<> +struct Packet_Fixed<0x7948> +{ + static const uint16_t PACKET_ID = 0x7948; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + TimeT valid_until = {}; +}; + +template<> +struct Packet_Fixed<0x7949> +{ + static const uint16_t PACKET_ID = 0x7949; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; + TimeT valid_until = {}; +}; + +template<> +struct Packet_Fixed<0x794a> +{ + static const uint16_t PACKET_ID = 0x794a; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + TimeT ban_until = {}; +}; + +template<> +struct Packet_Fixed<0x794b> +{ + static const uint16_t PACKET_ID = 0x794b; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; + TimeT ban_until = {}; +}; + +template<> +struct Packet_Fixed<0x794c> +{ + static const uint16_t PACKET_ID = 0x794c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + HumanTimeDiff ban_add = {}; +}; + +template<> +struct Packet_Fixed<0x794d> +{ + static const uint16_t PACKET_ID = 0x794d; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; + TimeT ban_until = {}; +}; + +template<> +struct Packet_Head<0x794e> +{ + static const uint16_t PACKET_ID = 0x794e; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t unused = {}; + // TODO remove this + uint32_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x794e> +{ + static const uint16_t PACKET_ID = 0x794e; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x794f> +{ + static const uint16_t PACKET_ID = 0x794f; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t error = {}; +}; + +template<> +struct Packet_Fixed<0x7950> +{ + static const uint16_t PACKET_ID = 0x7950; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + HumanTimeDiff valid_add = {}; +}; + +template<> +struct Packet_Fixed<0x7951> +{ + static const uint16_t PACKET_ID = 0x7951; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountName account_name = {}; + TimeT valid_until = {}; +}; + +template<> +struct Packet_Fixed<0x7952> +{ + static const uint16_t PACKET_ID = 0x7952; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; +}; + +template<> +struct Packet_Head<0x7953> +{ + static const uint16_t PACKET_ID = 0x7953; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + GmLevel gm_level = {}; + AccountName account_name = {}; + SEX sex = {}; + uint32_t login_count = {}; + uint32_t state = {}; + timestamp_seconds_buffer error_message = {}; + timestamp_milliseconds_buffer last_login_string = {}; + VString<15> ip_string = {}; + AccountEmail email = {}; + TimeT connect_until = {}; + TimeT ban_until = {}; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x7953> +{ + static const uint16_t PACKET_ID = 0x7953; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x7954> +{ + static const uint16_t PACKET_ID = 0x7954; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x7955> +{ + static const uint16_t PACKET_ID = 0x7955; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + + +template<> +struct NetPacket_Head<0x2726> +{ + Little16 magic_packet_id; + Little16 unused; + SkewedLength<Little32, 8> magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x2726>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2726>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2726>, unused) == 2, "offsetof(NetPacket_Head<0x2726>, unused) == 2"); +static_assert(offsetof(NetPacket_Head<0x2726>, magic_packet_length) == 4, "offsetof(NetPacket_Head<0x2726>, magic_packet_length) == 4"); +static_assert(sizeof(NetPacket_Head<0x2726>) == 8, "sizeof(NetPacket_Head<0x2726>) == 8"); +static_assert(alignof(NetPacket_Head<0x2726>) == 1, "alignof(NetPacket_Head<0x2726>) == 1"); +template<> +struct NetPacket_Repeat<0x2726> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x2726>, c) == 0, "offsetof(NetPacket_Repeat<0x2726>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x2726>) == 1, "sizeof(NetPacket_Repeat<0x2726>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x2726>) == 1, "alignof(NetPacket_Repeat<0x2726>) == 1"); + +template<> +struct NetPacket_Fixed<0x7918> +{ + Little16 magic_packet_id; + Little16 encryption_zero; + NetString<sizeof(AccountPass)> account_pass; +}; +static_assert(offsetof(NetPacket_Fixed<0x7918>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7918>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7918>, encryption_zero) == 2, "offsetof(NetPacket_Fixed<0x7918>, encryption_zero) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7918>, account_pass) == 4, "offsetof(NetPacket_Fixed<0x7918>, account_pass) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x7918>) == 28, "sizeof(NetPacket_Fixed<0x7918>) == 28"); +static_assert(alignof(NetPacket_Fixed<0x7918>) == 1, "alignof(NetPacket_Fixed<0x7918>) == 1"); + +template<> +struct NetPacket_Fixed<0x7919> +{ + Little16 magic_packet_id; + Byte error; +}; +static_assert(offsetof(NetPacket_Fixed<0x7919>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7919>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7919>, error) == 2, "offsetof(NetPacket_Fixed<0x7919>, error) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x7919>) == 3, "sizeof(NetPacket_Fixed<0x7919>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x7919>) == 1, "alignof(NetPacket_Fixed<0x7919>) == 1"); + +template<> +struct NetPacket_Fixed<0x7920> +{ + Little16 magic_packet_id; + Little32 start_account_id; + Little32 end_account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x7920>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7920>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7920>, start_account_id) == 2, "offsetof(NetPacket_Fixed<0x7920>, start_account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7920>, end_account_id) == 6, "offsetof(NetPacket_Fixed<0x7920>, end_account_id) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x7920>) == 10, "sizeof(NetPacket_Fixed<0x7920>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x7920>) == 1, "alignof(NetPacket_Fixed<0x7920>) == 1"); + +template<> +struct NetPacket_Head<0x7921> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x7921>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x7921>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x7921>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x7921>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x7921>) == 4, "sizeof(NetPacket_Head<0x7921>) == 4"); +static_assert(alignof(NetPacket_Head<0x7921>) == 1, "alignof(NetPacket_Head<0x7921>) == 1"); +template<> +struct NetPacket_Repeat<0x7921> +{ + Little32 account_id; + Byte gm_level; + NetString<sizeof(AccountName)> account_name; + Byte sex; + Little32 login_count; + Little32 status; +}; +static_assert(offsetof(NetPacket_Repeat<0x7921>, account_id) == 0, "offsetof(NetPacket_Repeat<0x7921>, account_id) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x7921>, gm_level) == 4, "offsetof(NetPacket_Repeat<0x7921>, gm_level) == 4"); +static_assert(offsetof(NetPacket_Repeat<0x7921>, account_name) == 5, "offsetof(NetPacket_Repeat<0x7921>, account_name) == 5"); +static_assert(offsetof(NetPacket_Repeat<0x7921>, sex) == 29, "offsetof(NetPacket_Repeat<0x7921>, sex) == 29"); +static_assert(offsetof(NetPacket_Repeat<0x7921>, login_count) == 30, "offsetof(NetPacket_Repeat<0x7921>, login_count) == 30"); +static_assert(offsetof(NetPacket_Repeat<0x7921>, status) == 34, "offsetof(NetPacket_Repeat<0x7921>, status) == 34"); +static_assert(sizeof(NetPacket_Repeat<0x7921>) == 38, "sizeof(NetPacket_Repeat<0x7921>) == 38"); +static_assert(alignof(NetPacket_Repeat<0x7921>) == 1, "alignof(NetPacket_Repeat<0x7921>) == 1"); + +template<> +struct NetPacket_Fixed<0x7924> +{ + Little16 magic_packet_id; + Little32 source_item_id; + Little32 dest_item_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x7924>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7924>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7924>, source_item_id) == 2, "offsetof(NetPacket_Fixed<0x7924>, source_item_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7924>, dest_item_id) == 6, "offsetof(NetPacket_Fixed<0x7924>, dest_item_id) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x7924>) == 10, "sizeof(NetPacket_Fixed<0x7924>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x7924>) == 1, "alignof(NetPacket_Fixed<0x7924>) == 1"); + +template<> +struct NetPacket_Fixed<0x7925> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x7925>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7925>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x7925>) == 2, "sizeof(NetPacket_Fixed<0x7925>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x7925>) == 1, "alignof(NetPacket_Fixed<0x7925>) == 1"); + +template<> +struct NetPacket_Fixed<0x7930> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + NetString<sizeof(AccountPass)> password; + char sex; + NetString<sizeof(AccountEmail)> email; +}; +static_assert(offsetof(NetPacket_Fixed<0x7930>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7930>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7930>, account_name) == 2, "offsetof(NetPacket_Fixed<0x7930>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7930>, password) == 26, "offsetof(NetPacket_Fixed<0x7930>, password) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x7930>, sex) == 50, "offsetof(NetPacket_Fixed<0x7930>, sex) == 50"); +static_assert(offsetof(NetPacket_Fixed<0x7930>, email) == 51, "offsetof(NetPacket_Fixed<0x7930>, email) == 51"); +static_assert(sizeof(NetPacket_Fixed<0x7930>) == 91, "sizeof(NetPacket_Fixed<0x7930>) == 91"); +static_assert(alignof(NetPacket_Fixed<0x7930>) == 1, "alignof(NetPacket_Fixed<0x7930>) == 1"); + +template<> +struct NetPacket_Fixed<0x7931> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x7931>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7931>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7931>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7931>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7931>, account_name) == 6, "offsetof(NetPacket_Fixed<0x7931>, account_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x7931>) == 30, "sizeof(NetPacket_Fixed<0x7931>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x7931>) == 1, "alignof(NetPacket_Fixed<0x7931>) == 1"); + +template<> +struct NetPacket_Fixed<0x7932> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x7932>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7932>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7932>, account_name) == 2, "offsetof(NetPacket_Fixed<0x7932>, account_name) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x7932>) == 26, "sizeof(NetPacket_Fixed<0x7932>) == 26"); +static_assert(alignof(NetPacket_Fixed<0x7932>) == 1, "alignof(NetPacket_Fixed<0x7932>) == 1"); + +template<> +struct NetPacket_Fixed<0x7933> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x7933>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7933>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7933>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7933>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7933>, account_name) == 6, "offsetof(NetPacket_Fixed<0x7933>, account_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x7933>) == 30, "sizeof(NetPacket_Fixed<0x7933>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x7933>) == 1, "alignof(NetPacket_Fixed<0x7933>) == 1"); + +template<> +struct NetPacket_Fixed<0x7934> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + NetString<sizeof(AccountPass)> password; +}; +static_assert(offsetof(NetPacket_Fixed<0x7934>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7934>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7934>, account_name) == 2, "offsetof(NetPacket_Fixed<0x7934>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7934>, password) == 26, "offsetof(NetPacket_Fixed<0x7934>, password) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x7934>) == 50, "sizeof(NetPacket_Fixed<0x7934>) == 50"); +static_assert(alignof(NetPacket_Fixed<0x7934>) == 1, "alignof(NetPacket_Fixed<0x7934>) == 1"); + +template<> +struct NetPacket_Fixed<0x7935> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x7935>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7935>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7935>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7935>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7935>, account_name) == 6, "offsetof(NetPacket_Fixed<0x7935>, account_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x7935>) == 30, "sizeof(NetPacket_Fixed<0x7935>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x7935>) == 1, "alignof(NetPacket_Fixed<0x7935>) == 1"); + +template<> +struct NetPacket_Fixed<0x7936> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + Little32 status; + NetString<sizeof(timestamp_seconds_buffer)> error_message; +}; +static_assert(offsetof(NetPacket_Fixed<0x7936>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7936>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7936>, account_name) == 2, "offsetof(NetPacket_Fixed<0x7936>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7936>, status) == 26, "offsetof(NetPacket_Fixed<0x7936>, status) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x7936>, error_message) == 30, "offsetof(NetPacket_Fixed<0x7936>, error_message) == 30"); +static_assert(sizeof(NetPacket_Fixed<0x7936>) == 50, "sizeof(NetPacket_Fixed<0x7936>) == 50"); +static_assert(alignof(NetPacket_Fixed<0x7936>) == 1, "alignof(NetPacket_Fixed<0x7936>) == 1"); + +template<> +struct NetPacket_Fixed<0x7937> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; + Little32 status; +}; +static_assert(offsetof(NetPacket_Fixed<0x7937>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7937>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7937>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7937>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7937>, account_name) == 6, "offsetof(NetPacket_Fixed<0x7937>, account_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x7937>, status) == 30, "offsetof(NetPacket_Fixed<0x7937>, status) == 30"); +static_assert(sizeof(NetPacket_Fixed<0x7937>) == 34, "sizeof(NetPacket_Fixed<0x7937>) == 34"); +static_assert(alignof(NetPacket_Fixed<0x7937>) == 1, "alignof(NetPacket_Fixed<0x7937>) == 1"); + +template<> +struct NetPacket_Fixed<0x7938> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x7938>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7938>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x7938>) == 2, "sizeof(NetPacket_Fixed<0x7938>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x7938>) == 1, "alignof(NetPacket_Fixed<0x7938>) == 1"); + +template<> +struct NetPacket_Head<0x7939> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x7939>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x7939>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x7939>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x7939>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x7939>) == 4, "sizeof(NetPacket_Head<0x7939>) == 4"); +static_assert(alignof(NetPacket_Head<0x7939>) == 1, "alignof(NetPacket_Head<0x7939>) == 1"); +template<> +struct NetPacket_Repeat<0x7939> +{ + IP4Address ip; + Little16 port; + NetString<sizeof(ServerName)> name; + Little16 users; + Little16 maintenance; + Little16 is_new; +}; +static_assert(offsetof(NetPacket_Repeat<0x7939>, ip) == 0, "offsetof(NetPacket_Repeat<0x7939>, ip) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x7939>, port) == 4, "offsetof(NetPacket_Repeat<0x7939>, port) == 4"); +static_assert(offsetof(NetPacket_Repeat<0x7939>, name) == 6, "offsetof(NetPacket_Repeat<0x7939>, name) == 6"); +static_assert(offsetof(NetPacket_Repeat<0x7939>, users) == 26, "offsetof(NetPacket_Repeat<0x7939>, users) == 26"); +static_assert(offsetof(NetPacket_Repeat<0x7939>, maintenance) == 28, "offsetof(NetPacket_Repeat<0x7939>, maintenance) == 28"); +static_assert(offsetof(NetPacket_Repeat<0x7939>, is_new) == 30, "offsetof(NetPacket_Repeat<0x7939>, is_new) == 30"); +static_assert(sizeof(NetPacket_Repeat<0x7939>) == 32, "sizeof(NetPacket_Repeat<0x7939>) == 32"); +static_assert(alignof(NetPacket_Repeat<0x7939>) == 1, "alignof(NetPacket_Repeat<0x7939>) == 1"); + +template<> +struct NetPacket_Fixed<0x793a> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + NetString<sizeof(AccountPass)> password; +}; +static_assert(offsetof(NetPacket_Fixed<0x793a>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x793a>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x793a>, account_name) == 2, "offsetof(NetPacket_Fixed<0x793a>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x793a>, password) == 26, "offsetof(NetPacket_Fixed<0x793a>, password) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x793a>) == 50, "sizeof(NetPacket_Fixed<0x793a>) == 50"); +static_assert(alignof(NetPacket_Fixed<0x793a>) == 1, "alignof(NetPacket_Fixed<0x793a>) == 1"); + +template<> +struct NetPacket_Fixed<0x793b> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x793b>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x793b>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x793b>, account_id) == 2, "offsetof(NetPacket_Fixed<0x793b>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x793b>, account_name) == 6, "offsetof(NetPacket_Fixed<0x793b>, account_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x793b>) == 30, "sizeof(NetPacket_Fixed<0x793b>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x793b>) == 1, "alignof(NetPacket_Fixed<0x793b>) == 1"); + +template<> +struct NetPacket_Fixed<0x793c> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + char sex; +}; +static_assert(offsetof(NetPacket_Fixed<0x793c>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x793c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x793c>, account_name) == 2, "offsetof(NetPacket_Fixed<0x793c>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x793c>, sex) == 26, "offsetof(NetPacket_Fixed<0x793c>, sex) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x793c>) == 27, "sizeof(NetPacket_Fixed<0x793c>) == 27"); +static_assert(alignof(NetPacket_Fixed<0x793c>) == 1, "alignof(NetPacket_Fixed<0x793c>) == 1"); + +template<> +struct NetPacket_Fixed<0x793d> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x793d>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x793d>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x793d>, account_id) == 2, "offsetof(NetPacket_Fixed<0x793d>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x793d>, account_name) == 6, "offsetof(NetPacket_Fixed<0x793d>, account_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x793d>) == 30, "sizeof(NetPacket_Fixed<0x793d>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x793d>) == 1, "alignof(NetPacket_Fixed<0x793d>) == 1"); + +template<> +struct NetPacket_Fixed<0x793e> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + Byte gm_level; +}; +static_assert(offsetof(NetPacket_Fixed<0x793e>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x793e>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x793e>, account_name) == 2, "offsetof(NetPacket_Fixed<0x793e>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x793e>, gm_level) == 26, "offsetof(NetPacket_Fixed<0x793e>, gm_level) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x793e>) == 27, "sizeof(NetPacket_Fixed<0x793e>) == 27"); +static_assert(alignof(NetPacket_Fixed<0x793e>) == 1, "alignof(NetPacket_Fixed<0x793e>) == 1"); + +template<> +struct NetPacket_Fixed<0x793f> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x793f>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x793f>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x793f>, account_id) == 2, "offsetof(NetPacket_Fixed<0x793f>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x793f>, account_name) == 6, "offsetof(NetPacket_Fixed<0x793f>, account_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x793f>) == 30, "sizeof(NetPacket_Fixed<0x793f>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x793f>) == 1, "alignof(NetPacket_Fixed<0x793f>) == 1"); + +template<> +struct NetPacket_Fixed<0x7940> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + NetString<sizeof(AccountEmail)> email; +}; +static_assert(offsetof(NetPacket_Fixed<0x7940>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7940>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7940>, account_name) == 2, "offsetof(NetPacket_Fixed<0x7940>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7940>, email) == 26, "offsetof(NetPacket_Fixed<0x7940>, email) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x7940>) == 66, "sizeof(NetPacket_Fixed<0x7940>) == 66"); +static_assert(alignof(NetPacket_Fixed<0x7940>) == 1, "alignof(NetPacket_Fixed<0x7940>) == 1"); + +template<> +struct NetPacket_Fixed<0x7941> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x7941>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7941>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7941>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7941>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7941>, account_name) == 6, "offsetof(NetPacket_Fixed<0x7941>, account_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x7941>) == 30, "sizeof(NetPacket_Fixed<0x7941>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x7941>) == 1, "alignof(NetPacket_Fixed<0x7941>) == 1"); + +template<> +struct NetPacket_Head<0x7942> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + SkewedLength<Little16, 28> magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x7942>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x7942>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x7942>, account_name) == 2, "offsetof(NetPacket_Head<0x7942>, account_name) == 2"); +static_assert(offsetof(NetPacket_Head<0x7942>, magic_packet_length) == 26, "offsetof(NetPacket_Head<0x7942>, magic_packet_length) == 26"); +static_assert(sizeof(NetPacket_Head<0x7942>) == 28, "sizeof(NetPacket_Head<0x7942>) == 28"); +static_assert(alignof(NetPacket_Head<0x7942>) == 1, "alignof(NetPacket_Head<0x7942>) == 1"); +template<> +struct NetPacket_Repeat<0x7942> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x7942>, c) == 0, "offsetof(NetPacket_Repeat<0x7942>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x7942>) == 1, "sizeof(NetPacket_Repeat<0x7942>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x7942>) == 1, "alignof(NetPacket_Repeat<0x7942>) == 1"); + +template<> +struct NetPacket_Fixed<0x7943> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x7943>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7943>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7943>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7943>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7943>, account_name) == 6, "offsetof(NetPacket_Fixed<0x7943>, account_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x7943>) == 30, "sizeof(NetPacket_Fixed<0x7943>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x7943>) == 1, "alignof(NetPacket_Fixed<0x7943>) == 1"); + +template<> +struct NetPacket_Fixed<0x7944> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x7944>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7944>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7944>, account_name) == 2, "offsetof(NetPacket_Fixed<0x7944>, account_name) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x7944>) == 26, "sizeof(NetPacket_Fixed<0x7944>) == 26"); +static_assert(alignof(NetPacket_Fixed<0x7944>) == 1, "alignof(NetPacket_Fixed<0x7944>) == 1"); + +template<> +struct NetPacket_Fixed<0x7945> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x7945>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7945>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7945>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7945>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7945>, account_name) == 6, "offsetof(NetPacket_Fixed<0x7945>, account_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x7945>) == 30, "sizeof(NetPacket_Fixed<0x7945>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x7945>) == 1, "alignof(NetPacket_Fixed<0x7945>) == 1"); + +template<> +struct NetPacket_Fixed<0x7946> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x7946>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7946>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7946>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7946>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x7946>) == 6, "sizeof(NetPacket_Fixed<0x7946>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x7946>) == 1, "alignof(NetPacket_Fixed<0x7946>) == 1"); + +template<> +struct NetPacket_Fixed<0x7947> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x7947>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7947>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7947>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7947>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7947>, account_name) == 6, "offsetof(NetPacket_Fixed<0x7947>, account_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x7947>) == 30, "sizeof(NetPacket_Fixed<0x7947>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x7947>) == 1, "alignof(NetPacket_Fixed<0x7947>) == 1"); + +template<> +struct NetPacket_Fixed<0x7948> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + Little32 valid_until; +}; +static_assert(offsetof(NetPacket_Fixed<0x7948>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7948>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7948>, account_name) == 2, "offsetof(NetPacket_Fixed<0x7948>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7948>, valid_until) == 26, "offsetof(NetPacket_Fixed<0x7948>, valid_until) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x7948>) == 30, "sizeof(NetPacket_Fixed<0x7948>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x7948>) == 1, "alignof(NetPacket_Fixed<0x7948>) == 1"); + +template<> +struct NetPacket_Fixed<0x7949> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; + Little32 valid_until; +}; +static_assert(offsetof(NetPacket_Fixed<0x7949>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7949>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7949>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7949>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7949>, account_name) == 6, "offsetof(NetPacket_Fixed<0x7949>, account_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x7949>, valid_until) == 30, "offsetof(NetPacket_Fixed<0x7949>, valid_until) == 30"); +static_assert(sizeof(NetPacket_Fixed<0x7949>) == 34, "sizeof(NetPacket_Fixed<0x7949>) == 34"); +static_assert(alignof(NetPacket_Fixed<0x7949>) == 1, "alignof(NetPacket_Fixed<0x7949>) == 1"); + +template<> +struct NetPacket_Fixed<0x794a> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + Little32 ban_until; +}; +static_assert(offsetof(NetPacket_Fixed<0x794a>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x794a>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x794a>, account_name) == 2, "offsetof(NetPacket_Fixed<0x794a>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x794a>, ban_until) == 26, "offsetof(NetPacket_Fixed<0x794a>, ban_until) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x794a>) == 30, "sizeof(NetPacket_Fixed<0x794a>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x794a>) == 1, "alignof(NetPacket_Fixed<0x794a>) == 1"); + +template<> +struct NetPacket_Fixed<0x794b> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; + Little32 ban_until; +}; +static_assert(offsetof(NetPacket_Fixed<0x794b>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x794b>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x794b>, account_id) == 2, "offsetof(NetPacket_Fixed<0x794b>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x794b>, account_name) == 6, "offsetof(NetPacket_Fixed<0x794b>, account_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x794b>, ban_until) == 30, "offsetof(NetPacket_Fixed<0x794b>, ban_until) == 30"); +static_assert(sizeof(NetPacket_Fixed<0x794b>) == 34, "sizeof(NetPacket_Fixed<0x794b>) == 34"); +static_assert(alignof(NetPacket_Fixed<0x794b>) == 1, "alignof(NetPacket_Fixed<0x794b>) == 1"); + +template<> +struct NetPacket_Fixed<0x794c> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + NetHumanTimeDiff ban_add; +}; +static_assert(offsetof(NetPacket_Fixed<0x794c>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x794c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x794c>, account_name) == 2, "offsetof(NetPacket_Fixed<0x794c>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x794c>, ban_add) == 26, "offsetof(NetPacket_Fixed<0x794c>, ban_add) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x794c>) == 38, "sizeof(NetPacket_Fixed<0x794c>) == 38"); +static_assert(alignof(NetPacket_Fixed<0x794c>) == 1, "alignof(NetPacket_Fixed<0x794c>) == 1"); + +template<> +struct NetPacket_Fixed<0x794d> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; + Little32 ban_until; +}; +static_assert(offsetof(NetPacket_Fixed<0x794d>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x794d>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x794d>, account_id) == 2, "offsetof(NetPacket_Fixed<0x794d>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x794d>, account_name) == 6, "offsetof(NetPacket_Fixed<0x794d>, account_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x794d>, ban_until) == 30, "offsetof(NetPacket_Fixed<0x794d>, ban_until) == 30"); +static_assert(sizeof(NetPacket_Fixed<0x794d>) == 34, "sizeof(NetPacket_Fixed<0x794d>) == 34"); +static_assert(alignof(NetPacket_Fixed<0x794d>) == 1, "alignof(NetPacket_Fixed<0x794d>) == 1"); + +template<> +struct NetPacket_Head<0x794e> +{ + Little16 magic_packet_id; + Little16 unused; + SkewedLength<Little32, 8> magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x794e>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x794e>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x794e>, unused) == 2, "offsetof(NetPacket_Head<0x794e>, unused) == 2"); +static_assert(offsetof(NetPacket_Head<0x794e>, magic_packet_length) == 4, "offsetof(NetPacket_Head<0x794e>, magic_packet_length) == 4"); +static_assert(sizeof(NetPacket_Head<0x794e>) == 8, "sizeof(NetPacket_Head<0x794e>) == 8"); +static_assert(alignof(NetPacket_Head<0x794e>) == 1, "alignof(NetPacket_Head<0x794e>) == 1"); +template<> +struct NetPacket_Repeat<0x794e> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x794e>, c) == 0, "offsetof(NetPacket_Repeat<0x794e>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x794e>) == 1, "sizeof(NetPacket_Repeat<0x794e>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x794e>) == 1, "alignof(NetPacket_Repeat<0x794e>) == 1"); + +template<> +struct NetPacket_Fixed<0x794f> +{ + Little16 magic_packet_id; + Little16 error; +}; +static_assert(offsetof(NetPacket_Fixed<0x794f>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x794f>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x794f>, error) == 2, "offsetof(NetPacket_Fixed<0x794f>, error) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x794f>) == 4, "sizeof(NetPacket_Fixed<0x794f>) == 4"); +static_assert(alignof(NetPacket_Fixed<0x794f>) == 1, "alignof(NetPacket_Fixed<0x794f>) == 1"); + +template<> +struct NetPacket_Fixed<0x7950> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + NetHumanTimeDiff valid_add; +}; +static_assert(offsetof(NetPacket_Fixed<0x7950>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7950>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7950>, account_name) == 2, "offsetof(NetPacket_Fixed<0x7950>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7950>, valid_add) == 26, "offsetof(NetPacket_Fixed<0x7950>, valid_add) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x7950>) == 38, "sizeof(NetPacket_Fixed<0x7950>) == 38"); +static_assert(alignof(NetPacket_Fixed<0x7950>) == 1, "alignof(NetPacket_Fixed<0x7950>) == 1"); + +template<> +struct NetPacket_Fixed<0x7951> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountName)> account_name; + Little32 valid_until; +}; +static_assert(offsetof(NetPacket_Fixed<0x7951>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7951>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7951>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7951>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x7951>, account_name) == 6, "offsetof(NetPacket_Fixed<0x7951>, account_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x7951>, valid_until) == 30, "offsetof(NetPacket_Fixed<0x7951>, valid_until) == 30"); +static_assert(sizeof(NetPacket_Fixed<0x7951>) == 34, "sizeof(NetPacket_Fixed<0x7951>) == 34"); +static_assert(alignof(NetPacket_Fixed<0x7951>) == 1, "alignof(NetPacket_Fixed<0x7951>) == 1"); + +template<> +struct NetPacket_Fixed<0x7952> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x7952>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7952>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7952>, account_name) == 2, "offsetof(NetPacket_Fixed<0x7952>, account_name) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x7952>) == 26, "sizeof(NetPacket_Fixed<0x7952>) == 26"); +static_assert(alignof(NetPacket_Fixed<0x7952>) == 1, "alignof(NetPacket_Fixed<0x7952>) == 1"); + +template<> +struct NetPacket_Head<0x7953> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte gm_level; + NetString<sizeof(AccountName)> account_name; + Byte sex; + Little32 login_count; + Little32 state; + NetString<sizeof(timestamp_seconds_buffer)> error_message; + NetString<sizeof(timestamp_milliseconds_buffer)> last_login_string; + NetString<sizeof(VString<15>)> ip_string; + NetString<sizeof(AccountEmail)> email; + Little32 connect_until; + Little32 ban_until; + SkewedLength<Little16, 150> magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x7953>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x7953>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x7953>, account_id) == 2, "offsetof(NetPacket_Head<0x7953>, account_id) == 2"); +static_assert(offsetof(NetPacket_Head<0x7953>, gm_level) == 6, "offsetof(NetPacket_Head<0x7953>, gm_level) == 6"); +static_assert(offsetof(NetPacket_Head<0x7953>, account_name) == 7, "offsetof(NetPacket_Head<0x7953>, account_name) == 7"); +static_assert(offsetof(NetPacket_Head<0x7953>, sex) == 31, "offsetof(NetPacket_Head<0x7953>, sex) == 31"); +static_assert(offsetof(NetPacket_Head<0x7953>, login_count) == 32, "offsetof(NetPacket_Head<0x7953>, login_count) == 32"); +static_assert(offsetof(NetPacket_Head<0x7953>, state) == 36, "offsetof(NetPacket_Head<0x7953>, state) == 36"); +static_assert(offsetof(NetPacket_Head<0x7953>, error_message) == 40, "offsetof(NetPacket_Head<0x7953>, error_message) == 40"); +static_assert(offsetof(NetPacket_Head<0x7953>, last_login_string) == 60, "offsetof(NetPacket_Head<0x7953>, last_login_string) == 60"); +static_assert(offsetof(NetPacket_Head<0x7953>, ip_string) == 84, "offsetof(NetPacket_Head<0x7953>, ip_string) == 84"); +static_assert(offsetof(NetPacket_Head<0x7953>, email) == 100, "offsetof(NetPacket_Head<0x7953>, email) == 100"); +static_assert(offsetof(NetPacket_Head<0x7953>, connect_until) == 140, "offsetof(NetPacket_Head<0x7953>, connect_until) == 140"); +static_assert(offsetof(NetPacket_Head<0x7953>, ban_until) == 144, "offsetof(NetPacket_Head<0x7953>, ban_until) == 144"); +static_assert(offsetof(NetPacket_Head<0x7953>, magic_packet_length) == 148, "offsetof(NetPacket_Head<0x7953>, magic_packet_length) == 148"); +static_assert(sizeof(NetPacket_Head<0x7953>) == 150, "sizeof(NetPacket_Head<0x7953>) == 150"); +static_assert(alignof(NetPacket_Head<0x7953>) == 1, "alignof(NetPacket_Head<0x7953>) == 1"); +template<> +struct NetPacket_Repeat<0x7953> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x7953>, c) == 0, "offsetof(NetPacket_Repeat<0x7953>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x7953>) == 1, "sizeof(NetPacket_Repeat<0x7953>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x7953>) == 1, "alignof(NetPacket_Repeat<0x7953>) == 1"); + +template<> +struct NetPacket_Fixed<0x7954> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x7954>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7954>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x7954>, account_id) == 2, "offsetof(NetPacket_Fixed<0x7954>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x7954>) == 6, "sizeof(NetPacket_Fixed<0x7954>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x7954>) == 1, "alignof(NetPacket_Fixed<0x7954>) == 1"); + +template<> +struct NetPacket_Fixed<0x7955> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x7955>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x7955>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x7955>) == 2, "sizeof(NetPacket_Fixed<0x7955>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x7955>) == 1, "alignof(NetPacket_Fixed<0x7955>) == 1"); + + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2726> *network, Packet_Head<0x2726> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->unused, native.unused); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2726> *native, NetPacket_Head<0x2726> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->unused, network.unused); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2726> *network, Packet_Repeat<0x2726> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2726> *native, NetPacket_Repeat<0x2726> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7918> *network, Packet_Fixed<0x7918> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->encryption_zero, native.encryption_zero); + rv &= native_to_network(&network->account_pass, native.account_pass); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7918> *native, NetPacket_Fixed<0x7918> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->encryption_zero, network.encryption_zero); + rv &= network_to_native(&native->account_pass, network.account_pass); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7919> *network, Packet_Fixed<0x7919> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->error, native.error); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7919> *native, NetPacket_Fixed<0x7919> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->error, network.error); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7920> *network, Packet_Fixed<0x7920> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->start_account_id, native.start_account_id); + rv &= native_to_network(&network->end_account_id, native.end_account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7920> *native, NetPacket_Fixed<0x7920> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->start_account_id, network.start_account_id); + rv &= network_to_native(&native->end_account_id, network.end_account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x7921> *network, Packet_Head<0x7921> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x7921> *native, NetPacket_Head<0x7921> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x7921> *network, Packet_Repeat<0x7921> native) +{ + bool rv = true; + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->gm_level, native.gm_level); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->sex, native.sex); + rv &= native_to_network(&network->login_count, native.login_count); + rv &= native_to_network(&network->status, native.status); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x7921> *native, NetPacket_Repeat<0x7921> network) +{ + bool rv = true; + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->gm_level, network.gm_level); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->sex, network.sex); + rv &= network_to_native(&native->login_count, network.login_count); + rv &= network_to_native(&native->status, network.status); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7924> *network, Packet_Fixed<0x7924> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->source_item_id, native.source_item_id); + rv &= native_to_network(&network->dest_item_id, native.dest_item_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7924> *native, NetPacket_Fixed<0x7924> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->source_item_id, network.source_item_id); + rv &= network_to_native(&native->dest_item_id, network.dest_item_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7925> *network, Packet_Fixed<0x7925> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7925> *native, NetPacket_Fixed<0x7925> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7930> *network, Packet_Fixed<0x7930> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->password, native.password); + rv &= native_to_network(&network->sex, native.sex); + rv &= native_to_network(&network->email, native.email); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7930> *native, NetPacket_Fixed<0x7930> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->password, network.password); + rv &= network_to_native(&native->sex, network.sex); + rv &= network_to_native(&native->email, network.email); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7931> *network, Packet_Fixed<0x7931> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7931> *native, NetPacket_Fixed<0x7931> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7932> *network, Packet_Fixed<0x7932> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7932> *native, NetPacket_Fixed<0x7932> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7933> *network, Packet_Fixed<0x7933> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7933> *native, NetPacket_Fixed<0x7933> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7934> *network, Packet_Fixed<0x7934> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->password, native.password); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7934> *native, NetPacket_Fixed<0x7934> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->password, network.password); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7935> *network, Packet_Fixed<0x7935> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7935> *native, NetPacket_Fixed<0x7935> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7936> *network, Packet_Fixed<0x7936> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->status, native.status); + rv &= native_to_network(&network->error_message, native.error_message); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7936> *native, NetPacket_Fixed<0x7936> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->status, network.status); + rv &= network_to_native(&native->error_message, network.error_message); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7937> *network, Packet_Fixed<0x7937> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->status, native.status); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7937> *native, NetPacket_Fixed<0x7937> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->status, network.status); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7938> *network, Packet_Fixed<0x7938> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7938> *native, NetPacket_Fixed<0x7938> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x7939> *network, Packet_Head<0x7939> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x7939> *native, NetPacket_Head<0x7939> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x7939> *network, Packet_Repeat<0x7939> native) +{ + bool rv = true; + rv &= native_to_network(&network->ip, native.ip); + rv &= native_to_network(&network->port, native.port); + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->users, native.users); + rv &= native_to_network(&network->maintenance, native.maintenance); + rv &= native_to_network(&network->is_new, native.is_new); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x7939> *native, NetPacket_Repeat<0x7939> network) +{ + bool rv = true; + rv &= network_to_native(&native->ip, network.ip); + rv &= network_to_native(&native->port, network.port); + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->users, network.users); + rv &= network_to_native(&native->maintenance, network.maintenance); + rv &= network_to_native(&native->is_new, network.is_new); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x793a> *network, Packet_Fixed<0x793a> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->password, native.password); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x793a> *native, NetPacket_Fixed<0x793a> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->password, network.password); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x793b> *network, Packet_Fixed<0x793b> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x793b> *native, NetPacket_Fixed<0x793b> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x793c> *network, Packet_Fixed<0x793c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->sex, native.sex); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x793c> *native, NetPacket_Fixed<0x793c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->sex, network.sex); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x793d> *network, Packet_Fixed<0x793d> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x793d> *native, NetPacket_Fixed<0x793d> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x793e> *network, Packet_Fixed<0x793e> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->gm_level, native.gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x793e> *native, NetPacket_Fixed<0x793e> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->gm_level, network.gm_level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x793f> *network, Packet_Fixed<0x793f> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x793f> *native, NetPacket_Fixed<0x793f> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7940> *network, Packet_Fixed<0x7940> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->email, native.email); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7940> *native, NetPacket_Fixed<0x7940> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->email, network.email); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7941> *network, Packet_Fixed<0x7941> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7941> *native, NetPacket_Fixed<0x7941> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x7942> *network, Packet_Head<0x7942> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x7942> *native, NetPacket_Head<0x7942> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x7942> *network, Packet_Repeat<0x7942> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x7942> *native, NetPacket_Repeat<0x7942> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7943> *network, Packet_Fixed<0x7943> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7943> *native, NetPacket_Fixed<0x7943> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7944> *network, Packet_Fixed<0x7944> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7944> *native, NetPacket_Fixed<0x7944> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7945> *network, Packet_Fixed<0x7945> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7945> *native, NetPacket_Fixed<0x7945> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7946> *network, Packet_Fixed<0x7946> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7946> *native, NetPacket_Fixed<0x7946> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7947> *network, Packet_Fixed<0x7947> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7947> *native, NetPacket_Fixed<0x7947> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7948> *network, Packet_Fixed<0x7948> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->valid_until, native.valid_until); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7948> *native, NetPacket_Fixed<0x7948> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->valid_until, network.valid_until); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7949> *network, Packet_Fixed<0x7949> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->valid_until, native.valid_until); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7949> *native, NetPacket_Fixed<0x7949> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->valid_until, network.valid_until); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x794a> *network, Packet_Fixed<0x794a> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->ban_until, native.ban_until); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x794a> *native, NetPacket_Fixed<0x794a> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->ban_until, network.ban_until); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x794b> *network, Packet_Fixed<0x794b> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->ban_until, native.ban_until); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x794b> *native, NetPacket_Fixed<0x794b> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->ban_until, network.ban_until); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x794c> *network, Packet_Fixed<0x794c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->ban_add, native.ban_add); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x794c> *native, NetPacket_Fixed<0x794c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->ban_add, network.ban_add); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x794d> *network, Packet_Fixed<0x794d> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->ban_until, native.ban_until); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x794d> *native, NetPacket_Fixed<0x794d> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->ban_until, network.ban_until); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x794e> *network, Packet_Head<0x794e> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->unused, native.unused); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x794e> *native, NetPacket_Head<0x794e> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->unused, network.unused); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x794e> *network, Packet_Repeat<0x794e> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x794e> *native, NetPacket_Repeat<0x794e> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x794f> *network, Packet_Fixed<0x794f> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->error, native.error); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x794f> *native, NetPacket_Fixed<0x794f> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->error, network.error); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7950> *network, Packet_Fixed<0x7950> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->valid_add, native.valid_add); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7950> *native, NetPacket_Fixed<0x7950> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->valid_add, network.valid_add); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7951> *network, Packet_Fixed<0x7951> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->valid_until, native.valid_until); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7951> *native, NetPacket_Fixed<0x7951> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->valid_until, network.valid_until); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7952> *network, Packet_Fixed<0x7952> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7952> *native, NetPacket_Fixed<0x7952> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x7953> *network, Packet_Head<0x7953> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->gm_level, native.gm_level); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->sex, native.sex); + rv &= native_to_network(&network->login_count, native.login_count); + rv &= native_to_network(&network->state, native.state); + rv &= native_to_network(&network->error_message, native.error_message); + rv &= native_to_network(&network->last_login_string, native.last_login_string); + rv &= native_to_network(&network->ip_string, native.ip_string); + rv &= native_to_network(&network->email, native.email); + rv &= native_to_network(&network->connect_until, native.connect_until); + rv &= native_to_network(&network->ban_until, native.ban_until); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x7953> *native, NetPacket_Head<0x7953> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->gm_level, network.gm_level); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->sex, network.sex); + rv &= network_to_native(&native->login_count, network.login_count); + rv &= network_to_native(&native->state, network.state); + rv &= network_to_native(&native->error_message, network.error_message); + rv &= network_to_native(&native->last_login_string, network.last_login_string); + rv &= network_to_native(&native->ip_string, network.ip_string); + rv &= network_to_native(&native->email, network.email); + rv &= network_to_native(&native->connect_until, network.connect_until); + rv &= network_to_native(&native->ban_until, network.ban_until); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x7953> *network, Packet_Repeat<0x7953> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x7953> *native, NetPacket_Repeat<0x7953> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7954> *network, Packet_Fixed<0x7954> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7954> *native, NetPacket_Fixed<0x7954> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x7955> *network, Packet_Fixed<0x7955> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x7955> *native, NetPacket_Fixed<0x7955> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +} // namespace tmwa diff --git a/src/proto2/login-admin_test.cpp b/src/proto2/login-admin_test.cpp new file mode 100644 index 0000000..1bc322d --- /dev/null +++ b/src/proto2/login-admin_test.cpp @@ -0,0 +1,27 @@ +#include "login-admin.hpp" +// login-admin_test.cpp - TMWA network protocol: login/admin +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "../poison.hpp" + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/proto2/login-char.hpp b/src/proto2/login-char.hpp new file mode 100644 index 0000000..00fe2ac --- /dev/null +++ b/src/proto2/login-char.hpp @@ -0,0 +1,1192 @@ +#pragma once +// login-char.hpp - TMWA network protocol: login/char +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "fwd.hpp" + +#include "types.hpp" + +namespace tmwa +{ +// This is an internal protocol, and can be changed without notice + +template<> +struct Packet_Fixed<0x2709> +{ + static const uint16_t PACKET_ID = 0x2709; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x2710> +{ + static const uint16_t PACKET_ID = 0x2710; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountName account_name = {}; + AccountPass account_pass = {}; + uint32_t unknown = {}; + IP4Address ip = {}; + uint16_t port = {}; + ServerName server_name = {}; + uint16_t unknown2 = {}; + uint16_t maintenance = {}; + uint16_t is_new = {}; +}; + +template<> +struct Packet_Fixed<0x2711> +{ + static const uint16_t PACKET_ID = 0x2711; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t code = {}; +}; + +template<> +struct Packet_Fixed<0x2712> +{ + static const uint16_t PACKET_ID = 0x2712; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint32_t login_id1 = {}; + uint32_t login_id2 = {}; + SEX sex = {}; + IP4Address ip = {}; +}; + +template<> +struct Packet_Fixed<0x2713> +{ + static const uint16_t PACKET_ID = 0x2713; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint8_t invalid = {}; + AccountEmail email = {}; + TimeT connect_until = {}; +}; + +template<> +struct Packet_Fixed<0x2714> +{ + static const uint16_t PACKET_ID = 0x2714; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint32_t users = {}; +}; + +template<> +struct Packet_Fixed<0x2716> +{ + static const uint16_t PACKET_ID = 0x2716; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x2717> +{ + static const uint16_t PACKET_ID = 0x2717; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountEmail email = {}; + TimeT connect_until = {}; +}; + +template<> +struct Packet_Head<0x2720> +{ + static const uint16_t PACKET_ID = 0x2720; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x2720> +{ + static const uint16_t PACKET_ID = 0x2720; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x2721> +{ + static const uint16_t PACKET_ID = 0x2721; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + GmLevel gm_level = {}; +}; + +template<> +struct Packet_Fixed<0x2722> +{ + static const uint16_t PACKET_ID = 0x2722; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountEmail old_email = {}; + AccountEmail new_email = {}; +}; + +template<> +struct Packet_Fixed<0x2723> +{ + static const uint16_t PACKET_ID = 0x2723; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + SEX sex = {}; +}; + +template<> +struct Packet_Fixed<0x2724> +{ + static const uint16_t PACKET_ID = 0x2724; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint32_t status = {}; +}; + +template<> +struct Packet_Fixed<0x2725> +{ + static const uint16_t PACKET_ID = 0x2725; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + HumanTimeDiff ban_add = {}; +}; + +template<> +struct Packet_Fixed<0x2727> +{ + static const uint16_t PACKET_ID = 0x2727; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Head<0x2728> +{ + static const uint16_t PACKET_ID = 0x2728; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x2728> +{ + static const uint16_t PACKET_ID = 0x2728; + + VarName name = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Head<0x2729> +{ + static const uint16_t PACKET_ID = 0x2729; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x2729> +{ + static const uint16_t PACKET_ID = 0x2729; + + VarName name = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Fixed<0x272a> +{ + static const uint16_t PACKET_ID = 0x272a; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x2730> +{ + static const uint16_t PACKET_ID = 0x2730; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x2731> +{ + static const uint16_t PACKET_ID = 0x2731; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint8_t ban_not_status = {}; + TimeT status_or_ban_until = {}; +}; + +template<> +struct Packet_Head<0x2732> +{ + static const uint16_t PACKET_ID = 0x2732; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x2732> +{ + static const uint16_t PACKET_ID = 0x2732; + + AccountId account_id = {}; + GmLevel gm_level = {}; +}; + +template<> +struct Packet_Fixed<0x2740> +{ + static const uint16_t PACKET_ID = 0x2740; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + AccountPass old_pass = {}; + AccountPass new_pass = {}; +}; + +template<> +struct Packet_Fixed<0x2741> +{ + static const uint16_t PACKET_ID = 0x2741; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint8_t status = {}; +}; + + +template<> +struct NetPacket_Fixed<0x2709> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2709>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2709>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x2709>) == 2, "sizeof(NetPacket_Fixed<0x2709>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x2709>) == 1, "alignof(NetPacket_Fixed<0x2709>) == 1"); + +template<> +struct NetPacket_Fixed<0x2710> +{ + Little16 magic_packet_id; + NetString<sizeof(AccountName)> account_name; + NetString<sizeof(AccountPass)> account_pass; + Little32 unknown; + IP4Address ip; + Little16 port; + NetString<sizeof(ServerName)> server_name; + Little16 unknown2; + Little16 maintenance; + Little16 is_new; +}; +static_assert(offsetof(NetPacket_Fixed<0x2710>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2710>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2710>, account_name) == 2, "offsetof(NetPacket_Fixed<0x2710>, account_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2710>, account_pass) == 26, "offsetof(NetPacket_Fixed<0x2710>, account_pass) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x2710>, unknown) == 50, "offsetof(NetPacket_Fixed<0x2710>, unknown) == 50"); +static_assert(offsetof(NetPacket_Fixed<0x2710>, ip) == 54, "offsetof(NetPacket_Fixed<0x2710>, ip) == 54"); +static_assert(offsetof(NetPacket_Fixed<0x2710>, port) == 58, "offsetof(NetPacket_Fixed<0x2710>, port) == 58"); +static_assert(offsetof(NetPacket_Fixed<0x2710>, server_name) == 60, "offsetof(NetPacket_Fixed<0x2710>, server_name) == 60"); +static_assert(offsetof(NetPacket_Fixed<0x2710>, unknown2) == 80, "offsetof(NetPacket_Fixed<0x2710>, unknown2) == 80"); +static_assert(offsetof(NetPacket_Fixed<0x2710>, maintenance) == 82, "offsetof(NetPacket_Fixed<0x2710>, maintenance) == 82"); +static_assert(offsetof(NetPacket_Fixed<0x2710>, is_new) == 84, "offsetof(NetPacket_Fixed<0x2710>, is_new) == 84"); +static_assert(sizeof(NetPacket_Fixed<0x2710>) == 86, "sizeof(NetPacket_Fixed<0x2710>) == 86"); +static_assert(alignof(NetPacket_Fixed<0x2710>) == 1, "alignof(NetPacket_Fixed<0x2710>) == 1"); + +template<> +struct NetPacket_Fixed<0x2711> +{ + Little16 magic_packet_id; + Byte code; +}; +static_assert(offsetof(NetPacket_Fixed<0x2711>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2711>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2711>, code) == 2, "offsetof(NetPacket_Fixed<0x2711>, code) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2711>) == 3, "sizeof(NetPacket_Fixed<0x2711>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x2711>) == 1, "alignof(NetPacket_Fixed<0x2711>) == 1"); + +template<> +struct NetPacket_Fixed<0x2712> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 login_id1; + Little32 login_id2; + Byte sex; + IP4Address ip; +}; +static_assert(offsetof(NetPacket_Fixed<0x2712>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2712>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2712>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2712>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2712>, login_id1) == 6, "offsetof(NetPacket_Fixed<0x2712>, login_id1) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2712>, login_id2) == 10, "offsetof(NetPacket_Fixed<0x2712>, login_id2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x2712>, sex) == 14, "offsetof(NetPacket_Fixed<0x2712>, sex) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x2712>, ip) == 15, "offsetof(NetPacket_Fixed<0x2712>, ip) == 15"); +static_assert(sizeof(NetPacket_Fixed<0x2712>) == 19, "sizeof(NetPacket_Fixed<0x2712>) == 19"); +static_assert(alignof(NetPacket_Fixed<0x2712>) == 1, "alignof(NetPacket_Fixed<0x2712>) == 1"); + +template<> +struct NetPacket_Fixed<0x2713> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte invalid; + NetString<sizeof(AccountEmail)> email; + Little32 connect_until; +}; +static_assert(offsetof(NetPacket_Fixed<0x2713>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2713>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2713>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2713>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2713>, invalid) == 6, "offsetof(NetPacket_Fixed<0x2713>, invalid) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2713>, email) == 7, "offsetof(NetPacket_Fixed<0x2713>, email) == 7"); +static_assert(offsetof(NetPacket_Fixed<0x2713>, connect_until) == 47, "offsetof(NetPacket_Fixed<0x2713>, connect_until) == 47"); +static_assert(sizeof(NetPacket_Fixed<0x2713>) == 51, "sizeof(NetPacket_Fixed<0x2713>) == 51"); +static_assert(alignof(NetPacket_Fixed<0x2713>) == 1, "alignof(NetPacket_Fixed<0x2713>) == 1"); + +template<> +struct NetPacket_Fixed<0x2714> +{ + Little16 magic_packet_id; + Little32 users; +}; +static_assert(offsetof(NetPacket_Fixed<0x2714>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2714>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2714>, users) == 2, "offsetof(NetPacket_Fixed<0x2714>, users) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2714>) == 6, "sizeof(NetPacket_Fixed<0x2714>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x2714>) == 1, "alignof(NetPacket_Fixed<0x2714>) == 1"); + +template<> +struct NetPacket_Fixed<0x2716> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2716>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2716>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2716>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2716>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2716>) == 6, "sizeof(NetPacket_Fixed<0x2716>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x2716>) == 1, "alignof(NetPacket_Fixed<0x2716>) == 1"); + +template<> +struct NetPacket_Fixed<0x2717> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountEmail)> email; + Little32 connect_until; +}; +static_assert(offsetof(NetPacket_Fixed<0x2717>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2717>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2717>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2717>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2717>, email) == 6, "offsetof(NetPacket_Fixed<0x2717>, email) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2717>, connect_until) == 46, "offsetof(NetPacket_Fixed<0x2717>, connect_until) == 46"); +static_assert(sizeof(NetPacket_Fixed<0x2717>) == 50, "sizeof(NetPacket_Fixed<0x2717>) == 50"); +static_assert(alignof(NetPacket_Fixed<0x2717>) == 1, "alignof(NetPacket_Fixed<0x2717>) == 1"); + +template<> +struct NetPacket_Head<0x2720> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x2720>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2720>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2720>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2720>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2720>, account_id) == 4, "offsetof(NetPacket_Head<0x2720>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x2720>) == 8, "sizeof(NetPacket_Head<0x2720>) == 8"); +static_assert(alignof(NetPacket_Head<0x2720>) == 1, "alignof(NetPacket_Head<0x2720>) == 1"); +template<> +struct NetPacket_Repeat<0x2720> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x2720>, c) == 0, "offsetof(NetPacket_Repeat<0x2720>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x2720>) == 1, "sizeof(NetPacket_Repeat<0x2720>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x2720>) == 1, "alignof(NetPacket_Repeat<0x2720>) == 1"); + +template<> +struct NetPacket_Fixed<0x2721> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 gm_level; +}; +static_assert(offsetof(NetPacket_Fixed<0x2721>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2721>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2721>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2721>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2721>, gm_level) == 6, "offsetof(NetPacket_Fixed<0x2721>, gm_level) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2721>) == 10, "sizeof(NetPacket_Fixed<0x2721>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x2721>) == 1, "alignof(NetPacket_Fixed<0x2721>) == 1"); + +template<> +struct NetPacket_Fixed<0x2722> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountEmail)> old_email; + NetString<sizeof(AccountEmail)> new_email; +}; +static_assert(offsetof(NetPacket_Fixed<0x2722>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2722>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2722>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2722>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2722>, old_email) == 6, "offsetof(NetPacket_Fixed<0x2722>, old_email) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2722>, new_email) == 46, "offsetof(NetPacket_Fixed<0x2722>, new_email) == 46"); +static_assert(sizeof(NetPacket_Fixed<0x2722>) == 86, "sizeof(NetPacket_Fixed<0x2722>) == 86"); +static_assert(alignof(NetPacket_Fixed<0x2722>) == 1, "alignof(NetPacket_Fixed<0x2722>) == 1"); + +template<> +struct NetPacket_Fixed<0x2723> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte sex; +}; +static_assert(offsetof(NetPacket_Fixed<0x2723>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2723>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2723>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2723>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2723>, sex) == 6, "offsetof(NetPacket_Fixed<0x2723>, sex) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2723>) == 7, "sizeof(NetPacket_Fixed<0x2723>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x2723>) == 1, "alignof(NetPacket_Fixed<0x2723>) == 1"); + +template<> +struct NetPacket_Fixed<0x2724> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 status; +}; +static_assert(offsetof(NetPacket_Fixed<0x2724>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2724>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2724>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2724>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2724>, status) == 6, "offsetof(NetPacket_Fixed<0x2724>, status) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2724>) == 10, "sizeof(NetPacket_Fixed<0x2724>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x2724>) == 1, "alignof(NetPacket_Fixed<0x2724>) == 1"); + +template<> +struct NetPacket_Fixed<0x2725> +{ + Little16 magic_packet_id; + Little32 account_id; + NetHumanTimeDiff ban_add; +}; +static_assert(offsetof(NetPacket_Fixed<0x2725>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2725>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2725>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2725>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2725>, ban_add) == 6, "offsetof(NetPacket_Fixed<0x2725>, ban_add) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2725>) == 18, "sizeof(NetPacket_Fixed<0x2725>) == 18"); +static_assert(alignof(NetPacket_Fixed<0x2725>) == 1, "alignof(NetPacket_Fixed<0x2725>) == 1"); + +template<> +struct NetPacket_Fixed<0x2727> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2727>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2727>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2727>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2727>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2727>) == 6, "sizeof(NetPacket_Fixed<0x2727>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x2727>) == 1, "alignof(NetPacket_Fixed<0x2727>) == 1"); + +template<> +struct NetPacket_Head<0x2728> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x2728>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2728>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2728>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2728>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2728>, account_id) == 4, "offsetof(NetPacket_Head<0x2728>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x2728>) == 8, "sizeof(NetPacket_Head<0x2728>) == 8"); +static_assert(alignof(NetPacket_Head<0x2728>) == 1, "alignof(NetPacket_Head<0x2728>) == 1"); +template<> +struct NetPacket_Repeat<0x2728> +{ + NetString<sizeof(VarName)> name; + Little32 value; +}; +static_assert(offsetof(NetPacket_Repeat<0x2728>, name) == 0, "offsetof(NetPacket_Repeat<0x2728>, name) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x2728>, value) == 32, "offsetof(NetPacket_Repeat<0x2728>, value) == 32"); +static_assert(sizeof(NetPacket_Repeat<0x2728>) == 36, "sizeof(NetPacket_Repeat<0x2728>) == 36"); +static_assert(alignof(NetPacket_Repeat<0x2728>) == 1, "alignof(NetPacket_Repeat<0x2728>) == 1"); + +template<> +struct NetPacket_Head<0x2729> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x2729>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2729>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2729>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2729>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x2729>, account_id) == 4, "offsetof(NetPacket_Head<0x2729>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x2729>) == 8, "sizeof(NetPacket_Head<0x2729>) == 8"); +static_assert(alignof(NetPacket_Head<0x2729>) == 1, "alignof(NetPacket_Head<0x2729>) == 1"); +template<> +struct NetPacket_Repeat<0x2729> +{ + NetString<sizeof(VarName)> name; + Little32 value; +}; +static_assert(offsetof(NetPacket_Repeat<0x2729>, name) == 0, "offsetof(NetPacket_Repeat<0x2729>, name) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x2729>, value) == 32, "offsetof(NetPacket_Repeat<0x2729>, value) == 32"); +static_assert(sizeof(NetPacket_Repeat<0x2729>) == 36, "sizeof(NetPacket_Repeat<0x2729>) == 36"); +static_assert(alignof(NetPacket_Repeat<0x2729>) == 1, "alignof(NetPacket_Repeat<0x2729>) == 1"); + +template<> +struct NetPacket_Fixed<0x272a> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x272a>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x272a>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x272a>, account_id) == 2, "offsetof(NetPacket_Fixed<0x272a>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x272a>) == 6, "sizeof(NetPacket_Fixed<0x272a>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x272a>) == 1, "alignof(NetPacket_Fixed<0x272a>) == 1"); + +template<> +struct NetPacket_Fixed<0x2730> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x2730>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2730>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2730>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2730>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x2730>) == 6, "sizeof(NetPacket_Fixed<0x2730>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x2730>) == 1, "alignof(NetPacket_Fixed<0x2730>) == 1"); + +template<> +struct NetPacket_Fixed<0x2731> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte ban_not_status; + Little32 status_or_ban_until; +}; +static_assert(offsetof(NetPacket_Fixed<0x2731>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2731>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2731>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2731>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2731>, ban_not_status) == 6, "offsetof(NetPacket_Fixed<0x2731>, ban_not_status) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2731>, status_or_ban_until) == 7, "offsetof(NetPacket_Fixed<0x2731>, status_or_ban_until) == 7"); +static_assert(sizeof(NetPacket_Fixed<0x2731>) == 11, "sizeof(NetPacket_Fixed<0x2731>) == 11"); +static_assert(alignof(NetPacket_Fixed<0x2731>) == 1, "alignof(NetPacket_Fixed<0x2731>) == 1"); + +template<> +struct NetPacket_Head<0x2732> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x2732>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x2732>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x2732>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x2732>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x2732>) == 4, "sizeof(NetPacket_Head<0x2732>) == 4"); +static_assert(alignof(NetPacket_Head<0x2732>) == 1, "alignof(NetPacket_Head<0x2732>) == 1"); +template<> +struct NetPacket_Repeat<0x2732> +{ + Little32 account_id; + Byte gm_level; +}; +static_assert(offsetof(NetPacket_Repeat<0x2732>, account_id) == 0, "offsetof(NetPacket_Repeat<0x2732>, account_id) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x2732>, gm_level) == 4, "offsetof(NetPacket_Repeat<0x2732>, gm_level) == 4"); +static_assert(sizeof(NetPacket_Repeat<0x2732>) == 5, "sizeof(NetPacket_Repeat<0x2732>) == 5"); +static_assert(alignof(NetPacket_Repeat<0x2732>) == 1, "alignof(NetPacket_Repeat<0x2732>) == 1"); + +template<> +struct NetPacket_Fixed<0x2740> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(AccountPass)> old_pass; + NetString<sizeof(AccountPass)> new_pass; +}; +static_assert(offsetof(NetPacket_Fixed<0x2740>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2740>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2740>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2740>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2740>, old_pass) == 6, "offsetof(NetPacket_Fixed<0x2740>, old_pass) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x2740>, new_pass) == 30, "offsetof(NetPacket_Fixed<0x2740>, new_pass) == 30"); +static_assert(sizeof(NetPacket_Fixed<0x2740>) == 54, "sizeof(NetPacket_Fixed<0x2740>) == 54"); +static_assert(alignof(NetPacket_Fixed<0x2740>) == 1, "alignof(NetPacket_Fixed<0x2740>) == 1"); + +template<> +struct NetPacket_Fixed<0x2741> +{ + Little16 magic_packet_id; + Little32 account_id; + Byte status; +}; +static_assert(offsetof(NetPacket_Fixed<0x2741>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x2741>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x2741>, account_id) == 2, "offsetof(NetPacket_Fixed<0x2741>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x2741>, status) == 6, "offsetof(NetPacket_Fixed<0x2741>, status) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x2741>) == 7, "sizeof(NetPacket_Fixed<0x2741>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x2741>) == 1, "alignof(NetPacket_Fixed<0x2741>) == 1"); + + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2709> *network, Packet_Fixed<0x2709> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2709> *native, NetPacket_Fixed<0x2709> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2710> *network, Packet_Fixed<0x2710> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->account_pass, native.account_pass); + rv &= native_to_network(&network->unknown, native.unknown); + rv &= native_to_network(&network->ip, native.ip); + rv &= native_to_network(&network->port, native.port); + rv &= native_to_network(&network->server_name, native.server_name); + rv &= native_to_network(&network->unknown2, native.unknown2); + rv &= native_to_network(&network->maintenance, native.maintenance); + rv &= native_to_network(&network->is_new, native.is_new); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2710> *native, NetPacket_Fixed<0x2710> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->account_pass, network.account_pass); + rv &= network_to_native(&native->unknown, network.unknown); + rv &= network_to_native(&native->ip, network.ip); + rv &= network_to_native(&native->port, network.port); + rv &= network_to_native(&native->server_name, network.server_name); + rv &= network_to_native(&native->unknown2, network.unknown2); + rv &= network_to_native(&native->maintenance, network.maintenance); + rv &= network_to_native(&native->is_new, network.is_new); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2711> *network, Packet_Fixed<0x2711> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->code, native.code); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2711> *native, NetPacket_Fixed<0x2711> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->code, network.code); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2712> *network, Packet_Fixed<0x2712> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->login_id1, native.login_id1); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->sex, native.sex); + rv &= native_to_network(&network->ip, native.ip); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2712> *native, NetPacket_Fixed<0x2712> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->login_id1, network.login_id1); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->sex, network.sex); + rv &= network_to_native(&native->ip, network.ip); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2713> *network, Packet_Fixed<0x2713> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->invalid, native.invalid); + rv &= native_to_network(&network->email, native.email); + rv &= native_to_network(&network->connect_until, native.connect_until); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2713> *native, NetPacket_Fixed<0x2713> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->invalid, network.invalid); + rv &= network_to_native(&native->email, network.email); + rv &= network_to_native(&native->connect_until, network.connect_until); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2714> *network, Packet_Fixed<0x2714> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->users, native.users); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2714> *native, NetPacket_Fixed<0x2714> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->users, network.users); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2716> *network, Packet_Fixed<0x2716> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2716> *native, NetPacket_Fixed<0x2716> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2717> *network, Packet_Fixed<0x2717> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->email, native.email); + rv &= native_to_network(&network->connect_until, native.connect_until); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2717> *native, NetPacket_Fixed<0x2717> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->email, network.email); + rv &= network_to_native(&native->connect_until, network.connect_until); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2720> *network, Packet_Head<0x2720> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2720> *native, NetPacket_Head<0x2720> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2720> *network, Packet_Repeat<0x2720> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2720> *native, NetPacket_Repeat<0x2720> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2721> *network, Packet_Fixed<0x2721> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->gm_level, native.gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2721> *native, NetPacket_Fixed<0x2721> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->gm_level, network.gm_level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2722> *network, Packet_Fixed<0x2722> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->old_email, native.old_email); + rv &= native_to_network(&network->new_email, native.new_email); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2722> *native, NetPacket_Fixed<0x2722> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->old_email, network.old_email); + rv &= network_to_native(&native->new_email, network.new_email); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2723> *network, Packet_Fixed<0x2723> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->sex, native.sex); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2723> *native, NetPacket_Fixed<0x2723> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->sex, network.sex); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2724> *network, Packet_Fixed<0x2724> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->status, native.status); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2724> *native, NetPacket_Fixed<0x2724> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->status, network.status); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2725> *network, Packet_Fixed<0x2725> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->ban_add, native.ban_add); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2725> *native, NetPacket_Fixed<0x2725> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->ban_add, network.ban_add); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2727> *network, Packet_Fixed<0x2727> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2727> *native, NetPacket_Fixed<0x2727> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2728> *network, Packet_Head<0x2728> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2728> *native, NetPacket_Head<0x2728> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2728> *network, Packet_Repeat<0x2728> native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2728> *native, NetPacket_Repeat<0x2728> network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2729> *network, Packet_Head<0x2729> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2729> *native, NetPacket_Head<0x2729> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2729> *network, Packet_Repeat<0x2729> native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2729> *native, NetPacket_Repeat<0x2729> network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x272a> *network, Packet_Fixed<0x272a> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x272a> *native, NetPacket_Fixed<0x272a> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2730> *network, Packet_Fixed<0x2730> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2730> *native, NetPacket_Fixed<0x2730> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2731> *network, Packet_Fixed<0x2731> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->ban_not_status, native.ban_not_status); + rv &= native_to_network(&network->status_or_ban_until, native.status_or_ban_until); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2731> *native, NetPacket_Fixed<0x2731> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->ban_not_status, network.ban_not_status); + rv &= network_to_native(&native->status_or_ban_until, network.status_or_ban_until); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x2732> *network, Packet_Head<0x2732> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x2732> *native, NetPacket_Head<0x2732> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x2732> *network, Packet_Repeat<0x2732> native) +{ + bool rv = true; + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->gm_level, native.gm_level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x2732> *native, NetPacket_Repeat<0x2732> network) +{ + bool rv = true; + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->gm_level, network.gm_level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2740> *network, Packet_Fixed<0x2740> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->old_pass, native.old_pass); + rv &= native_to_network(&network->new_pass, native.new_pass); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2740> *native, NetPacket_Fixed<0x2740> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->old_pass, network.old_pass); + rv &= network_to_native(&native->new_pass, network.new_pass); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x2741> *network, Packet_Fixed<0x2741> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->status, native.status); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x2741> *native, NetPacket_Fixed<0x2741> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->status, network.status); + return rv; +} + +} // namespace tmwa diff --git a/src/proto2/login-char_test.cpp b/src/proto2/login-char_test.cpp new file mode 100644 index 0000000..0b61645 --- /dev/null +++ b/src/proto2/login-char_test.cpp @@ -0,0 +1,27 @@ +#include "login-char.hpp" +// login-char_test.cpp - TMWA network protocol: login/char +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "../poison.hpp" + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/proto2/login-user.hpp b/src/proto2/login-user.hpp new file mode 100644 index 0000000..fb6fcc7 --- /dev/null +++ b/src/proto2/login-user.hpp @@ -0,0 +1,325 @@ +#pragma once +// login-user.hpp - TMWA network protocol: login/user +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "fwd.hpp" + +#include "types.hpp" + +namespace tmwa +{ +// This is a public protocol, and changes require client cooperation + +template<> +struct Packet_Head<0x0063> +{ + static const uint16_t PACKET_ID = 0x0063; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x0063> +{ + static const uint16_t PACKET_ID = 0x0063; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x0064> +{ + static const uint16_t PACKET_ID = 0x0064; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint32_t unknown = {}; + AccountName account_name = {}; + AccountPass account_pass = {}; + VERSION_2 version_2_flags = {}; +}; + +template<> +struct Packet_Head<0x0069> +{ + static const uint16_t PACKET_ID = 0x0069; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + uint32_t login_id1 = {}; + AccountId account_id = {}; + uint32_t login_id2 = {}; + uint32_t unused = {}; + timestamp_milliseconds_buffer last_login_string = {}; + uint16_t unused2 = {}; + SEX sex = {}; +}; +template<> +struct Packet_Repeat<0x0069> +{ + static const uint16_t PACKET_ID = 0x0069; + + IP4Address ip = {}; + uint16_t port = {}; + ServerName server_name = {}; + uint16_t users = {}; + uint16_t maintenance = {}; + uint16_t is_new = {}; +}; + +template<> +struct Packet_Fixed<0x006a> +{ + static const uint16_t PACKET_ID = 0x006a; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t error_code = {}; + timestamp_seconds_buffer error_message = {}; +}; + + +template<> +struct NetPacket_Head<0x0063> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x0063>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x0063>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x0063>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x0063>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x0063>) == 4, "sizeof(NetPacket_Head<0x0063>) == 4"); +static_assert(alignof(NetPacket_Head<0x0063>) == 1, "alignof(NetPacket_Head<0x0063>) == 1"); +template<> +struct NetPacket_Repeat<0x0063> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x0063>, c) == 0, "offsetof(NetPacket_Repeat<0x0063>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x0063>) == 1, "sizeof(NetPacket_Repeat<0x0063>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x0063>) == 1, "alignof(NetPacket_Repeat<0x0063>) == 1"); + +template<> +struct NetPacket_Fixed<0x0064> +{ + Little16 magic_packet_id; + Little32 unknown; + NetString<sizeof(AccountName)> account_name; + NetString<sizeof(AccountPass)> account_pass; + Byte version_2_flags; +}; +static_assert(offsetof(NetPacket_Fixed<0x0064>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0064>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0064>, unknown) == 2, "offsetof(NetPacket_Fixed<0x0064>, unknown) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0064>, account_name) == 6, "offsetof(NetPacket_Fixed<0x0064>, account_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0064>, account_pass) == 30, "offsetof(NetPacket_Fixed<0x0064>, account_pass) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x0064>, version_2_flags) == 54, "offsetof(NetPacket_Fixed<0x0064>, version_2_flags) == 54"); +static_assert(sizeof(NetPacket_Fixed<0x0064>) == 55, "sizeof(NetPacket_Fixed<0x0064>) == 55"); +static_assert(alignof(NetPacket_Fixed<0x0064>) == 1, "alignof(NetPacket_Fixed<0x0064>) == 1"); + +template<> +struct NetPacket_Head<0x0069> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 login_id1; + Little32 account_id; + Little32 login_id2; + Little32 unused; + NetString<sizeof(timestamp_milliseconds_buffer)> last_login_string; + Little16 unused2; + Byte sex; +}; +static_assert(offsetof(NetPacket_Head<0x0069>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x0069>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x0069>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x0069>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x0069>, login_id1) == 4, "offsetof(NetPacket_Head<0x0069>, login_id1) == 4"); +static_assert(offsetof(NetPacket_Head<0x0069>, account_id) == 8, "offsetof(NetPacket_Head<0x0069>, account_id) == 8"); +static_assert(offsetof(NetPacket_Head<0x0069>, login_id2) == 12, "offsetof(NetPacket_Head<0x0069>, login_id2) == 12"); +static_assert(offsetof(NetPacket_Head<0x0069>, unused) == 16, "offsetof(NetPacket_Head<0x0069>, unused) == 16"); +static_assert(offsetof(NetPacket_Head<0x0069>, last_login_string) == 20, "offsetof(NetPacket_Head<0x0069>, last_login_string) == 20"); +static_assert(offsetof(NetPacket_Head<0x0069>, unused2) == 44, "offsetof(NetPacket_Head<0x0069>, unused2) == 44"); +static_assert(offsetof(NetPacket_Head<0x0069>, sex) == 46, "offsetof(NetPacket_Head<0x0069>, sex) == 46"); +static_assert(sizeof(NetPacket_Head<0x0069>) == 47, "sizeof(NetPacket_Head<0x0069>) == 47"); +static_assert(alignof(NetPacket_Head<0x0069>) == 1, "alignof(NetPacket_Head<0x0069>) == 1"); +template<> +struct NetPacket_Repeat<0x0069> +{ + IP4Address ip; + Little16 port; + NetString<sizeof(ServerName)> server_name; + Little16 users; + Little16 maintenance; + Little16 is_new; +}; +static_assert(offsetof(NetPacket_Repeat<0x0069>, ip) == 0, "offsetof(NetPacket_Repeat<0x0069>, ip) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x0069>, port) == 4, "offsetof(NetPacket_Repeat<0x0069>, port) == 4"); +static_assert(offsetof(NetPacket_Repeat<0x0069>, server_name) == 6, "offsetof(NetPacket_Repeat<0x0069>, server_name) == 6"); +static_assert(offsetof(NetPacket_Repeat<0x0069>, users) == 26, "offsetof(NetPacket_Repeat<0x0069>, users) == 26"); +static_assert(offsetof(NetPacket_Repeat<0x0069>, maintenance) == 28, "offsetof(NetPacket_Repeat<0x0069>, maintenance) == 28"); +static_assert(offsetof(NetPacket_Repeat<0x0069>, is_new) == 30, "offsetof(NetPacket_Repeat<0x0069>, is_new) == 30"); +static_assert(sizeof(NetPacket_Repeat<0x0069>) == 32, "sizeof(NetPacket_Repeat<0x0069>) == 32"); +static_assert(alignof(NetPacket_Repeat<0x0069>) == 1, "alignof(NetPacket_Repeat<0x0069>) == 1"); + +template<> +struct NetPacket_Fixed<0x006a> +{ + Little16 magic_packet_id; + Byte error_code; + NetString<sizeof(timestamp_seconds_buffer)> error_message; +}; +static_assert(offsetof(NetPacket_Fixed<0x006a>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x006a>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x006a>, error_code) == 2, "offsetof(NetPacket_Fixed<0x006a>, error_code) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x006a>, error_message) == 3, "offsetof(NetPacket_Fixed<0x006a>, error_message) == 3"); +static_assert(sizeof(NetPacket_Fixed<0x006a>) == 23, "sizeof(NetPacket_Fixed<0x006a>) == 23"); +static_assert(alignof(NetPacket_Fixed<0x006a>) == 1, "alignof(NetPacket_Fixed<0x006a>) == 1"); + + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x0063> *network, Packet_Head<0x0063> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x0063> *native, NetPacket_Head<0x0063> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x0063> *network, Packet_Repeat<0x0063> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x0063> *native, NetPacket_Repeat<0x0063> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0064> *network, Packet_Fixed<0x0064> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->unknown, native.unknown); + rv &= native_to_network(&network->account_name, native.account_name); + rv &= native_to_network(&network->account_pass, native.account_pass); + rv &= native_to_network(&network->version_2_flags, native.version_2_flags); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0064> *native, NetPacket_Fixed<0x0064> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->unknown, network.unknown); + rv &= network_to_native(&native->account_name, network.account_name); + rv &= network_to_native(&native->account_pass, network.account_pass); + rv &= network_to_native(&native->version_2_flags, network.version_2_flags); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x0069> *network, Packet_Head<0x0069> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->login_id1, native.login_id1); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->login_id2, native.login_id2); + rv &= native_to_network(&network->unused, native.unused); + rv &= native_to_network(&network->last_login_string, native.last_login_string); + rv &= native_to_network(&network->unused2, native.unused2); + rv &= native_to_network(&network->sex, native.sex); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x0069> *native, NetPacket_Head<0x0069> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->login_id1, network.login_id1); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->login_id2, network.login_id2); + rv &= network_to_native(&native->unused, network.unused); + rv &= network_to_native(&native->last_login_string, network.last_login_string); + rv &= network_to_native(&native->unused2, network.unused2); + rv &= network_to_native(&native->sex, network.sex); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x0069> *network, Packet_Repeat<0x0069> native) +{ + bool rv = true; + rv &= native_to_network(&network->ip, native.ip); + rv &= native_to_network(&network->port, native.port); + rv &= native_to_network(&network->server_name, native.server_name); + rv &= native_to_network(&network->users, native.users); + rv &= native_to_network(&network->maintenance, native.maintenance); + rv &= native_to_network(&network->is_new, native.is_new); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x0069> *native, NetPacket_Repeat<0x0069> network) +{ + bool rv = true; + rv &= network_to_native(&native->ip, network.ip); + rv &= network_to_native(&native->port, network.port); + rv &= network_to_native(&native->server_name, network.server_name); + rv &= network_to_native(&native->users, network.users); + rv &= network_to_native(&native->maintenance, network.maintenance); + rv &= network_to_native(&native->is_new, network.is_new); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x006a> *network, Packet_Fixed<0x006a> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->error_code, native.error_code); + rv &= native_to_network(&network->error_message, native.error_message); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x006a> *native, NetPacket_Fixed<0x006a> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->error_code, network.error_code); + rv &= network_to_native(&native->error_message, network.error_message); + return rv; +} + +} // namespace tmwa diff --git a/src/proto2/login-user_test.cpp b/src/proto2/login-user_test.cpp new file mode 100644 index 0000000..fa2128a --- /dev/null +++ b/src/proto2/login-user_test.cpp @@ -0,0 +1,27 @@ +#include "login-user.hpp" +// login-user_test.cpp - TMWA network protocol: login/user +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "../poison.hpp" + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/proto2/map-user.hpp b/src/proto2/map-user.hpp new file mode 100644 index 0000000..630c4f2 --- /dev/null +++ b/src/proto2/map-user.hpp @@ -0,0 +1,7931 @@ +#pragma once +// map-user.hpp - TMWA network protocol: map/user +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "fwd.hpp" + +#include "types.hpp" + +namespace tmwa +{ +// This is a public protocol, and changes require client cooperation + +template<> +struct Packet_Fixed<0x0072> +{ + static const uint16_t PACKET_ID = 0x0072; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + CharId char_id = {}; + uint32_t login_id1 = {}; + uint32_t client_tick = {}; + SEX sex = {}; +}; + +template<> +struct Packet_Fixed<0x0073> +{ + static const uint16_t PACKET_ID = 0x0073; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + tick_t tick = {}; + Position1 pos = {}; + uint8_t five1 = {}; + uint8_t five2 = {}; +}; + +template<> +struct Packet_Fixed<0x0078> +{ + static const uint16_t PACKET_ID = 0x0078; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + interval_t speed = {}; + Opt1 opt1 = {}; + Opt2 opt2 = {}; + Option option = {}; + Species species = {}; + uint16_t unused_hair_style = {}; + uint16_t unused_weapon = {}; + uint16_t unused_head_bottom_or_species_again = {}; + uint16_t unused_shield_or_part_of_guild_emblem = {}; + uint16_t unused_head_top_or_unused_part_of_guild_emblem = {}; + uint16_t unused_head_mid_or_part_of_guild_id = {}; + uint16_t unused_hair_color_or_part_of_guild_id = {}; + uint16_t unused_clothes_color = {}; + uint16_t unused_1 = {}; + uint16_t unused_2 = {}; + Position1 unused_pos_again = {}; + uint8_t unused_4b = {}; + uint16_t unused_5 = {}; + uint16_t unused_zero_1 = {}; + uint8_t unused_zero_2 = {}; + uint8_t unused_sex = {}; + Position1 pos = {}; + uint8_t five1 = {}; + uint8_t five2 = {}; + uint8_t zero = {}; + uint16_t level = {}; +}; + +template<> +struct Packet_Fixed<0x007b> +{ + static const uint16_t PACKET_ID = 0x007b; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + interval_t speed = {}; + Opt1 opt1 = {}; + Opt2 opt2 = {}; + Option option = {}; + Species mob_class = {}; + uint16_t unused_hair_style = {}; + uint16_t unused_weapon = {}; + uint16_t unused_head_bottom = {}; + tick_t tick_and_maybe_part_of_guild_emblem = {}; + uint16_t unused_shield_or_maybe_part_of_guild_emblem = {}; + uint16_t unused_head_top_or_maybe_part_of_guild_id = {}; + uint16_t unused_head_mid_or_maybe_part_of_guild_id = {}; + uint16_t unused_hair_color = {}; + uint16_t unused_clothes_color = {}; + uint16_t unused_1 = {}; + uint16_t unused_2 = {}; + uint16_t unused_3 = {}; + uint16_t unused_4 = {}; + uint16_t unused_5 = {}; + uint16_t unused_zero_1 = {}; + uint8_t unused_zero_2 = {}; + uint8_t unused_sex = {}; + Position2 pos2 = {}; + uint8_t zero = {}; + uint8_t five1 = {}; + uint8_t five2 = {}; + uint16_t level = {}; +}; + +template<> +struct Packet_Fixed<0x007c> +{ + static const uint16_t PACKET_ID = 0x007c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + interval_t speed = {}; + Opt1 opt1 = {}; + Opt2 opt2 = {}; + Option option = {}; + uint16_t unknown_1 = {}; + uint16_t unknown_2 = {}; + uint16_t unknown_3 = {}; + Species species = {}; + uint16_t unknown_4 = {}; + uint16_t unknown_5 = {}; + uint16_t unknown_6 = {}; + uint16_t unknown_7 = {}; + uint16_t unknown_8 = {}; + uint16_t unknown_9 = {}; + uint16_t unknown_10 = {}; + Position1 pos = {}; + uint16_t unknown_11 = {}; +}; + +template<> +struct Packet_Fixed<0x007d> +{ + static const uint16_t PACKET_ID = 0x007d; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x007e> +{ + static const uint16_t PACKET_ID = 0x007e; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint32_t client_tick = {}; +}; + +template<> +struct Packet_Fixed<0x007f> +{ + static const uint16_t PACKET_ID = 0x007f; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + tick_t tick = {}; +}; + +template<> +struct Packet_Fixed<0x0080> +{ + static const uint16_t PACKET_ID = 0x0080; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + BeingRemoveWhy type = {}; +}; + +template<> +struct Packet_Fixed<0x0085> +{ + static const uint16_t PACKET_ID = 0x0085; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + Position1 pos = {}; +}; + +template<> +struct Packet_Fixed<0x0087> +{ + static const uint16_t PACKET_ID = 0x0087; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + tick_t tick = {}; + Position2 pos2 = {}; + uint8_t zero = {}; +}; + +template<> +struct Packet_Fixed<0x0088> +{ + static const uint16_t PACKET_ID = 0x0088; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + uint16_t x = {}; + uint16_t y = {}; +}; + +template<> +struct Packet_Fixed<0x0089> +{ + static const uint16_t PACKET_ID = 0x0089; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId target_id = {}; + DamageType action = {}; +}; + +template<> +struct Packet_Fixed<0x008a> +{ + static const uint16_t PACKET_ID = 0x008a; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId src_id = {}; + BlockId dst_id = {}; + tick_t tick = {}; + interval_t sdelay = {}; + interval_t ddelay = {}; + uint16_t damage = {}; + uint16_t div = {}; + DamageType damage_type = {}; + uint16_t damage2 = {}; +}; + +template<> +struct Packet_Head<0x008c> +{ + static const uint16_t PACKET_ID = 0x008c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x008c> +{ + static const uint16_t PACKET_ID = 0x008c; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x008d> +{ + static const uint16_t PACKET_ID = 0x008d; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + BlockId block_id = {}; +}; +template<> +struct Packet_Repeat<0x008d> +{ + static const uint16_t PACKET_ID = 0x008d; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x008e> +{ + static const uint16_t PACKET_ID = 0x008e; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x008e> +{ + static const uint16_t PACKET_ID = 0x008e; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x0090> +{ + static const uint16_t PACKET_ID = 0x0090; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + uint8_t unused = {}; +}; + +template<> +struct Packet_Fixed<0x0091> +{ + static const uint16_t PACKET_ID = 0x0091; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + MapName map_name = {}; + uint16_t x = {}; + uint16_t y = {}; +}; + +template<> +struct Packet_Fixed<0x0092> +{ + static const uint16_t PACKET_ID = 0x0092; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + MapName map_name = {}; + uint16_t x = {}; + uint16_t y = {}; + IP4Address ip = {}; + uint16_t port = {}; +}; + +template<> +struct Packet_Fixed<0x0094> +{ + static const uint16_t PACKET_ID = 0x0094; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; +}; + +template<> +struct Packet_Fixed<0x0095> +{ + static const uint16_t PACKET_ID = 0x0095; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + CharName char_name = {}; +}; + +template<> +struct Packet_Head<0x0096> +{ + static const uint16_t PACKET_ID = 0x0096; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + CharName target_name = {}; +}; +template<> +struct Packet_Repeat<0x0096> +{ + static const uint16_t PACKET_ID = 0x0096; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x0097> +{ + static const uint16_t PACKET_ID = 0x0097; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + CharName char_name = {}; +}; +template<> +struct Packet_Repeat<0x0097> +{ + static const uint16_t PACKET_ID = 0x0097; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x0098> +{ + static const uint16_t PACKET_ID = 0x0098; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t flag = {}; +}; + +template<> +struct Packet_Head<0x009a> +{ + static const uint16_t PACKET_ID = 0x009a; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x009a> +{ + static const uint16_t PACKET_ID = 0x009a; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x009b> +{ + static const uint16_t PACKET_ID = 0x009b; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t unused = {}; + uint8_t client_dir = {}; +}; + +template<> +struct Packet_Fixed<0x009c> +{ + static const uint16_t PACKET_ID = 0x009c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + uint16_t zero = {}; + uint8_t client_dir = {}; +}; + +template<> +struct Packet_Fixed<0x009d> +{ + static const uint16_t PACKET_ID = 0x009d; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + ItemNameId name_id = {}; + uint8_t identify = {}; + uint16_t x = {}; + uint16_t y = {}; + uint16_t amount = {}; + uint8_t subx = {}; + uint8_t suby = {}; +}; + +template<> +struct Packet_Fixed<0x009e> +{ + static const uint16_t PACKET_ID = 0x009e; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + ItemNameId name_id = {}; + uint8_t identify = {}; + uint16_t x = {}; + uint16_t y = {}; + uint8_t subx = {}; + uint8_t suby = {}; + uint16_t amount = {}; +}; + +template<> +struct Packet_Fixed<0x009f> +{ + static const uint16_t PACKET_ID = 0x009f; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId object_id = {}; +}; + +template<> +struct Packet_Fixed<0x00a0> +{ + static const uint16_t PACKET_ID = 0x00a0; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; + uint16_t amount = {}; + ItemNameId name_id = {}; + uint8_t identify = {}; + uint8_t broken_or_attribute = {}; + uint8_t refine = {}; + uint16_t card0 = {}; + uint16_t card1 = {}; + uint16_t card2 = {}; + uint16_t card3 = {}; + EPOS epos = {}; + ItemType item_type = {}; + PickupFail pickup_fail = {}; +}; + +template<> +struct Packet_Fixed<0x00a1> +{ + static const uint16_t PACKET_ID = 0x00a1; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; +}; + +template<> +struct Packet_Fixed<0x00a2> +{ + static const uint16_t PACKET_ID = 0x00a2; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; + uint16_t amount = {}; +}; + +template<> +struct Packet_Head<0x00a4> +{ + static const uint16_t PACKET_ID = 0x00a4; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x00a4> +{ + static const uint16_t PACKET_ID = 0x00a4; + + IOff2 ioff2 = {}; + ItemNameId name_id = {}; + ItemType item_type = {}; + uint8_t identify = {}; + EPOS epos_pc = {}; + EPOS epos_inv = {}; + uint8_t broken_or_attribute = {}; + uint8_t refine = {}; + uint16_t card0 = {}; + uint16_t card1 = {}; + uint16_t card2 = {}; + uint16_t card3 = {}; +}; + +template<> +struct Packet_Head<0x00a6> +{ + static const uint16_t PACKET_ID = 0x00a6; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x00a6> +{ + static const uint16_t PACKET_ID = 0x00a6; + + SOff1 soff1 = {}; + ItemNameId name_id = {}; + ItemType item_type = {}; + uint8_t identify = {}; + EPOS epos_id = {}; + EPOS epos_stor = {}; + uint8_t broken_or_attribute = {}; + uint8_t refine = {}; + uint16_t card0 = {}; + uint16_t card1 = {}; + uint16_t card2 = {}; + uint16_t card3 = {}; +}; + +template<> +struct Packet_Fixed<0x00a7> +{ + static const uint16_t PACKET_ID = 0x00a7; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; + uint32_t unused_id = {}; +}; + +template<> +struct Packet_Fixed<0x00a8> +{ + static const uint16_t PACKET_ID = 0x00a8; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; + uint16_t amount = {}; + uint8_t ok = {}; +}; + +template<> +struct Packet_Fixed<0x00a9> +{ + static const uint16_t PACKET_ID = 0x00a9; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; + EPOS epos_ignored = {}; +}; + +template<> +struct Packet_Fixed<0x00aa> +{ + static const uint16_t PACKET_ID = 0x00aa; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; + EPOS epos = {}; + uint8_t ok = {}; +}; + +template<> +struct Packet_Fixed<0x00ab> +{ + static const uint16_t PACKET_ID = 0x00ab; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; +}; + +template<> +struct Packet_Fixed<0x00ac> +{ + static const uint16_t PACKET_ID = 0x00ac; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; + EPOS epos = {}; + uint8_t ok = {}; +}; + +template<> +struct Packet_Fixed<0x00af> +{ + static const uint16_t PACKET_ID = 0x00af; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; + uint16_t amount = {}; +}; + +template<> +struct Packet_Fixed<0x00b0> +{ + static const uint16_t PACKET_ID = 0x00b0; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SP sp_type = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Fixed<0x00b1> +{ + static const uint16_t PACKET_ID = 0x00b1; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SP sp_type = {}; + uint32_t value = {}; +}; + +template<> +struct Packet_Fixed<0x00b2> +{ + static const uint16_t PACKET_ID = 0x00b2; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t flag = {}; +}; + +template<> +struct Packet_Fixed<0x00b3> +{ + static const uint16_t PACKET_ID = 0x00b3; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t one = {}; +}; + +template<> +struct Packet_Head<0x00b4> +{ + static const uint16_t PACKET_ID = 0x00b4; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + BlockId block_id = {}; +}; +template<> +struct Packet_Repeat<0x00b4> +{ + static const uint16_t PACKET_ID = 0x00b4; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x00b5> +{ + static const uint16_t PACKET_ID = 0x00b5; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; +}; + +template<> +struct Packet_Fixed<0x00b6> +{ + static const uint16_t PACKET_ID = 0x00b6; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; +}; + +template<> +struct Packet_Head<0x00b7> +{ + static const uint16_t PACKET_ID = 0x00b7; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + BlockId block_id = {}; +}; +template<> +struct Packet_Repeat<0x00b7> +{ + static const uint16_t PACKET_ID = 0x00b7; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x00b8> +{ + static const uint16_t PACKET_ID = 0x00b8; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId npc_id = {}; + uint8_t menu_entry = {}; +}; + +template<> +struct Packet_Fixed<0x00b9> +{ + static const uint16_t PACKET_ID = 0x00b9; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId npc_id = {}; +}; + +template<> +struct Packet_Fixed<0x00bb> +{ + static const uint16_t PACKET_ID = 0x00bb; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SP asp = {}; + uint8_t unused = {}; +}; + +template<> +struct Packet_Fixed<0x00bc> +{ + static const uint16_t PACKET_ID = 0x00bc; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SP sp_type = {}; + uint8_t ok = {}; + uint8_t val = {}; +}; + +template<> +struct Packet_Fixed<0x00bd> +{ + static const uint16_t PACKET_ID = 0x00bd; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t status_point = {}; + uint8_t str_attr = {}; + uint8_t str_upd = {}; + uint8_t agi_attr = {}; + uint8_t agi_upd = {}; + uint8_t vit_attr = {}; + uint8_t vit_upd = {}; + uint8_t int_attr = {}; + uint8_t int_upd = {}; + uint8_t dex_attr = {}; + uint8_t dex_upd = {}; + uint8_t luk_attr = {}; + uint8_t luk_upd = {}; + uint16_t atk_sum = {}; + uint16_t watk2 = {}; + uint16_t matk1 = {}; + uint16_t matk2 = {}; + uint16_t def = {}; + uint16_t def2 = {}; + uint16_t mdef = {}; + uint16_t mdef2 = {}; + uint16_t hit = {}; + uint16_t flee = {}; + uint16_t flee2 = {}; + uint16_t critical = {}; + uint16_t karma = {}; + uint16_t manner = {}; +}; + +template<> +struct Packet_Fixed<0x00be> +{ + static const uint16_t PACKET_ID = 0x00be; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SP sp_type = {}; + uint8_t value = {}; +}; + +template<> +struct Packet_Fixed<0x00bf> +{ + static const uint16_t PACKET_ID = 0x00bf; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t emote = {}; +}; + +template<> +struct Packet_Fixed<0x00c0> +{ + static const uint16_t PACKET_ID = 0x00c0; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + uint8_t type = {}; +}; + +template<> +struct Packet_Fixed<0x00c1> +{ + static const uint16_t PACKET_ID = 0x00c1; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x00c2> +{ + static const uint16_t PACKET_ID = 0x00c2; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint32_t users = {}; +}; + +template<> +struct Packet_Fixed<0x00c4> +{ + static const uint16_t PACKET_ID = 0x00c4; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; +}; + +template<> +struct Packet_Fixed<0x00c5> +{ + static const uint16_t PACKET_ID = 0x00c5; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + uint8_t type = {}; +}; + +template<> +struct Packet_Head<0x00c6> +{ + static const uint16_t PACKET_ID = 0x00c6; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x00c6> +{ + static const uint16_t PACKET_ID = 0x00c6; + + uint32_t base_price = {}; + uint32_t actual_price = {}; + ItemType type = {}; + ItemNameId name_id = {}; +}; + +template<> +struct Packet_Head<0x00c7> +{ + static const uint16_t PACKET_ID = 0x00c7; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x00c7> +{ + static const uint16_t PACKET_ID = 0x00c7; + + IOff2 ioff2 = {}; + uint32_t base_price = {}; + uint32_t actual_price = {}; +}; + +template<> +struct Packet_Head<0x00c8> +{ + static const uint16_t PACKET_ID = 0x00c8; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x00c8> +{ + static const uint16_t PACKET_ID = 0x00c8; + + uint16_t count = {}; + ItemNameId name_id = {}; +}; + +template<> +struct Packet_Head<0x00c9> +{ + static const uint16_t PACKET_ID = 0x00c9; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x00c9> +{ + static const uint16_t PACKET_ID = 0x00c9; + + IOff2 ioff2 = {}; + uint16_t count = {}; +}; + +template<> +struct Packet_Fixed<0x00ca> +{ + static const uint16_t PACKET_ID = 0x00ca; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t fail = {}; +}; + +template<> +struct Packet_Fixed<0x00cb> +{ + static const uint16_t PACKET_ID = 0x00cb; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t fail = {}; +}; + +template<> +struct Packet_Fixed<0x00cd> +{ + static const uint16_t PACKET_ID = 0x00cd; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x00e4> +{ + static const uint16_t PACKET_ID = 0x00e4; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; +}; + +template<> +struct Packet_Fixed<0x00e5> +{ + static const uint16_t PACKET_ID = 0x00e5; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharName char_name = {}; +}; + +template<> +struct Packet_Fixed<0x00e6> +{ + static const uint16_t PACKET_ID = 0x00e6; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t type = {}; +}; + +template<> +struct Packet_Fixed<0x00e7> +{ + static const uint16_t PACKET_ID = 0x00e7; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t type = {}; +}; + +template<> +struct Packet_Fixed<0x00e8> +{ + static const uint16_t PACKET_ID = 0x00e8; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 zeny_or_ioff2 = {}; + uint32_t amount = {}; +}; + +template<> +struct Packet_Fixed<0x00e9> +{ + static const uint16_t PACKET_ID = 0x00e9; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint32_t amount = {}; + ItemNameId name_id = {}; + uint8_t identify = {}; + uint8_t broken_or_attribute = {}; + uint8_t refine = {}; + uint16_t card0 = {}; + uint16_t card1 = {}; + uint16_t card2 = {}; + uint16_t card3 = {}; +}; + +template<> +struct Packet_Fixed<0x00eb> +{ + static const uint16_t PACKET_ID = 0x00eb; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x00ec> +{ + static const uint16_t PACKET_ID = 0x00ec; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t fail = {}; +}; + +template<> +struct Packet_Fixed<0x00ed> +{ + static const uint16_t PACKET_ID = 0x00ed; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x00ee> +{ + static const uint16_t PACKET_ID = 0x00ee; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x00ef> +{ + static const uint16_t PACKET_ID = 0x00ef; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x00f0> +{ + static const uint16_t PACKET_ID = 0x00f0; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t fail = {}; +}; + +template<> +struct Packet_Fixed<0x00f2> +{ + static const uint16_t PACKET_ID = 0x00f2; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t current_slots = {}; + uint16_t max_slots = {}; +}; + +template<> +struct Packet_Fixed<0x00f3> +{ + static const uint16_t PACKET_ID = 0x00f3; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; + uint32_t amount = {}; +}; + +template<> +struct Packet_Fixed<0x00f4> +{ + static const uint16_t PACKET_ID = 0x00f4; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SOff1 soff1 = {}; + uint32_t amount = {}; + ItemNameId name_id = {}; + uint8_t identify = {}; + uint8_t broken_or_attribute = {}; + uint8_t refine = {}; + uint16_t card0 = {}; + uint16_t card1 = {}; + uint16_t card2 = {}; + uint16_t card3 = {}; +}; + +template<> +struct Packet_Fixed<0x00f5> +{ + static const uint16_t PACKET_ID = 0x00f5; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SOff1 soff1 = {}; + uint32_t amount = {}; +}; + +template<> +struct Packet_Fixed<0x00f6> +{ + static const uint16_t PACKET_ID = 0x00f6; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SOff1 soff1 = {}; + uint32_t amount = {}; +}; + +template<> +struct Packet_Fixed<0x00f7> +{ + static const uint16_t PACKET_ID = 0x00f7; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x00f8> +{ + static const uint16_t PACKET_ID = 0x00f8; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x00f9> +{ + static const uint16_t PACKET_ID = 0x00f9; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + PartyName party_name = {}; +}; + +template<> +struct Packet_Fixed<0x00fa> +{ + static const uint16_t PACKET_ID = 0x00fa; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint8_t flag = {}; +}; + +template<> +struct Packet_Head<0x00fb> +{ + static const uint16_t PACKET_ID = 0x00fb; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + PartyName party_name = {}; +}; +template<> +struct Packet_Repeat<0x00fb> +{ + static const uint16_t PACKET_ID = 0x00fb; + + AccountId account_id = {}; + CharName char_name = {}; + MapName map_name = {}; + uint8_t leader = {}; + uint8_t online = {}; +}; + +template<> +struct Packet_Fixed<0x00fc> +{ + static const uint16_t PACKET_ID = 0x00fc; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; +}; + +template<> +struct Packet_Fixed<0x00fd> +{ + static const uint16_t PACKET_ID = 0x00fd; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + CharName char_name = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Fixed<0x00fe> +{ + static const uint16_t PACKET_ID = 0x00fe; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + PartyName party_name = {}; +}; + +template<> +struct Packet_Fixed<0x00ff> +{ + static const uint16_t PACKET_ID = 0x00ff; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint32_t flag = {}; +}; + +template<> +struct Packet_Fixed<0x0100> +{ + static const uint16_t PACKET_ID = 0x0100; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x0101> +{ + static const uint16_t PACKET_ID = 0x0101; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t exp = {}; + uint16_t item = {}; +}; + +template<> +struct Packet_Fixed<0x0102> +{ + static const uint16_t PACKET_ID = 0x0102; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t exp = {}; + uint16_t item = {}; +}; + +template<> +struct Packet_Fixed<0x0103> +{ + static const uint16_t PACKET_ID = 0x0103; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + CharName unused_char_name = {}; +}; + +template<> +struct Packet_Fixed<0x0105> +{ + static const uint16_t PACKET_ID = 0x0105; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + CharName char_name = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Fixed<0x0106> +{ + static const uint16_t PACKET_ID = 0x0106; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint16_t hp = {}; + uint16_t max_hp = {}; +}; + +template<> +struct Packet_Fixed<0x0107> +{ + static const uint16_t PACKET_ID = 0x0107; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + AccountId account_id = {}; + uint16_t x = {}; + uint16_t y = {}; +}; + +template<> +struct Packet_Head<0x0108> +{ + static const uint16_t PACKET_ID = 0x0108; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x0108> +{ + static const uint16_t PACKET_ID = 0x0108; + + uint8_t c = {}; +}; + +template<> +struct Packet_Head<0x0109> +{ + static const uint16_t PACKET_ID = 0x0109; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + AccountId account_id = {}; +}; +template<> +struct Packet_Repeat<0x0109> +{ + static const uint16_t PACKET_ID = 0x0109; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x010c> +{ + static const uint16_t PACKET_ID = 0x010c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; +}; + +template<> +struct Packet_Fixed<0x010e> +{ + static const uint16_t PACKET_ID = 0x010e; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SkillID skill_id = {}; + uint16_t level = {}; + uint16_t sp = {}; + uint16_t range = {}; + uint8_t can_raise = {}; +}; + +template<> +struct Packet_Head<0x010f> +{ + static const uint16_t PACKET_ID = 0x010f; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x010f> +{ + static const uint16_t PACKET_ID = 0x010f; + + SkillInfo info = {}; +}; + +template<> +struct Packet_Fixed<0x0110> +{ + static const uint16_t PACKET_ID = 0x0110; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SkillID skill_id = {}; + uint16_t btype = {}; + uint16_t zero1 = {}; + uint8_t zero2 = {}; + uint8_t type = {}; +}; + +template<> +struct Packet_Fixed<0x0112> +{ + static const uint16_t PACKET_ID = 0x0112; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SkillID skill_id = {}; +}; + +template<> +struct Packet_Fixed<0x0118> +{ + static const uint16_t PACKET_ID = 0x0118; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x0119> +{ + static const uint16_t PACKET_ID = 0x0119; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + Opt1 opt1 = {}; + Opt2 opt2 = {}; + Option option = {}; + uint8_t zero = {}; +}; + +template<> +struct Packet_Fixed<0x0139> +{ + static const uint16_t PACKET_ID = 0x0139; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + uint16_t bl_x = {}; + uint16_t bl_y = {}; + uint16_t sd_x = {}; + uint16_t sd_y = {}; + uint16_t range = {}; +}; + +template<> +struct Packet_Fixed<0x013a> +{ + static const uint16_t PACKET_ID = 0x013a; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t attack_range = {}; +}; + +template<> +struct Packet_Fixed<0x013b> +{ + static const uint16_t PACKET_ID = 0x013b; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t type = {}; +}; + +template<> +struct Packet_Fixed<0x013c> +{ + static const uint16_t PACKET_ID = 0x013c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; +}; + +template<> +struct Packet_Fixed<0x0141> +{ + static const uint16_t PACKET_ID = 0x0141; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SP sp_type = {}; + uint16_t zero = {}; + uint32_t value_status = {}; + uint32_t value_b_e = {}; +}; + +template<> +struct Packet_Fixed<0x0142> +{ + static const uint16_t PACKET_ID = 0x0142; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; +}; + +template<> +struct Packet_Fixed<0x0143> +{ + static const uint16_t PACKET_ID = 0x0143; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + uint32_t input_int_value = {}; +}; + +template<> +struct Packet_Fixed<0x0146> +{ + static const uint16_t PACKET_ID = 0x0146; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; +}; + +template<> +struct Packet_Fixed<0x0147> +{ + static const uint16_t PACKET_ID = 0x0147; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SkillInfo info = {}; +}; + +template<> +struct Packet_Fixed<0x0148> +{ + static const uint16_t PACKET_ID = 0x0148; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + uint16_t type = {}; +}; + +template<> +struct Packet_Fixed<0x014d> +{ + static const uint16_t PACKET_ID = 0x014d; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; +}; + +template<> +struct Packet_Fixed<0x018a> +{ + static const uint16_t PACKET_ID = 0x018a; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t unused = {}; +}; + +template<> +struct Packet_Fixed<0x018b> +{ + static const uint16_t PACKET_ID = 0x018b; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + uint16_t okay = {}; +}; + +template<> +struct Packet_Fixed<0x0195> +{ + static const uint16_t PACKET_ID = 0x0195; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + PartyName party_name = {}; + VString<23> guild_name = {}; + VString<23> guild_pos = {}; + VString<23> guild_pos_again = {}; +}; + +template<> +struct Packet_Fixed<0x0196> +{ + static const uint16_t PACKET_ID = 0x0196; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + StatusChange sc_type = {}; + BlockId block_id = {}; + uint8_t flag = {}; +}; + +template<> +struct Packet_Fixed<0x019b> +{ + static const uint16_t PACKET_ID = 0x019b; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + uint32_t type = {}; +}; + +template<> +struct Packet_Fixed<0x01b1> +{ + static const uint16_t PACKET_ID = 0x01b1; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; + uint16_t amount = {}; + uint8_t fail = {}; +}; + +template<> +struct Packet_Fixed<0x01c8> +{ + static const uint16_t PACKET_ID = 0x01c8; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + IOff2 ioff2 = {}; + ItemNameId name_id = {}; + BlockId block_id = {}; + uint16_t amount = {}; + uint8_t ok = {}; +}; + +template<> +struct Packet_Fixed<0x01d4> +{ + static const uint16_t PACKET_ID = 0x01d4; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; +}; + +template<> +struct Packet_Head<0x01d5> +{ + static const uint16_t PACKET_ID = 0x01d5; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; + BlockId block_id = {}; +}; +template<> +struct Packet_Repeat<0x01d5> +{ + static const uint16_t PACKET_ID = 0x01d5; + + uint8_t c = {}; +}; + +template<> +struct Packet_Fixed<0x01d7> +{ + static const uint16_t PACKET_ID = 0x01d7; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + LOOK look_type = {}; + uint16_t weapon_or_name_id_or_value = {}; + ItemNameId shield = {}; +}; + +template<> +struct Packet_Fixed<0x01d8> +{ + static const uint16_t PACKET_ID = 0x01d8; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + interval_t speed = {}; + Opt1 opt1 = {}; + Opt2 opt2 = {}; + Option option = {}; + Species species = {}; + uint16_t hair_style = {}; + ItemNameId weapon = {}; + ItemNameId shield = {}; + ItemNameId head_bottom = {}; + ItemNameId head_top = {}; + ItemNameId head_mid = {}; + uint16_t hair_color = {}; + uint16_t clothes_color = {}; + DIR head_dir = {}; + uint8_t unused2 = {}; + uint32_t guild_id = {}; + uint16_t guild_emblem_id = {}; + uint16_t manner = {}; + Opt3 opt3 = {}; + uint8_t karma = {}; + SEX sex = {}; + Position1 pos = {}; + uint16_t gm_bits = {}; + uint8_t dead_sit = {}; + uint16_t unused = {}; +}; + +template<> +struct Packet_Fixed<0x01d9> +{ + static const uint16_t PACKET_ID = 0x01d9; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + interval_t speed = {}; + Opt1 opt1 = {}; + Opt2 opt2 = {}; + Option option = {}; + Species species = {}; + uint16_t hair_style = {}; + ItemNameId weapon = {}; + ItemNameId shield = {}; + ItemNameId head_bottom = {}; + ItemNameId head_top = {}; + ItemNameId head_mid = {}; + uint16_t hair_color = {}; + uint16_t clothes_color = {}; + DIR head_dir = {}; + uint8_t unused2 = {}; + uint32_t guild_id = {}; + uint16_t guild_emblem_id = {}; + uint16_t manner = {}; + Opt3 opt3 = {}; + uint8_t karma = {}; + SEX sex = {}; + Position1 pos = {}; + uint16_t gm_bits = {}; + uint16_t unused = {}; +}; + +template<> +struct Packet_Fixed<0x01da> +{ + static const uint16_t PACKET_ID = 0x01da; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + interval_t speed = {}; + Opt1 opt1 = {}; + Opt2 opt2 = {}; + Option option = {}; + Species species = {}; + uint16_t hair_style = {}; + ItemNameId weapon = {}; + ItemNameId shield = {}; + ItemNameId head_bottom = {}; + tick_t tick = {}; + ItemNameId head_top = {}; + ItemNameId head_mid = {}; + uint16_t hair_color = {}; + uint16_t clothes_color = {}; + DIR head_dir = {}; + uint8_t unused2 = {}; + uint32_t guild_id = {}; + uint16_t guild_emblem_id = {}; + uint16_t manner = {}; + Opt3 opt3 = {}; + uint8_t karma = {}; + SEX sex = {}; + Position2 pos2 = {}; + uint16_t gm_bits = {}; + uint8_t five = {}; + uint16_t unused = {}; +}; + +template<> +struct Packet_Fixed<0x01de> +{ + static const uint16_t PACKET_ID = 0x01de; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + SkillID skill_id = {}; + BlockId src_id = {}; + BlockId dst_id = {}; + tick_t tick = {}; + interval_t sdelay = {}; + interval_t ddelay = {}; + uint32_t damage = {}; + uint16_t skill_level = {}; + uint16_t div = {}; + uint8_t type_or_hit = {}; +}; + +template<> +struct Packet_Head<0x01ee> +{ + static const uint16_t PACKET_ID = 0x01ee; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x01ee> +{ + static const uint16_t PACKET_ID = 0x01ee; + + IOff2 ioff2 = {}; + ItemNameId name_id = {}; + ItemType item_type = {}; + uint8_t identify = {}; + uint16_t amount = {}; + EPOS epos = {}; + uint16_t card0 = {}; + uint16_t card1 = {}; + uint16_t card2 = {}; + uint16_t card3 = {}; +}; + +template<> +struct Packet_Head<0x01f0> +{ + static const uint16_t PACKET_ID = 0x01f0; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + // TODO remove this + uint16_t magic_packet_length = {}; +}; +template<> +struct Packet_Repeat<0x01f0> +{ + static const uint16_t PACKET_ID = 0x01f0; + + SOff1 soff1 = {}; + ItemNameId name_id = {}; + ItemType item_type = {}; + uint8_t identify = {}; + uint16_t amount = {}; + EPOS epos_zero = {}; + uint16_t card0 = {}; + uint16_t card1 = {}; + uint16_t card2 = {}; + uint16_t card3 = {}; +}; + +template<> +struct Packet_Fixed<0x020c> +{ + static const uint16_t PACKET_ID = 0x020c; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId block_id = {}; + IP4Address ip = {}; +}; + +template<> +struct Packet_Fixed<0x0212> +{ + static const uint16_t PACKET_ID = 0x0212; + + // TODO remove this + uint16_t magic_packet_id = PACKET_ID; + BlockId npc_id = {}; + uint16_t command = {}; + BlockId id = {}; + uint16_t x = {}; + uint16_t y = {}; +}; + + +template<> +struct NetPacket_Fixed<0x0072> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 char_id; + Little32 login_id1; + Little32 client_tick; + Byte sex; +}; +static_assert(offsetof(NetPacket_Fixed<0x0072>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0072>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0072>, account_id) == 2, "offsetof(NetPacket_Fixed<0x0072>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0072>, char_id) == 6, "offsetof(NetPacket_Fixed<0x0072>, char_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0072>, login_id1) == 10, "offsetof(NetPacket_Fixed<0x0072>, login_id1) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x0072>, client_tick) == 14, "offsetof(NetPacket_Fixed<0x0072>, client_tick) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x0072>, sex) == 18, "offsetof(NetPacket_Fixed<0x0072>, sex) == 18"); +static_assert(sizeof(NetPacket_Fixed<0x0072>) == 19, "sizeof(NetPacket_Fixed<0x0072>) == 19"); +static_assert(alignof(NetPacket_Fixed<0x0072>) == 1, "alignof(NetPacket_Fixed<0x0072>) == 1"); + +template<> +struct NetPacket_Fixed<0x0073> +{ + Little16 magic_packet_id; + Little32 tick; + NetPosition1 pos; + Byte five1; + Byte five2; +}; +static_assert(offsetof(NetPacket_Fixed<0x0073>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0073>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0073>, tick) == 2, "offsetof(NetPacket_Fixed<0x0073>, tick) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0073>, pos) == 6, "offsetof(NetPacket_Fixed<0x0073>, pos) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0073>, five1) == 9, "offsetof(NetPacket_Fixed<0x0073>, five1) == 9"); +static_assert(offsetof(NetPacket_Fixed<0x0073>, five2) == 10, "offsetof(NetPacket_Fixed<0x0073>, five2) == 10"); +static_assert(sizeof(NetPacket_Fixed<0x0073>) == 11, "sizeof(NetPacket_Fixed<0x0073>) == 11"); +static_assert(alignof(NetPacket_Fixed<0x0073>) == 1, "alignof(NetPacket_Fixed<0x0073>) == 1"); + +template<> +struct NetPacket_Fixed<0x0078> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 speed; + Little16 opt1; + Little16 opt2; + Little16 option; + Little16 species; + Little16 unused_hair_style; + Little16 unused_weapon; + Little16 unused_head_bottom_or_species_again; + Little16 unused_shield_or_part_of_guild_emblem; + Little16 unused_head_top_or_unused_part_of_guild_emblem; + Little16 unused_head_mid_or_part_of_guild_id; + Little16 unused_hair_color_or_part_of_guild_id; + Little16 unused_clothes_color; + Little16 unused_1; + Little16 unused_2; + NetPosition1 unused_pos_again; + Byte unused_4b; + Little16 unused_5; + Little16 unused_zero_1; + Byte unused_zero_2; + Byte unused_sex; + NetPosition1 pos; + Byte five1; + Byte five2; + Byte zero; + Little16 level; +}; +static_assert(offsetof(NetPacket_Fixed<0x0078>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0078>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0078>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, speed) == 6, "offsetof(NetPacket_Fixed<0x0078>, speed) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, opt1) == 8, "offsetof(NetPacket_Fixed<0x0078>, opt1) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, opt2) == 10, "offsetof(NetPacket_Fixed<0x0078>, opt2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, option) == 12, "offsetof(NetPacket_Fixed<0x0078>, option) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, species) == 14, "offsetof(NetPacket_Fixed<0x0078>, species) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_hair_style) == 16, "offsetof(NetPacket_Fixed<0x0078>, unused_hair_style) == 16"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_weapon) == 18, "offsetof(NetPacket_Fixed<0x0078>, unused_weapon) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_head_bottom_or_species_again) == 20, "offsetof(NetPacket_Fixed<0x0078>, unused_head_bottom_or_species_again) == 20"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_shield_or_part_of_guild_emblem) == 22, "offsetof(NetPacket_Fixed<0x0078>, unused_shield_or_part_of_guild_emblem) == 22"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_head_top_or_unused_part_of_guild_emblem) == 24, "offsetof(NetPacket_Fixed<0x0078>, unused_head_top_or_unused_part_of_guild_emblem) == 24"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_head_mid_or_part_of_guild_id) == 26, "offsetof(NetPacket_Fixed<0x0078>, unused_head_mid_or_part_of_guild_id) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_hair_color_or_part_of_guild_id) == 28, "offsetof(NetPacket_Fixed<0x0078>, unused_hair_color_or_part_of_guild_id) == 28"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_clothes_color) == 30, "offsetof(NetPacket_Fixed<0x0078>, unused_clothes_color) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_1) == 32, "offsetof(NetPacket_Fixed<0x0078>, unused_1) == 32"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_2) == 34, "offsetof(NetPacket_Fixed<0x0078>, unused_2) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_pos_again) == 36, "offsetof(NetPacket_Fixed<0x0078>, unused_pos_again) == 36"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_4b) == 39, "offsetof(NetPacket_Fixed<0x0078>, unused_4b) == 39"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_5) == 40, "offsetof(NetPacket_Fixed<0x0078>, unused_5) == 40"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_zero_1) == 42, "offsetof(NetPacket_Fixed<0x0078>, unused_zero_1) == 42"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_zero_2) == 44, "offsetof(NetPacket_Fixed<0x0078>, unused_zero_2) == 44"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, unused_sex) == 45, "offsetof(NetPacket_Fixed<0x0078>, unused_sex) == 45"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, pos) == 46, "offsetof(NetPacket_Fixed<0x0078>, pos) == 46"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, five1) == 49, "offsetof(NetPacket_Fixed<0x0078>, five1) == 49"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, five2) == 50, "offsetof(NetPacket_Fixed<0x0078>, five2) == 50"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, zero) == 51, "offsetof(NetPacket_Fixed<0x0078>, zero) == 51"); +static_assert(offsetof(NetPacket_Fixed<0x0078>, level) == 52, "offsetof(NetPacket_Fixed<0x0078>, level) == 52"); +static_assert(sizeof(NetPacket_Fixed<0x0078>) == 54, "sizeof(NetPacket_Fixed<0x0078>) == 54"); +static_assert(alignof(NetPacket_Fixed<0x0078>) == 1, "alignof(NetPacket_Fixed<0x0078>) == 1"); + +template<> +struct NetPacket_Fixed<0x007b> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 speed; + Little16 opt1; + Little16 opt2; + Little16 option; + Little16 mob_class; + Little16 unused_hair_style; + Little16 unused_weapon; + Little16 unused_head_bottom; + Little32 tick_and_maybe_part_of_guild_emblem; + Little16 unused_shield_or_maybe_part_of_guild_emblem; + Little16 unused_head_top_or_maybe_part_of_guild_id; + Little16 unused_head_mid_or_maybe_part_of_guild_id; + Little16 unused_hair_color; + Little16 unused_clothes_color; + Little16 unused_1; + Little16 unused_2; + Little16 unused_3; + Little16 unused_4; + Little16 unused_5; + Little16 unused_zero_1; + Byte unused_zero_2; + Byte unused_sex; + NetPosition2 pos2; + Byte zero; + Byte five1; + Byte five2; + Little16 level; +}; +static_assert(offsetof(NetPacket_Fixed<0x007b>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x007b>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, block_id) == 2, "offsetof(NetPacket_Fixed<0x007b>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, speed) == 6, "offsetof(NetPacket_Fixed<0x007b>, speed) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, opt1) == 8, "offsetof(NetPacket_Fixed<0x007b>, opt1) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, opt2) == 10, "offsetof(NetPacket_Fixed<0x007b>, opt2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, option) == 12, "offsetof(NetPacket_Fixed<0x007b>, option) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, mob_class) == 14, "offsetof(NetPacket_Fixed<0x007b>, mob_class) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_hair_style) == 16, "offsetof(NetPacket_Fixed<0x007b>, unused_hair_style) == 16"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_weapon) == 18, "offsetof(NetPacket_Fixed<0x007b>, unused_weapon) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_head_bottom) == 20, "offsetof(NetPacket_Fixed<0x007b>, unused_head_bottom) == 20"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, tick_and_maybe_part_of_guild_emblem) == 22, "offsetof(NetPacket_Fixed<0x007b>, tick_and_maybe_part_of_guild_emblem) == 22"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_shield_or_maybe_part_of_guild_emblem) == 26, "offsetof(NetPacket_Fixed<0x007b>, unused_shield_or_maybe_part_of_guild_emblem) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_head_top_or_maybe_part_of_guild_id) == 28, "offsetof(NetPacket_Fixed<0x007b>, unused_head_top_or_maybe_part_of_guild_id) == 28"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_head_mid_or_maybe_part_of_guild_id) == 30, "offsetof(NetPacket_Fixed<0x007b>, unused_head_mid_or_maybe_part_of_guild_id) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_hair_color) == 32, "offsetof(NetPacket_Fixed<0x007b>, unused_hair_color) == 32"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_clothes_color) == 34, "offsetof(NetPacket_Fixed<0x007b>, unused_clothes_color) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_1) == 36, "offsetof(NetPacket_Fixed<0x007b>, unused_1) == 36"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_2) == 38, "offsetof(NetPacket_Fixed<0x007b>, unused_2) == 38"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_3) == 40, "offsetof(NetPacket_Fixed<0x007b>, unused_3) == 40"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_4) == 42, "offsetof(NetPacket_Fixed<0x007b>, unused_4) == 42"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_5) == 44, "offsetof(NetPacket_Fixed<0x007b>, unused_5) == 44"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_zero_1) == 46, "offsetof(NetPacket_Fixed<0x007b>, unused_zero_1) == 46"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_zero_2) == 48, "offsetof(NetPacket_Fixed<0x007b>, unused_zero_2) == 48"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, unused_sex) == 49, "offsetof(NetPacket_Fixed<0x007b>, unused_sex) == 49"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, pos2) == 50, "offsetof(NetPacket_Fixed<0x007b>, pos2) == 50"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, zero) == 55, "offsetof(NetPacket_Fixed<0x007b>, zero) == 55"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, five1) == 56, "offsetof(NetPacket_Fixed<0x007b>, five1) == 56"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, five2) == 57, "offsetof(NetPacket_Fixed<0x007b>, five2) == 57"); +static_assert(offsetof(NetPacket_Fixed<0x007b>, level) == 58, "offsetof(NetPacket_Fixed<0x007b>, level) == 58"); +static_assert(sizeof(NetPacket_Fixed<0x007b>) == 60, "sizeof(NetPacket_Fixed<0x007b>) == 60"); +static_assert(alignof(NetPacket_Fixed<0x007b>) == 1, "alignof(NetPacket_Fixed<0x007b>) == 1"); + +template<> +struct NetPacket_Fixed<0x007c> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 speed; + Little16 opt1; + Little16 opt2; + Little16 option; + Little16 unknown_1; + Little16 unknown_2; + Little16 unknown_3; + Little16 species; + Little16 unknown_4; + Little16 unknown_5; + Little16 unknown_6; + Little16 unknown_7; + Little16 unknown_8; + Little16 unknown_9; + Little16 unknown_10; + NetPosition1 pos; + Little16 unknown_11; +}; +static_assert(offsetof(NetPacket_Fixed<0x007c>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x007c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, block_id) == 2, "offsetof(NetPacket_Fixed<0x007c>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, speed) == 6, "offsetof(NetPacket_Fixed<0x007c>, speed) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, opt1) == 8, "offsetof(NetPacket_Fixed<0x007c>, opt1) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, opt2) == 10, "offsetof(NetPacket_Fixed<0x007c>, opt2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, option) == 12, "offsetof(NetPacket_Fixed<0x007c>, option) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, unknown_1) == 14, "offsetof(NetPacket_Fixed<0x007c>, unknown_1) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, unknown_2) == 16, "offsetof(NetPacket_Fixed<0x007c>, unknown_2) == 16"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, unknown_3) == 18, "offsetof(NetPacket_Fixed<0x007c>, unknown_3) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, species) == 20, "offsetof(NetPacket_Fixed<0x007c>, species) == 20"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, unknown_4) == 22, "offsetof(NetPacket_Fixed<0x007c>, unknown_4) == 22"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, unknown_5) == 24, "offsetof(NetPacket_Fixed<0x007c>, unknown_5) == 24"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, unknown_6) == 26, "offsetof(NetPacket_Fixed<0x007c>, unknown_6) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, unknown_7) == 28, "offsetof(NetPacket_Fixed<0x007c>, unknown_7) == 28"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, unknown_8) == 30, "offsetof(NetPacket_Fixed<0x007c>, unknown_8) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, unknown_9) == 32, "offsetof(NetPacket_Fixed<0x007c>, unknown_9) == 32"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, unknown_10) == 34, "offsetof(NetPacket_Fixed<0x007c>, unknown_10) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, pos) == 36, "offsetof(NetPacket_Fixed<0x007c>, pos) == 36"); +static_assert(offsetof(NetPacket_Fixed<0x007c>, unknown_11) == 39, "offsetof(NetPacket_Fixed<0x007c>, unknown_11) == 39"); +static_assert(sizeof(NetPacket_Fixed<0x007c>) == 41, "sizeof(NetPacket_Fixed<0x007c>) == 41"); +static_assert(alignof(NetPacket_Fixed<0x007c>) == 1, "alignof(NetPacket_Fixed<0x007c>) == 1"); + +template<> +struct NetPacket_Fixed<0x007d> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x007d>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x007d>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x007d>) == 2, "sizeof(NetPacket_Fixed<0x007d>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x007d>) == 1, "alignof(NetPacket_Fixed<0x007d>) == 1"); + +template<> +struct NetPacket_Fixed<0x007e> +{ + Little16 magic_packet_id; + Little32 client_tick; +}; +static_assert(offsetof(NetPacket_Fixed<0x007e>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x007e>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x007e>, client_tick) == 2, "offsetof(NetPacket_Fixed<0x007e>, client_tick) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x007e>) == 6, "sizeof(NetPacket_Fixed<0x007e>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x007e>) == 1, "alignof(NetPacket_Fixed<0x007e>) == 1"); + +template<> +struct NetPacket_Fixed<0x007f> +{ + Little16 magic_packet_id; + Little32 tick; +}; +static_assert(offsetof(NetPacket_Fixed<0x007f>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x007f>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x007f>, tick) == 2, "offsetof(NetPacket_Fixed<0x007f>, tick) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x007f>) == 6, "sizeof(NetPacket_Fixed<0x007f>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x007f>) == 1, "alignof(NetPacket_Fixed<0x007f>) == 1"); + +template<> +struct NetPacket_Fixed<0x0080> +{ + Little16 magic_packet_id; + Little32 block_id; + Byte type; +}; +static_assert(offsetof(NetPacket_Fixed<0x0080>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0080>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0080>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0080>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0080>, type) == 6, "offsetof(NetPacket_Fixed<0x0080>, type) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x0080>) == 7, "sizeof(NetPacket_Fixed<0x0080>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x0080>) == 1, "alignof(NetPacket_Fixed<0x0080>) == 1"); + +template<> +struct NetPacket_Fixed<0x0085> +{ + Little16 magic_packet_id; + NetPosition1 pos; +}; +static_assert(offsetof(NetPacket_Fixed<0x0085>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0085>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0085>, pos) == 2, "offsetof(NetPacket_Fixed<0x0085>, pos) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0085>) == 5, "sizeof(NetPacket_Fixed<0x0085>) == 5"); +static_assert(alignof(NetPacket_Fixed<0x0085>) == 1, "alignof(NetPacket_Fixed<0x0085>) == 1"); + +template<> +struct NetPacket_Fixed<0x0087> +{ + Little16 magic_packet_id; + Little32 tick; + NetPosition2 pos2; + Byte zero; +}; +static_assert(offsetof(NetPacket_Fixed<0x0087>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0087>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0087>, tick) == 2, "offsetof(NetPacket_Fixed<0x0087>, tick) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0087>, pos2) == 6, "offsetof(NetPacket_Fixed<0x0087>, pos2) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0087>, zero) == 11, "offsetof(NetPacket_Fixed<0x0087>, zero) == 11"); +static_assert(sizeof(NetPacket_Fixed<0x0087>) == 12, "sizeof(NetPacket_Fixed<0x0087>) == 12"); +static_assert(alignof(NetPacket_Fixed<0x0087>) == 1, "alignof(NetPacket_Fixed<0x0087>) == 1"); + +template<> +struct NetPacket_Fixed<0x0088> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 x; + Little16 y; +}; +static_assert(offsetof(NetPacket_Fixed<0x0088>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0088>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0088>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0088>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0088>, x) == 6, "offsetof(NetPacket_Fixed<0x0088>, x) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0088>, y) == 8, "offsetof(NetPacket_Fixed<0x0088>, y) == 8"); +static_assert(sizeof(NetPacket_Fixed<0x0088>) == 10, "sizeof(NetPacket_Fixed<0x0088>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x0088>) == 1, "alignof(NetPacket_Fixed<0x0088>) == 1"); + +template<> +struct NetPacket_Fixed<0x0089> +{ + Little16 magic_packet_id; + Little32 target_id; + Byte action; +}; +static_assert(offsetof(NetPacket_Fixed<0x0089>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0089>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0089>, target_id) == 2, "offsetof(NetPacket_Fixed<0x0089>, target_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0089>, action) == 6, "offsetof(NetPacket_Fixed<0x0089>, action) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x0089>) == 7, "sizeof(NetPacket_Fixed<0x0089>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x0089>) == 1, "alignof(NetPacket_Fixed<0x0089>) == 1"); + +template<> +struct NetPacket_Fixed<0x008a> +{ + Little16 magic_packet_id; + Little32 src_id; + Little32 dst_id; + Little32 tick; + Little32 sdelay; + Little32 ddelay; + Little16 damage; + Little16 div; + Byte damage_type; + Little16 damage2; +}; +static_assert(offsetof(NetPacket_Fixed<0x008a>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x008a>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x008a>, src_id) == 2, "offsetof(NetPacket_Fixed<0x008a>, src_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x008a>, dst_id) == 6, "offsetof(NetPacket_Fixed<0x008a>, dst_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x008a>, tick) == 10, "offsetof(NetPacket_Fixed<0x008a>, tick) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x008a>, sdelay) == 14, "offsetof(NetPacket_Fixed<0x008a>, sdelay) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x008a>, ddelay) == 18, "offsetof(NetPacket_Fixed<0x008a>, ddelay) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x008a>, damage) == 22, "offsetof(NetPacket_Fixed<0x008a>, damage) == 22"); +static_assert(offsetof(NetPacket_Fixed<0x008a>, div) == 24, "offsetof(NetPacket_Fixed<0x008a>, div) == 24"); +static_assert(offsetof(NetPacket_Fixed<0x008a>, damage_type) == 26, "offsetof(NetPacket_Fixed<0x008a>, damage_type) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x008a>, damage2) == 27, "offsetof(NetPacket_Fixed<0x008a>, damage2) == 27"); +static_assert(sizeof(NetPacket_Fixed<0x008a>) == 29, "sizeof(NetPacket_Fixed<0x008a>) == 29"); +static_assert(alignof(NetPacket_Fixed<0x008a>) == 1, "alignof(NetPacket_Fixed<0x008a>) == 1"); + +template<> +struct NetPacket_Head<0x008c> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x008c>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x008c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x008c>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x008c>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x008c>) == 4, "sizeof(NetPacket_Head<0x008c>) == 4"); +static_assert(alignof(NetPacket_Head<0x008c>) == 1, "alignof(NetPacket_Head<0x008c>) == 1"); +template<> +struct NetPacket_Repeat<0x008c> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x008c>, c) == 0, "offsetof(NetPacket_Repeat<0x008c>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x008c>) == 1, "sizeof(NetPacket_Repeat<0x008c>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x008c>) == 1, "alignof(NetPacket_Repeat<0x008c>) == 1"); + +template<> +struct NetPacket_Head<0x008d> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Head<0x008d>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x008d>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x008d>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x008d>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x008d>, block_id) == 4, "offsetof(NetPacket_Head<0x008d>, block_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x008d>) == 8, "sizeof(NetPacket_Head<0x008d>) == 8"); +static_assert(alignof(NetPacket_Head<0x008d>) == 1, "alignof(NetPacket_Head<0x008d>) == 1"); +template<> +struct NetPacket_Repeat<0x008d> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x008d>, c) == 0, "offsetof(NetPacket_Repeat<0x008d>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x008d>) == 1, "sizeof(NetPacket_Repeat<0x008d>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x008d>) == 1, "alignof(NetPacket_Repeat<0x008d>) == 1"); + +template<> +struct NetPacket_Head<0x008e> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x008e>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x008e>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x008e>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x008e>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x008e>) == 4, "sizeof(NetPacket_Head<0x008e>) == 4"); +static_assert(alignof(NetPacket_Head<0x008e>) == 1, "alignof(NetPacket_Head<0x008e>) == 1"); +template<> +struct NetPacket_Repeat<0x008e> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x008e>, c) == 0, "offsetof(NetPacket_Repeat<0x008e>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x008e>) == 1, "sizeof(NetPacket_Repeat<0x008e>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x008e>) == 1, "alignof(NetPacket_Repeat<0x008e>) == 1"); + +template<> +struct NetPacket_Fixed<0x0090> +{ + Little16 magic_packet_id; + Little32 block_id; + Byte unused; +}; +static_assert(offsetof(NetPacket_Fixed<0x0090>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0090>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0090>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0090>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0090>, unused) == 6, "offsetof(NetPacket_Fixed<0x0090>, unused) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x0090>) == 7, "sizeof(NetPacket_Fixed<0x0090>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x0090>) == 1, "alignof(NetPacket_Fixed<0x0090>) == 1"); + +template<> +struct NetPacket_Fixed<0x0091> +{ + Little16 magic_packet_id; + NetString<sizeof(MapName)> map_name; + Little16 x; + Little16 y; +}; +static_assert(offsetof(NetPacket_Fixed<0x0091>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0091>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0091>, map_name) == 2, "offsetof(NetPacket_Fixed<0x0091>, map_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0091>, x) == 18, "offsetof(NetPacket_Fixed<0x0091>, x) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x0091>, y) == 20, "offsetof(NetPacket_Fixed<0x0091>, y) == 20"); +static_assert(sizeof(NetPacket_Fixed<0x0091>) == 22, "sizeof(NetPacket_Fixed<0x0091>) == 22"); +static_assert(alignof(NetPacket_Fixed<0x0091>) == 1, "alignof(NetPacket_Fixed<0x0091>) == 1"); + +template<> +struct NetPacket_Fixed<0x0092> +{ + Little16 magic_packet_id; + NetString<sizeof(MapName)> map_name; + Little16 x; + Little16 y; + IP4Address ip; + Little16 port; +}; +static_assert(offsetof(NetPacket_Fixed<0x0092>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0092>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0092>, map_name) == 2, "offsetof(NetPacket_Fixed<0x0092>, map_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0092>, x) == 18, "offsetof(NetPacket_Fixed<0x0092>, x) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x0092>, y) == 20, "offsetof(NetPacket_Fixed<0x0092>, y) == 20"); +static_assert(offsetof(NetPacket_Fixed<0x0092>, ip) == 22, "offsetof(NetPacket_Fixed<0x0092>, ip) == 22"); +static_assert(offsetof(NetPacket_Fixed<0x0092>, port) == 26, "offsetof(NetPacket_Fixed<0x0092>, port) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x0092>) == 28, "sizeof(NetPacket_Fixed<0x0092>) == 28"); +static_assert(alignof(NetPacket_Fixed<0x0092>) == 1, "alignof(NetPacket_Fixed<0x0092>) == 1"); + +template<> +struct NetPacket_Fixed<0x0094> +{ + Little16 magic_packet_id; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x0094>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0094>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0094>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0094>, block_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0094>) == 6, "sizeof(NetPacket_Fixed<0x0094>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x0094>) == 1, "alignof(NetPacket_Fixed<0x0094>) == 1"); + +template<> +struct NetPacket_Fixed<0x0095> +{ + Little16 magic_packet_id; + Little32 block_id; + NetString<sizeof(CharName)> char_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x0095>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0095>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0095>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0095>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0095>, char_name) == 6, "offsetof(NetPacket_Fixed<0x0095>, char_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x0095>) == 30, "sizeof(NetPacket_Fixed<0x0095>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x0095>) == 1, "alignof(NetPacket_Fixed<0x0095>) == 1"); + +template<> +struct NetPacket_Head<0x0096> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + NetString<sizeof(CharName)> target_name; +}; +static_assert(offsetof(NetPacket_Head<0x0096>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x0096>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x0096>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x0096>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x0096>, target_name) == 4, "offsetof(NetPacket_Head<0x0096>, target_name) == 4"); +static_assert(sizeof(NetPacket_Head<0x0096>) == 28, "sizeof(NetPacket_Head<0x0096>) == 28"); +static_assert(alignof(NetPacket_Head<0x0096>) == 1, "alignof(NetPacket_Head<0x0096>) == 1"); +template<> +struct NetPacket_Repeat<0x0096> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x0096>, c) == 0, "offsetof(NetPacket_Repeat<0x0096>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x0096>) == 1, "sizeof(NetPacket_Repeat<0x0096>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x0096>) == 1, "alignof(NetPacket_Repeat<0x0096>) == 1"); + +template<> +struct NetPacket_Head<0x0097> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + NetString<sizeof(CharName)> char_name; +}; +static_assert(offsetof(NetPacket_Head<0x0097>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x0097>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x0097>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x0097>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x0097>, char_name) == 4, "offsetof(NetPacket_Head<0x0097>, char_name) == 4"); +static_assert(sizeof(NetPacket_Head<0x0097>) == 28, "sizeof(NetPacket_Head<0x0097>) == 28"); +static_assert(alignof(NetPacket_Head<0x0097>) == 1, "alignof(NetPacket_Head<0x0097>) == 1"); +template<> +struct NetPacket_Repeat<0x0097> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x0097>, c) == 0, "offsetof(NetPacket_Repeat<0x0097>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x0097>) == 1, "sizeof(NetPacket_Repeat<0x0097>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x0097>) == 1, "alignof(NetPacket_Repeat<0x0097>) == 1"); + +template<> +struct NetPacket_Fixed<0x0098> +{ + Little16 magic_packet_id; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x0098>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0098>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0098>, flag) == 2, "offsetof(NetPacket_Fixed<0x0098>, flag) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0098>) == 3, "sizeof(NetPacket_Fixed<0x0098>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x0098>) == 1, "alignof(NetPacket_Fixed<0x0098>) == 1"); + +template<> +struct NetPacket_Head<0x009a> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x009a>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x009a>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x009a>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x009a>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x009a>) == 4, "sizeof(NetPacket_Head<0x009a>) == 4"); +static_assert(alignof(NetPacket_Head<0x009a>) == 1, "alignof(NetPacket_Head<0x009a>) == 1"); +template<> +struct NetPacket_Repeat<0x009a> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x009a>, c) == 0, "offsetof(NetPacket_Repeat<0x009a>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x009a>) == 1, "sizeof(NetPacket_Repeat<0x009a>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x009a>) == 1, "alignof(NetPacket_Repeat<0x009a>) == 1"); + +template<> +struct NetPacket_Fixed<0x009b> +{ + Little16 magic_packet_id; + Little16 unused; + Byte client_dir; +}; +static_assert(offsetof(NetPacket_Fixed<0x009b>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x009b>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x009b>, unused) == 2, "offsetof(NetPacket_Fixed<0x009b>, unused) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x009b>, client_dir) == 4, "offsetof(NetPacket_Fixed<0x009b>, client_dir) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x009b>) == 5, "sizeof(NetPacket_Fixed<0x009b>) == 5"); +static_assert(alignof(NetPacket_Fixed<0x009b>) == 1, "alignof(NetPacket_Fixed<0x009b>) == 1"); + +template<> +struct NetPacket_Fixed<0x009c> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 zero; + Byte client_dir; +}; +static_assert(offsetof(NetPacket_Fixed<0x009c>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x009c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x009c>, block_id) == 2, "offsetof(NetPacket_Fixed<0x009c>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x009c>, zero) == 6, "offsetof(NetPacket_Fixed<0x009c>, zero) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x009c>, client_dir) == 8, "offsetof(NetPacket_Fixed<0x009c>, client_dir) == 8"); +static_assert(sizeof(NetPacket_Fixed<0x009c>) == 9, "sizeof(NetPacket_Fixed<0x009c>) == 9"); +static_assert(alignof(NetPacket_Fixed<0x009c>) == 1, "alignof(NetPacket_Fixed<0x009c>) == 1"); + +template<> +struct NetPacket_Fixed<0x009d> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 name_id; + Byte identify; + Little16 x; + Little16 y; + Little16 amount; + Byte subx; + Byte suby; +}; +static_assert(offsetof(NetPacket_Fixed<0x009d>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x009d>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x009d>, block_id) == 2, "offsetof(NetPacket_Fixed<0x009d>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x009d>, name_id) == 6, "offsetof(NetPacket_Fixed<0x009d>, name_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x009d>, identify) == 8, "offsetof(NetPacket_Fixed<0x009d>, identify) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x009d>, x) == 9, "offsetof(NetPacket_Fixed<0x009d>, x) == 9"); +static_assert(offsetof(NetPacket_Fixed<0x009d>, y) == 11, "offsetof(NetPacket_Fixed<0x009d>, y) == 11"); +static_assert(offsetof(NetPacket_Fixed<0x009d>, amount) == 13, "offsetof(NetPacket_Fixed<0x009d>, amount) == 13"); +static_assert(offsetof(NetPacket_Fixed<0x009d>, subx) == 15, "offsetof(NetPacket_Fixed<0x009d>, subx) == 15"); +static_assert(offsetof(NetPacket_Fixed<0x009d>, suby) == 16, "offsetof(NetPacket_Fixed<0x009d>, suby) == 16"); +static_assert(sizeof(NetPacket_Fixed<0x009d>) == 17, "sizeof(NetPacket_Fixed<0x009d>) == 17"); +static_assert(alignof(NetPacket_Fixed<0x009d>) == 1, "alignof(NetPacket_Fixed<0x009d>) == 1"); + +template<> +struct NetPacket_Fixed<0x009e> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 name_id; + Byte identify; + Little16 x; + Little16 y; + Byte subx; + Byte suby; + Little16 amount; +}; +static_assert(offsetof(NetPacket_Fixed<0x009e>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x009e>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x009e>, block_id) == 2, "offsetof(NetPacket_Fixed<0x009e>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x009e>, name_id) == 6, "offsetof(NetPacket_Fixed<0x009e>, name_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x009e>, identify) == 8, "offsetof(NetPacket_Fixed<0x009e>, identify) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x009e>, x) == 9, "offsetof(NetPacket_Fixed<0x009e>, x) == 9"); +static_assert(offsetof(NetPacket_Fixed<0x009e>, y) == 11, "offsetof(NetPacket_Fixed<0x009e>, y) == 11"); +static_assert(offsetof(NetPacket_Fixed<0x009e>, subx) == 13, "offsetof(NetPacket_Fixed<0x009e>, subx) == 13"); +static_assert(offsetof(NetPacket_Fixed<0x009e>, suby) == 14, "offsetof(NetPacket_Fixed<0x009e>, suby) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x009e>, amount) == 15, "offsetof(NetPacket_Fixed<0x009e>, amount) == 15"); +static_assert(sizeof(NetPacket_Fixed<0x009e>) == 17, "sizeof(NetPacket_Fixed<0x009e>) == 17"); +static_assert(alignof(NetPacket_Fixed<0x009e>) == 1, "alignof(NetPacket_Fixed<0x009e>) == 1"); + +template<> +struct NetPacket_Fixed<0x009f> +{ + Little16 magic_packet_id; + Little32 object_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x009f>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x009f>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x009f>, object_id) == 2, "offsetof(NetPacket_Fixed<0x009f>, object_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x009f>) == 6, "sizeof(NetPacket_Fixed<0x009f>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x009f>) == 1, "alignof(NetPacket_Fixed<0x009f>) == 1"); + +template<> +struct NetPacket_Fixed<0x00a0> +{ + Little16 magic_packet_id; + Little16 ioff2; + Little16 amount; + Little16 name_id; + Byte identify; + Byte broken_or_attribute; + Byte refine; + Little16 card0; + Little16 card1; + Little16 card2; + Little16 card3; + Little16 epos; + Byte item_type; + Byte pickup_fail; +}; +static_assert(offsetof(NetPacket_Fixed<0x00a0>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00a0>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x00a0>, ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, amount) == 4, "offsetof(NetPacket_Fixed<0x00a0>, amount) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, name_id) == 6, "offsetof(NetPacket_Fixed<0x00a0>, name_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, identify) == 8, "offsetof(NetPacket_Fixed<0x00a0>, identify) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, broken_or_attribute) == 9, "offsetof(NetPacket_Fixed<0x00a0>, broken_or_attribute) == 9"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, refine) == 10, "offsetof(NetPacket_Fixed<0x00a0>, refine) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, card0) == 11, "offsetof(NetPacket_Fixed<0x00a0>, card0) == 11"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, card1) == 13, "offsetof(NetPacket_Fixed<0x00a0>, card1) == 13"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, card2) == 15, "offsetof(NetPacket_Fixed<0x00a0>, card2) == 15"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, card3) == 17, "offsetof(NetPacket_Fixed<0x00a0>, card3) == 17"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, epos) == 19, "offsetof(NetPacket_Fixed<0x00a0>, epos) == 19"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, item_type) == 21, "offsetof(NetPacket_Fixed<0x00a0>, item_type) == 21"); +static_assert(offsetof(NetPacket_Fixed<0x00a0>, pickup_fail) == 22, "offsetof(NetPacket_Fixed<0x00a0>, pickup_fail) == 22"); +static_assert(sizeof(NetPacket_Fixed<0x00a0>) == 23, "sizeof(NetPacket_Fixed<0x00a0>) == 23"); +static_assert(alignof(NetPacket_Fixed<0x00a0>) == 1, "alignof(NetPacket_Fixed<0x00a0>) == 1"); + +template<> +struct NetPacket_Fixed<0x00a1> +{ + Little16 magic_packet_id; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00a1>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00a1>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00a1>, block_id) == 2, "offsetof(NetPacket_Fixed<0x00a1>, block_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00a1>) == 6, "sizeof(NetPacket_Fixed<0x00a1>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00a1>) == 1, "alignof(NetPacket_Fixed<0x00a1>) == 1"); + +template<> +struct NetPacket_Fixed<0x00a2> +{ + Little16 magic_packet_id; + Little16 ioff2; + Little16 amount; +}; +static_assert(offsetof(NetPacket_Fixed<0x00a2>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00a2>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00a2>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x00a2>, ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00a2>, amount) == 4, "offsetof(NetPacket_Fixed<0x00a2>, amount) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00a2>) == 6, "sizeof(NetPacket_Fixed<0x00a2>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00a2>) == 1, "alignof(NetPacket_Fixed<0x00a2>) == 1"); + +template<> +struct NetPacket_Head<0x00a4> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x00a4>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x00a4>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x00a4>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x00a4>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x00a4>) == 4, "sizeof(NetPacket_Head<0x00a4>) == 4"); +static_assert(alignof(NetPacket_Head<0x00a4>) == 1, "alignof(NetPacket_Head<0x00a4>) == 1"); +template<> +struct NetPacket_Repeat<0x00a4> +{ + Little16 ioff2; + Little16 name_id; + Byte item_type; + Byte identify; + Little16 epos_pc; + Little16 epos_inv; + Byte broken_or_attribute; + Byte refine; + Little16 card0; + Little16 card1; + Little16 card2; + Little16 card3; +}; +static_assert(offsetof(NetPacket_Repeat<0x00a4>, ioff2) == 0, "offsetof(NetPacket_Repeat<0x00a4>, ioff2) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x00a4>, name_id) == 2, "offsetof(NetPacket_Repeat<0x00a4>, name_id) == 2"); +static_assert(offsetof(NetPacket_Repeat<0x00a4>, item_type) == 4, "offsetof(NetPacket_Repeat<0x00a4>, item_type) == 4"); +static_assert(offsetof(NetPacket_Repeat<0x00a4>, identify) == 5, "offsetof(NetPacket_Repeat<0x00a4>, identify) == 5"); +static_assert(offsetof(NetPacket_Repeat<0x00a4>, epos_pc) == 6, "offsetof(NetPacket_Repeat<0x00a4>, epos_pc) == 6"); +static_assert(offsetof(NetPacket_Repeat<0x00a4>, epos_inv) == 8, "offsetof(NetPacket_Repeat<0x00a4>, epos_inv) == 8"); +static_assert(offsetof(NetPacket_Repeat<0x00a4>, broken_or_attribute) == 10, "offsetof(NetPacket_Repeat<0x00a4>, broken_or_attribute) == 10"); +static_assert(offsetof(NetPacket_Repeat<0x00a4>, refine) == 11, "offsetof(NetPacket_Repeat<0x00a4>, refine) == 11"); +static_assert(offsetof(NetPacket_Repeat<0x00a4>, card0) == 12, "offsetof(NetPacket_Repeat<0x00a4>, card0) == 12"); +static_assert(offsetof(NetPacket_Repeat<0x00a4>, card1) == 14, "offsetof(NetPacket_Repeat<0x00a4>, card1) == 14"); +static_assert(offsetof(NetPacket_Repeat<0x00a4>, card2) == 16, "offsetof(NetPacket_Repeat<0x00a4>, card2) == 16"); +static_assert(offsetof(NetPacket_Repeat<0x00a4>, card3) == 18, "offsetof(NetPacket_Repeat<0x00a4>, card3) == 18"); +static_assert(sizeof(NetPacket_Repeat<0x00a4>) == 20, "sizeof(NetPacket_Repeat<0x00a4>) == 20"); +static_assert(alignof(NetPacket_Repeat<0x00a4>) == 1, "alignof(NetPacket_Repeat<0x00a4>) == 1"); + +template<> +struct NetPacket_Head<0x00a6> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x00a6>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x00a6>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x00a6>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x00a6>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x00a6>) == 4, "sizeof(NetPacket_Head<0x00a6>) == 4"); +static_assert(alignof(NetPacket_Head<0x00a6>) == 1, "alignof(NetPacket_Head<0x00a6>) == 1"); +template<> +struct NetPacket_Repeat<0x00a6> +{ + Little16 soff1; + Little16 name_id; + Byte item_type; + Byte identify; + Little16 epos_id; + Little16 epos_stor; + Byte broken_or_attribute; + Byte refine; + Little16 card0; + Little16 card1; + Little16 card2; + Little16 card3; +}; +static_assert(offsetof(NetPacket_Repeat<0x00a6>, soff1) == 0, "offsetof(NetPacket_Repeat<0x00a6>, soff1) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x00a6>, name_id) == 2, "offsetof(NetPacket_Repeat<0x00a6>, name_id) == 2"); +static_assert(offsetof(NetPacket_Repeat<0x00a6>, item_type) == 4, "offsetof(NetPacket_Repeat<0x00a6>, item_type) == 4"); +static_assert(offsetof(NetPacket_Repeat<0x00a6>, identify) == 5, "offsetof(NetPacket_Repeat<0x00a6>, identify) == 5"); +static_assert(offsetof(NetPacket_Repeat<0x00a6>, epos_id) == 6, "offsetof(NetPacket_Repeat<0x00a6>, epos_id) == 6"); +static_assert(offsetof(NetPacket_Repeat<0x00a6>, epos_stor) == 8, "offsetof(NetPacket_Repeat<0x00a6>, epos_stor) == 8"); +static_assert(offsetof(NetPacket_Repeat<0x00a6>, broken_or_attribute) == 10, "offsetof(NetPacket_Repeat<0x00a6>, broken_or_attribute) == 10"); +static_assert(offsetof(NetPacket_Repeat<0x00a6>, refine) == 11, "offsetof(NetPacket_Repeat<0x00a6>, refine) == 11"); +static_assert(offsetof(NetPacket_Repeat<0x00a6>, card0) == 12, "offsetof(NetPacket_Repeat<0x00a6>, card0) == 12"); +static_assert(offsetof(NetPacket_Repeat<0x00a6>, card1) == 14, "offsetof(NetPacket_Repeat<0x00a6>, card1) == 14"); +static_assert(offsetof(NetPacket_Repeat<0x00a6>, card2) == 16, "offsetof(NetPacket_Repeat<0x00a6>, card2) == 16"); +static_assert(offsetof(NetPacket_Repeat<0x00a6>, card3) == 18, "offsetof(NetPacket_Repeat<0x00a6>, card3) == 18"); +static_assert(sizeof(NetPacket_Repeat<0x00a6>) == 20, "sizeof(NetPacket_Repeat<0x00a6>) == 20"); +static_assert(alignof(NetPacket_Repeat<0x00a6>) == 1, "alignof(NetPacket_Repeat<0x00a6>) == 1"); + +template<> +struct NetPacket_Fixed<0x00a7> +{ + Little16 magic_packet_id; + Little16 ioff2; + Little32 unused_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00a7>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00a7>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00a7>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x00a7>, ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00a7>, unused_id) == 4, "offsetof(NetPacket_Fixed<0x00a7>, unused_id) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00a7>) == 8, "sizeof(NetPacket_Fixed<0x00a7>) == 8"); +static_assert(alignof(NetPacket_Fixed<0x00a7>) == 1, "alignof(NetPacket_Fixed<0x00a7>) == 1"); + +template<> +struct NetPacket_Fixed<0x00a8> +{ + Little16 magic_packet_id; + Little16 ioff2; + Little16 amount; + Byte ok; +}; +static_assert(offsetof(NetPacket_Fixed<0x00a8>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00a8>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00a8>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x00a8>, ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00a8>, amount) == 4, "offsetof(NetPacket_Fixed<0x00a8>, amount) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x00a8>, ok) == 6, "offsetof(NetPacket_Fixed<0x00a8>, ok) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x00a8>) == 7, "sizeof(NetPacket_Fixed<0x00a8>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x00a8>) == 1, "alignof(NetPacket_Fixed<0x00a8>) == 1"); + +template<> +struct NetPacket_Fixed<0x00a9> +{ + Little16 magic_packet_id; + Little16 ioff2; + Little16 epos_ignored; +}; +static_assert(offsetof(NetPacket_Fixed<0x00a9>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00a9>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00a9>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x00a9>, ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00a9>, epos_ignored) == 4, "offsetof(NetPacket_Fixed<0x00a9>, epos_ignored) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00a9>) == 6, "sizeof(NetPacket_Fixed<0x00a9>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00a9>) == 1, "alignof(NetPacket_Fixed<0x00a9>) == 1"); + +template<> +struct NetPacket_Fixed<0x00aa> +{ + Little16 magic_packet_id; + Little16 ioff2; + Little16 epos; + Byte ok; +}; +static_assert(offsetof(NetPacket_Fixed<0x00aa>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00aa>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00aa>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x00aa>, ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00aa>, epos) == 4, "offsetof(NetPacket_Fixed<0x00aa>, epos) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x00aa>, ok) == 6, "offsetof(NetPacket_Fixed<0x00aa>, ok) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x00aa>) == 7, "sizeof(NetPacket_Fixed<0x00aa>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x00aa>) == 1, "alignof(NetPacket_Fixed<0x00aa>) == 1"); + +template<> +struct NetPacket_Fixed<0x00ab> +{ + Little16 magic_packet_id; + Little16 ioff2; +}; +static_assert(offsetof(NetPacket_Fixed<0x00ab>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00ab>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00ab>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x00ab>, ioff2) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00ab>) == 4, "sizeof(NetPacket_Fixed<0x00ab>) == 4"); +static_assert(alignof(NetPacket_Fixed<0x00ab>) == 1, "alignof(NetPacket_Fixed<0x00ab>) == 1"); + +template<> +struct NetPacket_Fixed<0x00ac> +{ + Little16 magic_packet_id; + Little16 ioff2; + Little16 epos; + Byte ok; +}; +static_assert(offsetof(NetPacket_Fixed<0x00ac>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00ac>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00ac>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x00ac>, ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00ac>, epos) == 4, "offsetof(NetPacket_Fixed<0x00ac>, epos) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x00ac>, ok) == 6, "offsetof(NetPacket_Fixed<0x00ac>, ok) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x00ac>) == 7, "sizeof(NetPacket_Fixed<0x00ac>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x00ac>) == 1, "alignof(NetPacket_Fixed<0x00ac>) == 1"); + +template<> +struct NetPacket_Fixed<0x00af> +{ + Little16 magic_packet_id; + Little16 ioff2; + Little16 amount; +}; +static_assert(offsetof(NetPacket_Fixed<0x00af>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00af>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00af>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x00af>, ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00af>, amount) == 4, "offsetof(NetPacket_Fixed<0x00af>, amount) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00af>) == 6, "sizeof(NetPacket_Fixed<0x00af>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00af>) == 1, "alignof(NetPacket_Fixed<0x00af>) == 1"); + +template<> +struct NetPacket_Fixed<0x00b0> +{ + Little16 magic_packet_id; + Little16 sp_type; + Little32 value; +}; +static_assert(offsetof(NetPacket_Fixed<0x00b0>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00b0>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00b0>, sp_type) == 2, "offsetof(NetPacket_Fixed<0x00b0>, sp_type) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00b0>, value) == 4, "offsetof(NetPacket_Fixed<0x00b0>, value) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00b0>) == 8, "sizeof(NetPacket_Fixed<0x00b0>) == 8"); +static_assert(alignof(NetPacket_Fixed<0x00b0>) == 1, "alignof(NetPacket_Fixed<0x00b0>) == 1"); + +template<> +struct NetPacket_Fixed<0x00b1> +{ + Little16 magic_packet_id; + Little16 sp_type; + Little32 value; +}; +static_assert(offsetof(NetPacket_Fixed<0x00b1>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00b1>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00b1>, sp_type) == 2, "offsetof(NetPacket_Fixed<0x00b1>, sp_type) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00b1>, value) == 4, "offsetof(NetPacket_Fixed<0x00b1>, value) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00b1>) == 8, "sizeof(NetPacket_Fixed<0x00b1>) == 8"); +static_assert(alignof(NetPacket_Fixed<0x00b1>) == 1, "alignof(NetPacket_Fixed<0x00b1>) == 1"); + +template<> +struct NetPacket_Fixed<0x00b2> +{ + Little16 magic_packet_id; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x00b2>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00b2>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00b2>, flag) == 2, "offsetof(NetPacket_Fixed<0x00b2>, flag) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00b2>) == 3, "sizeof(NetPacket_Fixed<0x00b2>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x00b2>) == 1, "alignof(NetPacket_Fixed<0x00b2>) == 1"); + +template<> +struct NetPacket_Fixed<0x00b3> +{ + Little16 magic_packet_id; + Byte one; +}; +static_assert(offsetof(NetPacket_Fixed<0x00b3>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00b3>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00b3>, one) == 2, "offsetof(NetPacket_Fixed<0x00b3>, one) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00b3>) == 3, "sizeof(NetPacket_Fixed<0x00b3>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x00b3>) == 1, "alignof(NetPacket_Fixed<0x00b3>) == 1"); + +template<> +struct NetPacket_Head<0x00b4> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Head<0x00b4>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x00b4>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x00b4>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x00b4>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x00b4>, block_id) == 4, "offsetof(NetPacket_Head<0x00b4>, block_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x00b4>) == 8, "sizeof(NetPacket_Head<0x00b4>) == 8"); +static_assert(alignof(NetPacket_Head<0x00b4>) == 1, "alignof(NetPacket_Head<0x00b4>) == 1"); +template<> +struct NetPacket_Repeat<0x00b4> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x00b4>, c) == 0, "offsetof(NetPacket_Repeat<0x00b4>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x00b4>) == 1, "sizeof(NetPacket_Repeat<0x00b4>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x00b4>) == 1, "alignof(NetPacket_Repeat<0x00b4>) == 1"); + +template<> +struct NetPacket_Fixed<0x00b5> +{ + Little16 magic_packet_id; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00b5>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00b5>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00b5>, block_id) == 2, "offsetof(NetPacket_Fixed<0x00b5>, block_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00b5>) == 6, "sizeof(NetPacket_Fixed<0x00b5>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00b5>) == 1, "alignof(NetPacket_Fixed<0x00b5>) == 1"); + +template<> +struct NetPacket_Fixed<0x00b6> +{ + Little16 magic_packet_id; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00b6>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00b6>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00b6>, block_id) == 2, "offsetof(NetPacket_Fixed<0x00b6>, block_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00b6>) == 6, "sizeof(NetPacket_Fixed<0x00b6>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00b6>) == 1, "alignof(NetPacket_Fixed<0x00b6>) == 1"); + +template<> +struct NetPacket_Head<0x00b7> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Head<0x00b7>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x00b7>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x00b7>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x00b7>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x00b7>, block_id) == 4, "offsetof(NetPacket_Head<0x00b7>, block_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x00b7>) == 8, "sizeof(NetPacket_Head<0x00b7>) == 8"); +static_assert(alignof(NetPacket_Head<0x00b7>) == 1, "alignof(NetPacket_Head<0x00b7>) == 1"); +template<> +struct NetPacket_Repeat<0x00b7> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x00b7>, c) == 0, "offsetof(NetPacket_Repeat<0x00b7>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x00b7>) == 1, "sizeof(NetPacket_Repeat<0x00b7>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x00b7>) == 1, "alignof(NetPacket_Repeat<0x00b7>) == 1"); + +template<> +struct NetPacket_Fixed<0x00b8> +{ + Little16 magic_packet_id; + Little32 npc_id; + Byte menu_entry; +}; +static_assert(offsetof(NetPacket_Fixed<0x00b8>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00b8>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00b8>, npc_id) == 2, "offsetof(NetPacket_Fixed<0x00b8>, npc_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00b8>, menu_entry) == 6, "offsetof(NetPacket_Fixed<0x00b8>, menu_entry) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x00b8>) == 7, "sizeof(NetPacket_Fixed<0x00b8>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x00b8>) == 1, "alignof(NetPacket_Fixed<0x00b8>) == 1"); + +template<> +struct NetPacket_Fixed<0x00b9> +{ + Little16 magic_packet_id; + Little32 npc_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00b9>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00b9>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00b9>, npc_id) == 2, "offsetof(NetPacket_Fixed<0x00b9>, npc_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00b9>) == 6, "sizeof(NetPacket_Fixed<0x00b9>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00b9>) == 1, "alignof(NetPacket_Fixed<0x00b9>) == 1"); + +template<> +struct NetPacket_Fixed<0x00bb> +{ + Little16 magic_packet_id; + Little16 asp; + Byte unused; +}; +static_assert(offsetof(NetPacket_Fixed<0x00bb>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00bb>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00bb>, asp) == 2, "offsetof(NetPacket_Fixed<0x00bb>, asp) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00bb>, unused) == 4, "offsetof(NetPacket_Fixed<0x00bb>, unused) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00bb>) == 5, "sizeof(NetPacket_Fixed<0x00bb>) == 5"); +static_assert(alignof(NetPacket_Fixed<0x00bb>) == 1, "alignof(NetPacket_Fixed<0x00bb>) == 1"); + +template<> +struct NetPacket_Fixed<0x00bc> +{ + Little16 magic_packet_id; + Little16 sp_type; + Byte ok; + Byte val; +}; +static_assert(offsetof(NetPacket_Fixed<0x00bc>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00bc>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00bc>, sp_type) == 2, "offsetof(NetPacket_Fixed<0x00bc>, sp_type) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00bc>, ok) == 4, "offsetof(NetPacket_Fixed<0x00bc>, ok) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x00bc>, val) == 5, "offsetof(NetPacket_Fixed<0x00bc>, val) == 5"); +static_assert(sizeof(NetPacket_Fixed<0x00bc>) == 6, "sizeof(NetPacket_Fixed<0x00bc>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00bc>) == 1, "alignof(NetPacket_Fixed<0x00bc>) == 1"); + +template<> +struct NetPacket_Fixed<0x00bd> +{ + Little16 magic_packet_id; + Little16 status_point; + Byte str_attr; + Byte str_upd; + Byte agi_attr; + Byte agi_upd; + Byte vit_attr; + Byte vit_upd; + Byte int_attr; + Byte int_upd; + Byte dex_attr; + Byte dex_upd; + Byte luk_attr; + Byte luk_upd; + Little16 atk_sum; + Little16 watk2; + Little16 matk1; + Little16 matk2; + Little16 def; + Little16 def2; + Little16 mdef; + Little16 mdef2; + Little16 hit; + Little16 flee; + Little16 flee2; + Little16 critical; + Little16 karma; + Little16 manner; +}; +static_assert(offsetof(NetPacket_Fixed<0x00bd>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00bd>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, status_point) == 2, "offsetof(NetPacket_Fixed<0x00bd>, status_point) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, str_attr) == 4, "offsetof(NetPacket_Fixed<0x00bd>, str_attr) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, str_upd) == 5, "offsetof(NetPacket_Fixed<0x00bd>, str_upd) == 5"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, agi_attr) == 6, "offsetof(NetPacket_Fixed<0x00bd>, agi_attr) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, agi_upd) == 7, "offsetof(NetPacket_Fixed<0x00bd>, agi_upd) == 7"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, vit_attr) == 8, "offsetof(NetPacket_Fixed<0x00bd>, vit_attr) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, vit_upd) == 9, "offsetof(NetPacket_Fixed<0x00bd>, vit_upd) == 9"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, int_attr) == 10, "offsetof(NetPacket_Fixed<0x00bd>, int_attr) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, int_upd) == 11, "offsetof(NetPacket_Fixed<0x00bd>, int_upd) == 11"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, dex_attr) == 12, "offsetof(NetPacket_Fixed<0x00bd>, dex_attr) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, dex_upd) == 13, "offsetof(NetPacket_Fixed<0x00bd>, dex_upd) == 13"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, luk_attr) == 14, "offsetof(NetPacket_Fixed<0x00bd>, luk_attr) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, luk_upd) == 15, "offsetof(NetPacket_Fixed<0x00bd>, luk_upd) == 15"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, atk_sum) == 16, "offsetof(NetPacket_Fixed<0x00bd>, atk_sum) == 16"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, watk2) == 18, "offsetof(NetPacket_Fixed<0x00bd>, watk2) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, matk1) == 20, "offsetof(NetPacket_Fixed<0x00bd>, matk1) == 20"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, matk2) == 22, "offsetof(NetPacket_Fixed<0x00bd>, matk2) == 22"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, def) == 24, "offsetof(NetPacket_Fixed<0x00bd>, def) == 24"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, def2) == 26, "offsetof(NetPacket_Fixed<0x00bd>, def2) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, mdef) == 28, "offsetof(NetPacket_Fixed<0x00bd>, mdef) == 28"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, mdef2) == 30, "offsetof(NetPacket_Fixed<0x00bd>, mdef2) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, hit) == 32, "offsetof(NetPacket_Fixed<0x00bd>, hit) == 32"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, flee) == 34, "offsetof(NetPacket_Fixed<0x00bd>, flee) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, flee2) == 36, "offsetof(NetPacket_Fixed<0x00bd>, flee2) == 36"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, critical) == 38, "offsetof(NetPacket_Fixed<0x00bd>, critical) == 38"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, karma) == 40, "offsetof(NetPacket_Fixed<0x00bd>, karma) == 40"); +static_assert(offsetof(NetPacket_Fixed<0x00bd>, manner) == 42, "offsetof(NetPacket_Fixed<0x00bd>, manner) == 42"); +static_assert(sizeof(NetPacket_Fixed<0x00bd>) == 44, "sizeof(NetPacket_Fixed<0x00bd>) == 44"); +static_assert(alignof(NetPacket_Fixed<0x00bd>) == 1, "alignof(NetPacket_Fixed<0x00bd>) == 1"); + +template<> +struct NetPacket_Fixed<0x00be> +{ + Little16 magic_packet_id; + Little16 sp_type; + Byte value; +}; +static_assert(offsetof(NetPacket_Fixed<0x00be>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00be>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00be>, sp_type) == 2, "offsetof(NetPacket_Fixed<0x00be>, sp_type) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00be>, value) == 4, "offsetof(NetPacket_Fixed<0x00be>, value) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00be>) == 5, "sizeof(NetPacket_Fixed<0x00be>) == 5"); +static_assert(alignof(NetPacket_Fixed<0x00be>) == 1, "alignof(NetPacket_Fixed<0x00be>) == 1"); + +template<> +struct NetPacket_Fixed<0x00bf> +{ + Little16 magic_packet_id; + Byte emote; +}; +static_assert(offsetof(NetPacket_Fixed<0x00bf>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00bf>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00bf>, emote) == 2, "offsetof(NetPacket_Fixed<0x00bf>, emote) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00bf>) == 3, "sizeof(NetPacket_Fixed<0x00bf>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x00bf>) == 1, "alignof(NetPacket_Fixed<0x00bf>) == 1"); + +template<> +struct NetPacket_Fixed<0x00c0> +{ + Little16 magic_packet_id; + Little32 block_id; + Byte type; +}; +static_assert(offsetof(NetPacket_Fixed<0x00c0>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00c0>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00c0>, block_id) == 2, "offsetof(NetPacket_Fixed<0x00c0>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00c0>, type) == 6, "offsetof(NetPacket_Fixed<0x00c0>, type) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x00c0>) == 7, "sizeof(NetPacket_Fixed<0x00c0>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x00c0>) == 1, "alignof(NetPacket_Fixed<0x00c0>) == 1"); + +template<> +struct NetPacket_Fixed<0x00c1> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00c1>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00c1>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x00c1>) == 2, "sizeof(NetPacket_Fixed<0x00c1>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x00c1>) == 1, "alignof(NetPacket_Fixed<0x00c1>) == 1"); + +template<> +struct NetPacket_Fixed<0x00c2> +{ + Little16 magic_packet_id; + Little32 users; +}; +static_assert(offsetof(NetPacket_Fixed<0x00c2>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00c2>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00c2>, users) == 2, "offsetof(NetPacket_Fixed<0x00c2>, users) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00c2>) == 6, "sizeof(NetPacket_Fixed<0x00c2>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00c2>) == 1, "alignof(NetPacket_Fixed<0x00c2>) == 1"); + +template<> +struct NetPacket_Fixed<0x00c4> +{ + Little16 magic_packet_id; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00c4>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00c4>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00c4>, block_id) == 2, "offsetof(NetPacket_Fixed<0x00c4>, block_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00c4>) == 6, "sizeof(NetPacket_Fixed<0x00c4>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00c4>) == 1, "alignof(NetPacket_Fixed<0x00c4>) == 1"); + +template<> +struct NetPacket_Fixed<0x00c5> +{ + Little16 magic_packet_id; + Little32 block_id; + Byte type; +}; +static_assert(offsetof(NetPacket_Fixed<0x00c5>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00c5>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00c5>, block_id) == 2, "offsetof(NetPacket_Fixed<0x00c5>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00c5>, type) == 6, "offsetof(NetPacket_Fixed<0x00c5>, type) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x00c5>) == 7, "sizeof(NetPacket_Fixed<0x00c5>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x00c5>) == 1, "alignof(NetPacket_Fixed<0x00c5>) == 1"); + +template<> +struct NetPacket_Head<0x00c6> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x00c6>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x00c6>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x00c6>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x00c6>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x00c6>) == 4, "sizeof(NetPacket_Head<0x00c6>) == 4"); +static_assert(alignof(NetPacket_Head<0x00c6>) == 1, "alignof(NetPacket_Head<0x00c6>) == 1"); +template<> +struct NetPacket_Repeat<0x00c6> +{ + Little32 base_price; + Little32 actual_price; + Byte type; + Little16 name_id; +}; +static_assert(offsetof(NetPacket_Repeat<0x00c6>, base_price) == 0, "offsetof(NetPacket_Repeat<0x00c6>, base_price) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x00c6>, actual_price) == 4, "offsetof(NetPacket_Repeat<0x00c6>, actual_price) == 4"); +static_assert(offsetof(NetPacket_Repeat<0x00c6>, type) == 8, "offsetof(NetPacket_Repeat<0x00c6>, type) == 8"); +static_assert(offsetof(NetPacket_Repeat<0x00c6>, name_id) == 9, "offsetof(NetPacket_Repeat<0x00c6>, name_id) == 9"); +static_assert(sizeof(NetPacket_Repeat<0x00c6>) == 11, "sizeof(NetPacket_Repeat<0x00c6>) == 11"); +static_assert(alignof(NetPacket_Repeat<0x00c6>) == 1, "alignof(NetPacket_Repeat<0x00c6>) == 1"); + +template<> +struct NetPacket_Head<0x00c7> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x00c7>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x00c7>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x00c7>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x00c7>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x00c7>) == 4, "sizeof(NetPacket_Head<0x00c7>) == 4"); +static_assert(alignof(NetPacket_Head<0x00c7>) == 1, "alignof(NetPacket_Head<0x00c7>) == 1"); +template<> +struct NetPacket_Repeat<0x00c7> +{ + Little16 ioff2; + Little32 base_price; + Little32 actual_price; +}; +static_assert(offsetof(NetPacket_Repeat<0x00c7>, ioff2) == 0, "offsetof(NetPacket_Repeat<0x00c7>, ioff2) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x00c7>, base_price) == 2, "offsetof(NetPacket_Repeat<0x00c7>, base_price) == 2"); +static_assert(offsetof(NetPacket_Repeat<0x00c7>, actual_price) == 6, "offsetof(NetPacket_Repeat<0x00c7>, actual_price) == 6"); +static_assert(sizeof(NetPacket_Repeat<0x00c7>) == 10, "sizeof(NetPacket_Repeat<0x00c7>) == 10"); +static_assert(alignof(NetPacket_Repeat<0x00c7>) == 1, "alignof(NetPacket_Repeat<0x00c7>) == 1"); + +template<> +struct NetPacket_Head<0x00c8> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x00c8>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x00c8>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x00c8>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x00c8>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x00c8>) == 4, "sizeof(NetPacket_Head<0x00c8>) == 4"); +static_assert(alignof(NetPacket_Head<0x00c8>) == 1, "alignof(NetPacket_Head<0x00c8>) == 1"); +template<> +struct NetPacket_Repeat<0x00c8> +{ + Little16 count; + Little16 name_id; +}; +static_assert(offsetof(NetPacket_Repeat<0x00c8>, count) == 0, "offsetof(NetPacket_Repeat<0x00c8>, count) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x00c8>, name_id) == 2, "offsetof(NetPacket_Repeat<0x00c8>, name_id) == 2"); +static_assert(sizeof(NetPacket_Repeat<0x00c8>) == 4, "sizeof(NetPacket_Repeat<0x00c8>) == 4"); +static_assert(alignof(NetPacket_Repeat<0x00c8>) == 1, "alignof(NetPacket_Repeat<0x00c8>) == 1"); + +template<> +struct NetPacket_Head<0x00c9> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x00c9>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x00c9>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x00c9>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x00c9>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x00c9>) == 4, "sizeof(NetPacket_Head<0x00c9>) == 4"); +static_assert(alignof(NetPacket_Head<0x00c9>) == 1, "alignof(NetPacket_Head<0x00c9>) == 1"); +template<> +struct NetPacket_Repeat<0x00c9> +{ + Little16 ioff2; + Little16 count; +}; +static_assert(offsetof(NetPacket_Repeat<0x00c9>, ioff2) == 0, "offsetof(NetPacket_Repeat<0x00c9>, ioff2) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x00c9>, count) == 2, "offsetof(NetPacket_Repeat<0x00c9>, count) == 2"); +static_assert(sizeof(NetPacket_Repeat<0x00c9>) == 4, "sizeof(NetPacket_Repeat<0x00c9>) == 4"); +static_assert(alignof(NetPacket_Repeat<0x00c9>) == 1, "alignof(NetPacket_Repeat<0x00c9>) == 1"); + +template<> +struct NetPacket_Fixed<0x00ca> +{ + Little16 magic_packet_id; + Byte fail; +}; +static_assert(offsetof(NetPacket_Fixed<0x00ca>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00ca>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00ca>, fail) == 2, "offsetof(NetPacket_Fixed<0x00ca>, fail) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00ca>) == 3, "sizeof(NetPacket_Fixed<0x00ca>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x00ca>) == 1, "alignof(NetPacket_Fixed<0x00ca>) == 1"); + +template<> +struct NetPacket_Fixed<0x00cb> +{ + Little16 magic_packet_id; + Byte fail; +}; +static_assert(offsetof(NetPacket_Fixed<0x00cb>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00cb>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00cb>, fail) == 2, "offsetof(NetPacket_Fixed<0x00cb>, fail) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00cb>) == 3, "sizeof(NetPacket_Fixed<0x00cb>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x00cb>) == 1, "alignof(NetPacket_Fixed<0x00cb>) == 1"); + +template<> +struct NetPacket_Fixed<0x00cd> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00cd>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00cd>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00cd>, account_id) == 2, "offsetof(NetPacket_Fixed<0x00cd>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00cd>) == 6, "sizeof(NetPacket_Fixed<0x00cd>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00cd>) == 1, "alignof(NetPacket_Fixed<0x00cd>) == 1"); + +template<> +struct NetPacket_Fixed<0x00e4> +{ + Little16 magic_packet_id; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00e4>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00e4>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00e4>, block_id) == 2, "offsetof(NetPacket_Fixed<0x00e4>, block_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00e4>) == 6, "sizeof(NetPacket_Fixed<0x00e4>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00e4>) == 1, "alignof(NetPacket_Fixed<0x00e4>) == 1"); + +template<> +struct NetPacket_Fixed<0x00e5> +{ + Little16 magic_packet_id; + NetString<sizeof(CharName)> char_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x00e5>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00e5>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00e5>, char_name) == 2, "offsetof(NetPacket_Fixed<0x00e5>, char_name) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00e5>) == 26, "sizeof(NetPacket_Fixed<0x00e5>) == 26"); +static_assert(alignof(NetPacket_Fixed<0x00e5>) == 1, "alignof(NetPacket_Fixed<0x00e5>) == 1"); + +template<> +struct NetPacket_Fixed<0x00e6> +{ + Little16 magic_packet_id; + Byte type; +}; +static_assert(offsetof(NetPacket_Fixed<0x00e6>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00e6>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00e6>, type) == 2, "offsetof(NetPacket_Fixed<0x00e6>, type) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00e6>) == 3, "sizeof(NetPacket_Fixed<0x00e6>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x00e6>) == 1, "alignof(NetPacket_Fixed<0x00e6>) == 1"); + +template<> +struct NetPacket_Fixed<0x00e7> +{ + Little16 magic_packet_id; + Byte type; +}; +static_assert(offsetof(NetPacket_Fixed<0x00e7>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00e7>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00e7>, type) == 2, "offsetof(NetPacket_Fixed<0x00e7>, type) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00e7>) == 3, "sizeof(NetPacket_Fixed<0x00e7>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x00e7>) == 1, "alignof(NetPacket_Fixed<0x00e7>) == 1"); + +template<> +struct NetPacket_Fixed<0x00e8> +{ + Little16 magic_packet_id; + Little16 zeny_or_ioff2; + Little32 amount; +}; +static_assert(offsetof(NetPacket_Fixed<0x00e8>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00e8>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00e8>, zeny_or_ioff2) == 2, "offsetof(NetPacket_Fixed<0x00e8>, zeny_or_ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00e8>, amount) == 4, "offsetof(NetPacket_Fixed<0x00e8>, amount) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00e8>) == 8, "sizeof(NetPacket_Fixed<0x00e8>) == 8"); +static_assert(alignof(NetPacket_Fixed<0x00e8>) == 1, "alignof(NetPacket_Fixed<0x00e8>) == 1"); + +template<> +struct NetPacket_Fixed<0x00e9> +{ + Little16 magic_packet_id; + Little32 amount; + Little16 name_id; + Byte identify; + Byte broken_or_attribute; + Byte refine; + Little16 card0; + Little16 card1; + Little16 card2; + Little16 card3; +}; +static_assert(offsetof(NetPacket_Fixed<0x00e9>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00e9>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00e9>, amount) == 2, "offsetof(NetPacket_Fixed<0x00e9>, amount) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00e9>, name_id) == 6, "offsetof(NetPacket_Fixed<0x00e9>, name_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x00e9>, identify) == 8, "offsetof(NetPacket_Fixed<0x00e9>, identify) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x00e9>, broken_or_attribute) == 9, "offsetof(NetPacket_Fixed<0x00e9>, broken_or_attribute) == 9"); +static_assert(offsetof(NetPacket_Fixed<0x00e9>, refine) == 10, "offsetof(NetPacket_Fixed<0x00e9>, refine) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x00e9>, card0) == 11, "offsetof(NetPacket_Fixed<0x00e9>, card0) == 11"); +static_assert(offsetof(NetPacket_Fixed<0x00e9>, card1) == 13, "offsetof(NetPacket_Fixed<0x00e9>, card1) == 13"); +static_assert(offsetof(NetPacket_Fixed<0x00e9>, card2) == 15, "offsetof(NetPacket_Fixed<0x00e9>, card2) == 15"); +static_assert(offsetof(NetPacket_Fixed<0x00e9>, card3) == 17, "offsetof(NetPacket_Fixed<0x00e9>, card3) == 17"); +static_assert(sizeof(NetPacket_Fixed<0x00e9>) == 19, "sizeof(NetPacket_Fixed<0x00e9>) == 19"); +static_assert(alignof(NetPacket_Fixed<0x00e9>) == 1, "alignof(NetPacket_Fixed<0x00e9>) == 1"); + +template<> +struct NetPacket_Fixed<0x00eb> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00eb>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00eb>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x00eb>) == 2, "sizeof(NetPacket_Fixed<0x00eb>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x00eb>) == 1, "alignof(NetPacket_Fixed<0x00eb>) == 1"); + +template<> +struct NetPacket_Fixed<0x00ec> +{ + Little16 magic_packet_id; + Byte fail; +}; +static_assert(offsetof(NetPacket_Fixed<0x00ec>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00ec>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00ec>, fail) == 2, "offsetof(NetPacket_Fixed<0x00ec>, fail) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00ec>) == 3, "sizeof(NetPacket_Fixed<0x00ec>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x00ec>) == 1, "alignof(NetPacket_Fixed<0x00ec>) == 1"); + +template<> +struct NetPacket_Fixed<0x00ed> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00ed>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00ed>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x00ed>) == 2, "sizeof(NetPacket_Fixed<0x00ed>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x00ed>) == 1, "alignof(NetPacket_Fixed<0x00ed>) == 1"); + +template<> +struct NetPacket_Fixed<0x00ee> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00ee>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00ee>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x00ee>) == 2, "sizeof(NetPacket_Fixed<0x00ee>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x00ee>) == 1, "alignof(NetPacket_Fixed<0x00ee>) == 1"); + +template<> +struct NetPacket_Fixed<0x00ef> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00ef>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00ef>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x00ef>) == 2, "sizeof(NetPacket_Fixed<0x00ef>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x00ef>) == 1, "alignof(NetPacket_Fixed<0x00ef>) == 1"); + +template<> +struct NetPacket_Fixed<0x00f0> +{ + Little16 magic_packet_id; + Byte fail; +}; +static_assert(offsetof(NetPacket_Fixed<0x00f0>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00f0>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00f0>, fail) == 2, "offsetof(NetPacket_Fixed<0x00f0>, fail) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00f0>) == 3, "sizeof(NetPacket_Fixed<0x00f0>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x00f0>) == 1, "alignof(NetPacket_Fixed<0x00f0>) == 1"); + +template<> +struct NetPacket_Fixed<0x00f2> +{ + Little16 magic_packet_id; + Little16 current_slots; + Little16 max_slots; +}; +static_assert(offsetof(NetPacket_Fixed<0x00f2>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00f2>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00f2>, current_slots) == 2, "offsetof(NetPacket_Fixed<0x00f2>, current_slots) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00f2>, max_slots) == 4, "offsetof(NetPacket_Fixed<0x00f2>, max_slots) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00f2>) == 6, "sizeof(NetPacket_Fixed<0x00f2>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00f2>) == 1, "alignof(NetPacket_Fixed<0x00f2>) == 1"); + +template<> +struct NetPacket_Fixed<0x00f3> +{ + Little16 magic_packet_id; + Little16 ioff2; + Little32 amount; +}; +static_assert(offsetof(NetPacket_Fixed<0x00f3>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00f3>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00f3>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x00f3>, ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00f3>, amount) == 4, "offsetof(NetPacket_Fixed<0x00f3>, amount) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00f3>) == 8, "sizeof(NetPacket_Fixed<0x00f3>) == 8"); +static_assert(alignof(NetPacket_Fixed<0x00f3>) == 1, "alignof(NetPacket_Fixed<0x00f3>) == 1"); + +template<> +struct NetPacket_Fixed<0x00f4> +{ + Little16 magic_packet_id; + Little16 soff1; + Little32 amount; + Little16 name_id; + Byte identify; + Byte broken_or_attribute; + Byte refine; + Little16 card0; + Little16 card1; + Little16 card2; + Little16 card3; +}; +static_assert(offsetof(NetPacket_Fixed<0x00f4>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00f4>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00f4>, soff1) == 2, "offsetof(NetPacket_Fixed<0x00f4>, soff1) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00f4>, amount) == 4, "offsetof(NetPacket_Fixed<0x00f4>, amount) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x00f4>, name_id) == 8, "offsetof(NetPacket_Fixed<0x00f4>, name_id) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x00f4>, identify) == 10, "offsetof(NetPacket_Fixed<0x00f4>, identify) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x00f4>, broken_or_attribute) == 11, "offsetof(NetPacket_Fixed<0x00f4>, broken_or_attribute) == 11"); +static_assert(offsetof(NetPacket_Fixed<0x00f4>, refine) == 12, "offsetof(NetPacket_Fixed<0x00f4>, refine) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x00f4>, card0) == 13, "offsetof(NetPacket_Fixed<0x00f4>, card0) == 13"); +static_assert(offsetof(NetPacket_Fixed<0x00f4>, card1) == 15, "offsetof(NetPacket_Fixed<0x00f4>, card1) == 15"); +static_assert(offsetof(NetPacket_Fixed<0x00f4>, card2) == 17, "offsetof(NetPacket_Fixed<0x00f4>, card2) == 17"); +static_assert(offsetof(NetPacket_Fixed<0x00f4>, card3) == 19, "offsetof(NetPacket_Fixed<0x00f4>, card3) == 19"); +static_assert(sizeof(NetPacket_Fixed<0x00f4>) == 21, "sizeof(NetPacket_Fixed<0x00f4>) == 21"); +static_assert(alignof(NetPacket_Fixed<0x00f4>) == 1, "alignof(NetPacket_Fixed<0x00f4>) == 1"); + +template<> +struct NetPacket_Fixed<0x00f5> +{ + Little16 magic_packet_id; + Little16 soff1; + Little32 amount; +}; +static_assert(offsetof(NetPacket_Fixed<0x00f5>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00f5>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00f5>, soff1) == 2, "offsetof(NetPacket_Fixed<0x00f5>, soff1) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00f5>, amount) == 4, "offsetof(NetPacket_Fixed<0x00f5>, amount) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00f5>) == 8, "sizeof(NetPacket_Fixed<0x00f5>) == 8"); +static_assert(alignof(NetPacket_Fixed<0x00f5>) == 1, "alignof(NetPacket_Fixed<0x00f5>) == 1"); + +template<> +struct NetPacket_Fixed<0x00f6> +{ + Little16 magic_packet_id; + Little16 soff1; + Little32 amount; +}; +static_assert(offsetof(NetPacket_Fixed<0x00f6>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00f6>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00f6>, soff1) == 2, "offsetof(NetPacket_Fixed<0x00f6>, soff1) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00f6>, amount) == 4, "offsetof(NetPacket_Fixed<0x00f6>, amount) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x00f6>) == 8, "sizeof(NetPacket_Fixed<0x00f6>) == 8"); +static_assert(alignof(NetPacket_Fixed<0x00f6>) == 1, "alignof(NetPacket_Fixed<0x00f6>) == 1"); + +template<> +struct NetPacket_Fixed<0x00f7> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00f7>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00f7>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x00f7>) == 2, "sizeof(NetPacket_Fixed<0x00f7>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x00f7>) == 1, "alignof(NetPacket_Fixed<0x00f7>) == 1"); + +template<> +struct NetPacket_Fixed<0x00f8> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00f8>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00f8>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x00f8>) == 2, "sizeof(NetPacket_Fixed<0x00f8>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x00f8>) == 1, "alignof(NetPacket_Fixed<0x00f8>) == 1"); + +template<> +struct NetPacket_Fixed<0x00f9> +{ + Little16 magic_packet_id; + NetString<sizeof(PartyName)> party_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x00f9>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00f9>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00f9>, party_name) == 2, "offsetof(NetPacket_Fixed<0x00f9>, party_name) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00f9>) == 26, "sizeof(NetPacket_Fixed<0x00f9>) == 26"); +static_assert(alignof(NetPacket_Fixed<0x00f9>) == 1, "alignof(NetPacket_Fixed<0x00f9>) == 1"); + +template<> +struct NetPacket_Fixed<0x00fa> +{ + Little16 magic_packet_id; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x00fa>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00fa>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00fa>, flag) == 2, "offsetof(NetPacket_Fixed<0x00fa>, flag) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00fa>) == 3, "sizeof(NetPacket_Fixed<0x00fa>) == 3"); +static_assert(alignof(NetPacket_Fixed<0x00fa>) == 1, "alignof(NetPacket_Fixed<0x00fa>) == 1"); + +template<> +struct NetPacket_Head<0x00fb> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + NetString<sizeof(PartyName)> party_name; +}; +static_assert(offsetof(NetPacket_Head<0x00fb>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x00fb>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x00fb>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x00fb>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x00fb>, party_name) == 4, "offsetof(NetPacket_Head<0x00fb>, party_name) == 4"); +static_assert(sizeof(NetPacket_Head<0x00fb>) == 28, "sizeof(NetPacket_Head<0x00fb>) == 28"); +static_assert(alignof(NetPacket_Head<0x00fb>) == 1, "alignof(NetPacket_Head<0x00fb>) == 1"); +template<> +struct NetPacket_Repeat<0x00fb> +{ + Little32 account_id; + NetString<sizeof(CharName)> char_name; + NetString<sizeof(MapName)> map_name; + Byte leader; + Byte online; +}; +static_assert(offsetof(NetPacket_Repeat<0x00fb>, account_id) == 0, "offsetof(NetPacket_Repeat<0x00fb>, account_id) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x00fb>, char_name) == 4, "offsetof(NetPacket_Repeat<0x00fb>, char_name) == 4"); +static_assert(offsetof(NetPacket_Repeat<0x00fb>, map_name) == 28, "offsetof(NetPacket_Repeat<0x00fb>, map_name) == 28"); +static_assert(offsetof(NetPacket_Repeat<0x00fb>, leader) == 44, "offsetof(NetPacket_Repeat<0x00fb>, leader) == 44"); +static_assert(offsetof(NetPacket_Repeat<0x00fb>, online) == 45, "offsetof(NetPacket_Repeat<0x00fb>, online) == 45"); +static_assert(sizeof(NetPacket_Repeat<0x00fb>) == 46, "sizeof(NetPacket_Repeat<0x00fb>) == 46"); +static_assert(alignof(NetPacket_Repeat<0x00fb>) == 1, "alignof(NetPacket_Repeat<0x00fb>) == 1"); + +template<> +struct NetPacket_Fixed<0x00fc> +{ + Little16 magic_packet_id; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x00fc>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00fc>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00fc>, account_id) == 2, "offsetof(NetPacket_Fixed<0x00fc>, account_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x00fc>) == 6, "sizeof(NetPacket_Fixed<0x00fc>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x00fc>) == 1, "alignof(NetPacket_Fixed<0x00fc>) == 1"); + +template<> +struct NetPacket_Fixed<0x00fd> +{ + Little16 magic_packet_id; + NetString<sizeof(CharName)> char_name; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x00fd>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00fd>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00fd>, char_name) == 2, "offsetof(NetPacket_Fixed<0x00fd>, char_name) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00fd>, flag) == 26, "offsetof(NetPacket_Fixed<0x00fd>, flag) == 26"); +static_assert(sizeof(NetPacket_Fixed<0x00fd>) == 27, "sizeof(NetPacket_Fixed<0x00fd>) == 27"); +static_assert(alignof(NetPacket_Fixed<0x00fd>) == 1, "alignof(NetPacket_Fixed<0x00fd>) == 1"); + +template<> +struct NetPacket_Fixed<0x00fe> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(PartyName)> party_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x00fe>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00fe>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00fe>, account_id) == 2, "offsetof(NetPacket_Fixed<0x00fe>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00fe>, party_name) == 6, "offsetof(NetPacket_Fixed<0x00fe>, party_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x00fe>) == 30, "sizeof(NetPacket_Fixed<0x00fe>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x00fe>) == 1, "alignof(NetPacket_Fixed<0x00fe>) == 1"); + +template<> +struct NetPacket_Fixed<0x00ff> +{ + Little16 magic_packet_id; + Little32 account_id; + Little32 flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x00ff>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x00ff>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x00ff>, account_id) == 2, "offsetof(NetPacket_Fixed<0x00ff>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x00ff>, flag) == 6, "offsetof(NetPacket_Fixed<0x00ff>, flag) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x00ff>) == 10, "sizeof(NetPacket_Fixed<0x00ff>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x00ff>) == 1, "alignof(NetPacket_Fixed<0x00ff>) == 1"); + +template<> +struct NetPacket_Fixed<0x0100> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x0100>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0100>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x0100>) == 2, "sizeof(NetPacket_Fixed<0x0100>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x0100>) == 1, "alignof(NetPacket_Fixed<0x0100>) == 1"); + +template<> +struct NetPacket_Fixed<0x0101> +{ + Little16 magic_packet_id; + Little16 exp; + Little16 item; +}; +static_assert(offsetof(NetPacket_Fixed<0x0101>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0101>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0101>, exp) == 2, "offsetof(NetPacket_Fixed<0x0101>, exp) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0101>, item) == 4, "offsetof(NetPacket_Fixed<0x0101>, item) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x0101>) == 6, "sizeof(NetPacket_Fixed<0x0101>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x0101>) == 1, "alignof(NetPacket_Fixed<0x0101>) == 1"); + +template<> +struct NetPacket_Fixed<0x0102> +{ + Little16 magic_packet_id; + Little16 exp; + Little16 item; +}; +static_assert(offsetof(NetPacket_Fixed<0x0102>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0102>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0102>, exp) == 2, "offsetof(NetPacket_Fixed<0x0102>, exp) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0102>, item) == 4, "offsetof(NetPacket_Fixed<0x0102>, item) == 4"); +static_assert(sizeof(NetPacket_Fixed<0x0102>) == 6, "sizeof(NetPacket_Fixed<0x0102>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x0102>) == 1, "alignof(NetPacket_Fixed<0x0102>) == 1"); + +template<> +struct NetPacket_Fixed<0x0103> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(CharName)> unused_char_name; +}; +static_assert(offsetof(NetPacket_Fixed<0x0103>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0103>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0103>, account_id) == 2, "offsetof(NetPacket_Fixed<0x0103>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0103>, unused_char_name) == 6, "offsetof(NetPacket_Fixed<0x0103>, unused_char_name) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x0103>) == 30, "sizeof(NetPacket_Fixed<0x0103>) == 30"); +static_assert(alignof(NetPacket_Fixed<0x0103>) == 1, "alignof(NetPacket_Fixed<0x0103>) == 1"); + +template<> +struct NetPacket_Fixed<0x0105> +{ + Little16 magic_packet_id; + Little32 account_id; + NetString<sizeof(CharName)> char_name; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x0105>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0105>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0105>, account_id) == 2, "offsetof(NetPacket_Fixed<0x0105>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0105>, char_name) == 6, "offsetof(NetPacket_Fixed<0x0105>, char_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0105>, flag) == 30, "offsetof(NetPacket_Fixed<0x0105>, flag) == 30"); +static_assert(sizeof(NetPacket_Fixed<0x0105>) == 31, "sizeof(NetPacket_Fixed<0x0105>) == 31"); +static_assert(alignof(NetPacket_Fixed<0x0105>) == 1, "alignof(NetPacket_Fixed<0x0105>) == 1"); + +template<> +struct NetPacket_Fixed<0x0106> +{ + Little16 magic_packet_id; + Little32 account_id; + Little16 hp; + Little16 max_hp; +}; +static_assert(offsetof(NetPacket_Fixed<0x0106>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0106>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0106>, account_id) == 2, "offsetof(NetPacket_Fixed<0x0106>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0106>, hp) == 6, "offsetof(NetPacket_Fixed<0x0106>, hp) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0106>, max_hp) == 8, "offsetof(NetPacket_Fixed<0x0106>, max_hp) == 8"); +static_assert(sizeof(NetPacket_Fixed<0x0106>) == 10, "sizeof(NetPacket_Fixed<0x0106>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x0106>) == 1, "alignof(NetPacket_Fixed<0x0106>) == 1"); + +template<> +struct NetPacket_Fixed<0x0107> +{ + Little16 magic_packet_id; + Little32 account_id; + Little16 x; + Little16 y; +}; +static_assert(offsetof(NetPacket_Fixed<0x0107>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0107>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0107>, account_id) == 2, "offsetof(NetPacket_Fixed<0x0107>, account_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0107>, x) == 6, "offsetof(NetPacket_Fixed<0x0107>, x) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0107>, y) == 8, "offsetof(NetPacket_Fixed<0x0107>, y) == 8"); +static_assert(sizeof(NetPacket_Fixed<0x0107>) == 10, "sizeof(NetPacket_Fixed<0x0107>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x0107>) == 1, "alignof(NetPacket_Fixed<0x0107>) == 1"); + +template<> +struct NetPacket_Head<0x0108> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x0108>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x0108>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x0108>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x0108>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x0108>) == 4, "sizeof(NetPacket_Head<0x0108>) == 4"); +static_assert(alignof(NetPacket_Head<0x0108>) == 1, "alignof(NetPacket_Head<0x0108>) == 1"); +template<> +struct NetPacket_Repeat<0x0108> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x0108>, c) == 0, "offsetof(NetPacket_Repeat<0x0108>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x0108>) == 1, "sizeof(NetPacket_Repeat<0x0108>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x0108>) == 1, "alignof(NetPacket_Repeat<0x0108>) == 1"); + +template<> +struct NetPacket_Head<0x0109> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 account_id; +}; +static_assert(offsetof(NetPacket_Head<0x0109>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x0109>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x0109>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x0109>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x0109>, account_id) == 4, "offsetof(NetPacket_Head<0x0109>, account_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x0109>) == 8, "sizeof(NetPacket_Head<0x0109>) == 8"); +static_assert(alignof(NetPacket_Head<0x0109>) == 1, "alignof(NetPacket_Head<0x0109>) == 1"); +template<> +struct NetPacket_Repeat<0x0109> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x0109>, c) == 0, "offsetof(NetPacket_Repeat<0x0109>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x0109>) == 1, "sizeof(NetPacket_Repeat<0x0109>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x0109>) == 1, "alignof(NetPacket_Repeat<0x0109>) == 1"); + +template<> +struct NetPacket_Fixed<0x010c> +{ + Little16 magic_packet_id; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x010c>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x010c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x010c>, block_id) == 2, "offsetof(NetPacket_Fixed<0x010c>, block_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x010c>) == 6, "sizeof(NetPacket_Fixed<0x010c>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x010c>) == 1, "alignof(NetPacket_Fixed<0x010c>) == 1"); + +template<> +struct NetPacket_Fixed<0x010e> +{ + Little16 magic_packet_id; + Little16 skill_id; + Little16 level; + Little16 sp; + Little16 range; + Byte can_raise; +}; +static_assert(offsetof(NetPacket_Fixed<0x010e>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x010e>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x010e>, skill_id) == 2, "offsetof(NetPacket_Fixed<0x010e>, skill_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x010e>, level) == 4, "offsetof(NetPacket_Fixed<0x010e>, level) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x010e>, sp) == 6, "offsetof(NetPacket_Fixed<0x010e>, sp) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x010e>, range) == 8, "offsetof(NetPacket_Fixed<0x010e>, range) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x010e>, can_raise) == 10, "offsetof(NetPacket_Fixed<0x010e>, can_raise) == 10"); +static_assert(sizeof(NetPacket_Fixed<0x010e>) == 11, "sizeof(NetPacket_Fixed<0x010e>) == 11"); +static_assert(alignof(NetPacket_Fixed<0x010e>) == 1, "alignof(NetPacket_Fixed<0x010e>) == 1"); + +template<> +struct NetPacket_Head<0x010f> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x010f>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x010f>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x010f>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x010f>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x010f>) == 4, "sizeof(NetPacket_Head<0x010f>) == 4"); +static_assert(alignof(NetPacket_Head<0x010f>) == 1, "alignof(NetPacket_Head<0x010f>) == 1"); +template<> +struct NetPacket_Repeat<0x010f> +{ + NetSkillInfo info; +}; +static_assert(offsetof(NetPacket_Repeat<0x010f>, info) == 0, "offsetof(NetPacket_Repeat<0x010f>, info) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x010f>) == 37, "sizeof(NetPacket_Repeat<0x010f>) == 37"); +static_assert(alignof(NetPacket_Repeat<0x010f>) == 1, "alignof(NetPacket_Repeat<0x010f>) == 1"); + +template<> +struct NetPacket_Fixed<0x0110> +{ + Little16 magic_packet_id; + Little16 skill_id; + Little16 btype; + Little16 zero1; + Byte zero2; + Byte type; +}; +static_assert(offsetof(NetPacket_Fixed<0x0110>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0110>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0110>, skill_id) == 2, "offsetof(NetPacket_Fixed<0x0110>, skill_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0110>, btype) == 4, "offsetof(NetPacket_Fixed<0x0110>, btype) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x0110>, zero1) == 6, "offsetof(NetPacket_Fixed<0x0110>, zero1) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0110>, zero2) == 8, "offsetof(NetPacket_Fixed<0x0110>, zero2) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x0110>, type) == 9, "offsetof(NetPacket_Fixed<0x0110>, type) == 9"); +static_assert(sizeof(NetPacket_Fixed<0x0110>) == 10, "sizeof(NetPacket_Fixed<0x0110>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x0110>) == 1, "alignof(NetPacket_Fixed<0x0110>) == 1"); + +template<> +struct NetPacket_Fixed<0x0112> +{ + Little16 magic_packet_id; + Little16 skill_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x0112>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0112>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0112>, skill_id) == 2, "offsetof(NetPacket_Fixed<0x0112>, skill_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0112>) == 4, "sizeof(NetPacket_Fixed<0x0112>) == 4"); +static_assert(alignof(NetPacket_Fixed<0x0112>) == 1, "alignof(NetPacket_Fixed<0x0112>) == 1"); + +template<> +struct NetPacket_Fixed<0x0118> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x0118>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0118>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x0118>) == 2, "sizeof(NetPacket_Fixed<0x0118>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x0118>) == 1, "alignof(NetPacket_Fixed<0x0118>) == 1"); + +template<> +struct NetPacket_Fixed<0x0119> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 opt1; + Little16 opt2; + Little16 option; + Byte zero; +}; +static_assert(offsetof(NetPacket_Fixed<0x0119>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0119>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0119>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0119>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0119>, opt1) == 6, "offsetof(NetPacket_Fixed<0x0119>, opt1) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0119>, opt2) == 8, "offsetof(NetPacket_Fixed<0x0119>, opt2) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x0119>, option) == 10, "offsetof(NetPacket_Fixed<0x0119>, option) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x0119>, zero) == 12, "offsetof(NetPacket_Fixed<0x0119>, zero) == 12"); +static_assert(sizeof(NetPacket_Fixed<0x0119>) == 13, "sizeof(NetPacket_Fixed<0x0119>) == 13"); +static_assert(alignof(NetPacket_Fixed<0x0119>) == 1, "alignof(NetPacket_Fixed<0x0119>) == 1"); + +template<> +struct NetPacket_Fixed<0x0139> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 bl_x; + Little16 bl_y; + Little16 sd_x; + Little16 sd_y; + Little16 range; +}; +static_assert(offsetof(NetPacket_Fixed<0x0139>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0139>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0139>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0139>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0139>, bl_x) == 6, "offsetof(NetPacket_Fixed<0x0139>, bl_x) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0139>, bl_y) == 8, "offsetof(NetPacket_Fixed<0x0139>, bl_y) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x0139>, sd_x) == 10, "offsetof(NetPacket_Fixed<0x0139>, sd_x) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x0139>, sd_y) == 12, "offsetof(NetPacket_Fixed<0x0139>, sd_y) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x0139>, range) == 14, "offsetof(NetPacket_Fixed<0x0139>, range) == 14"); +static_assert(sizeof(NetPacket_Fixed<0x0139>) == 16, "sizeof(NetPacket_Fixed<0x0139>) == 16"); +static_assert(alignof(NetPacket_Fixed<0x0139>) == 1, "alignof(NetPacket_Fixed<0x0139>) == 1"); + +template<> +struct NetPacket_Fixed<0x013a> +{ + Little16 magic_packet_id; + Little16 attack_range; +}; +static_assert(offsetof(NetPacket_Fixed<0x013a>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x013a>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x013a>, attack_range) == 2, "offsetof(NetPacket_Fixed<0x013a>, attack_range) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x013a>) == 4, "sizeof(NetPacket_Fixed<0x013a>) == 4"); +static_assert(alignof(NetPacket_Fixed<0x013a>) == 1, "alignof(NetPacket_Fixed<0x013a>) == 1"); + +template<> +struct NetPacket_Fixed<0x013b> +{ + Little16 magic_packet_id; + Little16 type; +}; +static_assert(offsetof(NetPacket_Fixed<0x013b>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x013b>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x013b>, type) == 2, "offsetof(NetPacket_Fixed<0x013b>, type) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x013b>) == 4, "sizeof(NetPacket_Fixed<0x013b>) == 4"); +static_assert(alignof(NetPacket_Fixed<0x013b>) == 1, "alignof(NetPacket_Fixed<0x013b>) == 1"); + +template<> +struct NetPacket_Fixed<0x013c> +{ + Little16 magic_packet_id; + Little16 ioff2; +}; +static_assert(offsetof(NetPacket_Fixed<0x013c>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x013c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x013c>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x013c>, ioff2) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x013c>) == 4, "sizeof(NetPacket_Fixed<0x013c>) == 4"); +static_assert(alignof(NetPacket_Fixed<0x013c>) == 1, "alignof(NetPacket_Fixed<0x013c>) == 1"); + +template<> +struct NetPacket_Fixed<0x0141> +{ + Little16 magic_packet_id; + Little16 sp_type; + Little16 zero; + Little32 value_status; + Little32 value_b_e; +}; +static_assert(offsetof(NetPacket_Fixed<0x0141>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0141>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0141>, sp_type) == 2, "offsetof(NetPacket_Fixed<0x0141>, sp_type) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0141>, zero) == 4, "offsetof(NetPacket_Fixed<0x0141>, zero) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x0141>, value_status) == 6, "offsetof(NetPacket_Fixed<0x0141>, value_status) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0141>, value_b_e) == 10, "offsetof(NetPacket_Fixed<0x0141>, value_b_e) == 10"); +static_assert(sizeof(NetPacket_Fixed<0x0141>) == 14, "sizeof(NetPacket_Fixed<0x0141>) == 14"); +static_assert(alignof(NetPacket_Fixed<0x0141>) == 1, "alignof(NetPacket_Fixed<0x0141>) == 1"); + +template<> +struct NetPacket_Fixed<0x0142> +{ + Little16 magic_packet_id; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x0142>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0142>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0142>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0142>, block_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0142>) == 6, "sizeof(NetPacket_Fixed<0x0142>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x0142>) == 1, "alignof(NetPacket_Fixed<0x0142>) == 1"); + +template<> +struct NetPacket_Fixed<0x0143> +{ + Little16 magic_packet_id; + Little32 block_id; + Little32 input_int_value; +}; +static_assert(offsetof(NetPacket_Fixed<0x0143>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0143>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0143>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0143>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0143>, input_int_value) == 6, "offsetof(NetPacket_Fixed<0x0143>, input_int_value) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x0143>) == 10, "sizeof(NetPacket_Fixed<0x0143>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x0143>) == 1, "alignof(NetPacket_Fixed<0x0143>) == 1"); + +template<> +struct NetPacket_Fixed<0x0146> +{ + Little16 magic_packet_id; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x0146>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0146>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0146>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0146>, block_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0146>) == 6, "sizeof(NetPacket_Fixed<0x0146>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x0146>) == 1, "alignof(NetPacket_Fixed<0x0146>) == 1"); + +template<> +struct NetPacket_Fixed<0x0147> +{ + Little16 magic_packet_id; + NetSkillInfo info; +}; +static_assert(offsetof(NetPacket_Fixed<0x0147>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0147>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0147>, info) == 2, "offsetof(NetPacket_Fixed<0x0147>, info) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x0147>) == 39, "sizeof(NetPacket_Fixed<0x0147>) == 39"); +static_assert(alignof(NetPacket_Fixed<0x0147>) == 1, "alignof(NetPacket_Fixed<0x0147>) == 1"); + +template<> +struct NetPacket_Fixed<0x0148> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 type; +}; +static_assert(offsetof(NetPacket_Fixed<0x0148>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0148>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0148>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0148>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0148>, type) == 6, "offsetof(NetPacket_Fixed<0x0148>, type) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x0148>) == 8, "sizeof(NetPacket_Fixed<0x0148>) == 8"); +static_assert(alignof(NetPacket_Fixed<0x0148>) == 1, "alignof(NetPacket_Fixed<0x0148>) == 1"); + +template<> +struct NetPacket_Fixed<0x014d> +{ + Little16 magic_packet_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x014d>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x014d>, magic_packet_id) == 0"); +static_assert(sizeof(NetPacket_Fixed<0x014d>) == 2, "sizeof(NetPacket_Fixed<0x014d>) == 2"); +static_assert(alignof(NetPacket_Fixed<0x014d>) == 1, "alignof(NetPacket_Fixed<0x014d>) == 1"); + +template<> +struct NetPacket_Fixed<0x018a> +{ + Little16 magic_packet_id; + Little16 unused; +}; +static_assert(offsetof(NetPacket_Fixed<0x018a>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x018a>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x018a>, unused) == 2, "offsetof(NetPacket_Fixed<0x018a>, unused) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x018a>) == 4, "sizeof(NetPacket_Fixed<0x018a>) == 4"); +static_assert(alignof(NetPacket_Fixed<0x018a>) == 1, "alignof(NetPacket_Fixed<0x018a>) == 1"); + +template<> +struct NetPacket_Fixed<0x018b> +{ + Little16 magic_packet_id; + Little16 okay; +}; +static_assert(offsetof(NetPacket_Fixed<0x018b>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x018b>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x018b>, okay) == 2, "offsetof(NetPacket_Fixed<0x018b>, okay) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x018b>) == 4, "sizeof(NetPacket_Fixed<0x018b>) == 4"); +static_assert(alignof(NetPacket_Fixed<0x018b>) == 1, "alignof(NetPacket_Fixed<0x018b>) == 1"); + +template<> +struct NetPacket_Fixed<0x0195> +{ + Little16 magic_packet_id; + Little32 block_id; + NetString<sizeof(PartyName)> party_name; + NetString<sizeof(VString<23>)> guild_name; + NetString<sizeof(VString<23>)> guild_pos; + NetString<sizeof(VString<23>)> guild_pos_again; +}; +static_assert(offsetof(NetPacket_Fixed<0x0195>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0195>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0195>, block_id) == 2, "offsetof(NetPacket_Fixed<0x0195>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0195>, party_name) == 6, "offsetof(NetPacket_Fixed<0x0195>, party_name) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0195>, guild_name) == 30, "offsetof(NetPacket_Fixed<0x0195>, guild_name) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x0195>, guild_pos) == 54, "offsetof(NetPacket_Fixed<0x0195>, guild_pos) == 54"); +static_assert(offsetof(NetPacket_Fixed<0x0195>, guild_pos_again) == 78, "offsetof(NetPacket_Fixed<0x0195>, guild_pos_again) == 78"); +static_assert(sizeof(NetPacket_Fixed<0x0195>) == 102, "sizeof(NetPacket_Fixed<0x0195>) == 102"); +static_assert(alignof(NetPacket_Fixed<0x0195>) == 1, "alignof(NetPacket_Fixed<0x0195>) == 1"); + +template<> +struct NetPacket_Fixed<0x0196> +{ + Little16 magic_packet_id; + Little16 sc_type; + Little32 block_id; + Byte flag; +}; +static_assert(offsetof(NetPacket_Fixed<0x0196>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0196>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0196>, sc_type) == 2, "offsetof(NetPacket_Fixed<0x0196>, sc_type) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0196>, block_id) == 4, "offsetof(NetPacket_Fixed<0x0196>, block_id) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x0196>, flag) == 8, "offsetof(NetPacket_Fixed<0x0196>, flag) == 8"); +static_assert(sizeof(NetPacket_Fixed<0x0196>) == 9, "sizeof(NetPacket_Fixed<0x0196>) == 9"); +static_assert(alignof(NetPacket_Fixed<0x0196>) == 1, "alignof(NetPacket_Fixed<0x0196>) == 1"); + +template<> +struct NetPacket_Fixed<0x019b> +{ + Little16 magic_packet_id; + Little32 block_id; + Little32 type; +}; +static_assert(offsetof(NetPacket_Fixed<0x019b>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x019b>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x019b>, block_id) == 2, "offsetof(NetPacket_Fixed<0x019b>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x019b>, type) == 6, "offsetof(NetPacket_Fixed<0x019b>, type) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x019b>) == 10, "sizeof(NetPacket_Fixed<0x019b>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x019b>) == 1, "alignof(NetPacket_Fixed<0x019b>) == 1"); + +template<> +struct NetPacket_Fixed<0x01b1> +{ + Little16 magic_packet_id; + Little16 ioff2; + Little16 amount; + Byte fail; +}; +static_assert(offsetof(NetPacket_Fixed<0x01b1>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x01b1>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x01b1>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x01b1>, ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x01b1>, amount) == 4, "offsetof(NetPacket_Fixed<0x01b1>, amount) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x01b1>, fail) == 6, "offsetof(NetPacket_Fixed<0x01b1>, fail) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x01b1>) == 7, "sizeof(NetPacket_Fixed<0x01b1>) == 7"); +static_assert(alignof(NetPacket_Fixed<0x01b1>) == 1, "alignof(NetPacket_Fixed<0x01b1>) == 1"); + +template<> +struct NetPacket_Fixed<0x01c8> +{ + Little16 magic_packet_id; + Little16 ioff2; + Little16 name_id; + Little32 block_id; + Little16 amount; + Byte ok; +}; +static_assert(offsetof(NetPacket_Fixed<0x01c8>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x01c8>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x01c8>, ioff2) == 2, "offsetof(NetPacket_Fixed<0x01c8>, ioff2) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x01c8>, name_id) == 4, "offsetof(NetPacket_Fixed<0x01c8>, name_id) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x01c8>, block_id) == 6, "offsetof(NetPacket_Fixed<0x01c8>, block_id) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x01c8>, amount) == 10, "offsetof(NetPacket_Fixed<0x01c8>, amount) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x01c8>, ok) == 12, "offsetof(NetPacket_Fixed<0x01c8>, ok) == 12"); +static_assert(sizeof(NetPacket_Fixed<0x01c8>) == 13, "sizeof(NetPacket_Fixed<0x01c8>) == 13"); +static_assert(alignof(NetPacket_Fixed<0x01c8>) == 1, "alignof(NetPacket_Fixed<0x01c8>) == 1"); + +template<> +struct NetPacket_Fixed<0x01d4> +{ + Little16 magic_packet_id; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Fixed<0x01d4>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x01d4>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x01d4>, block_id) == 2, "offsetof(NetPacket_Fixed<0x01d4>, block_id) == 2"); +static_assert(sizeof(NetPacket_Fixed<0x01d4>) == 6, "sizeof(NetPacket_Fixed<0x01d4>) == 6"); +static_assert(alignof(NetPacket_Fixed<0x01d4>) == 1, "alignof(NetPacket_Fixed<0x01d4>) == 1"); + +template<> +struct NetPacket_Head<0x01d5> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; + Little32 block_id; +}; +static_assert(offsetof(NetPacket_Head<0x01d5>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x01d5>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x01d5>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x01d5>, magic_packet_length) == 2"); +static_assert(offsetof(NetPacket_Head<0x01d5>, block_id) == 4, "offsetof(NetPacket_Head<0x01d5>, block_id) == 4"); +static_assert(sizeof(NetPacket_Head<0x01d5>) == 8, "sizeof(NetPacket_Head<0x01d5>) == 8"); +static_assert(alignof(NetPacket_Head<0x01d5>) == 1, "alignof(NetPacket_Head<0x01d5>) == 1"); +template<> +struct NetPacket_Repeat<0x01d5> +{ + Byte c; +}; +static_assert(offsetof(NetPacket_Repeat<0x01d5>, c) == 0, "offsetof(NetPacket_Repeat<0x01d5>, c) == 0"); +static_assert(sizeof(NetPacket_Repeat<0x01d5>) == 1, "sizeof(NetPacket_Repeat<0x01d5>) == 1"); +static_assert(alignof(NetPacket_Repeat<0x01d5>) == 1, "alignof(NetPacket_Repeat<0x01d5>) == 1"); + +template<> +struct NetPacket_Fixed<0x01d7> +{ + Little16 magic_packet_id; + Little32 block_id; + Byte look_type; + Little16 weapon_or_name_id_or_value; + Little16 shield; +}; +static_assert(offsetof(NetPacket_Fixed<0x01d7>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x01d7>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x01d7>, block_id) == 2, "offsetof(NetPacket_Fixed<0x01d7>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x01d7>, look_type) == 6, "offsetof(NetPacket_Fixed<0x01d7>, look_type) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x01d7>, weapon_or_name_id_or_value) == 7, "offsetof(NetPacket_Fixed<0x01d7>, weapon_or_name_id_or_value) == 7"); +static_assert(offsetof(NetPacket_Fixed<0x01d7>, shield) == 9, "offsetof(NetPacket_Fixed<0x01d7>, shield) == 9"); +static_assert(sizeof(NetPacket_Fixed<0x01d7>) == 11, "sizeof(NetPacket_Fixed<0x01d7>) == 11"); +static_assert(alignof(NetPacket_Fixed<0x01d7>) == 1, "alignof(NetPacket_Fixed<0x01d7>) == 1"); + +template<> +struct NetPacket_Fixed<0x01d8> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 speed; + Little16 opt1; + Little16 opt2; + Little16 option; + Little16 species; + Little16 hair_style; + Little16 weapon; + Little16 shield; + Little16 head_bottom; + Little16 head_top; + Little16 head_mid; + Little16 hair_color; + Little16 clothes_color; + Byte head_dir; + Byte unused2; + Little32 guild_id; + Little16 guild_emblem_id; + Little16 manner; + Little16 opt3; + Byte karma; + Byte sex; + NetPosition1 pos; + Little16 gm_bits; + Byte dead_sit; + Little16 unused; +}; +static_assert(offsetof(NetPacket_Fixed<0x01d8>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x01d8>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, block_id) == 2, "offsetof(NetPacket_Fixed<0x01d8>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, speed) == 6, "offsetof(NetPacket_Fixed<0x01d8>, speed) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, opt1) == 8, "offsetof(NetPacket_Fixed<0x01d8>, opt1) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, opt2) == 10, "offsetof(NetPacket_Fixed<0x01d8>, opt2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, option) == 12, "offsetof(NetPacket_Fixed<0x01d8>, option) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, species) == 14, "offsetof(NetPacket_Fixed<0x01d8>, species) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, hair_style) == 16, "offsetof(NetPacket_Fixed<0x01d8>, hair_style) == 16"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, weapon) == 18, "offsetof(NetPacket_Fixed<0x01d8>, weapon) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, shield) == 20, "offsetof(NetPacket_Fixed<0x01d8>, shield) == 20"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, head_bottom) == 22, "offsetof(NetPacket_Fixed<0x01d8>, head_bottom) == 22"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, head_top) == 24, "offsetof(NetPacket_Fixed<0x01d8>, head_top) == 24"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, head_mid) == 26, "offsetof(NetPacket_Fixed<0x01d8>, head_mid) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, hair_color) == 28, "offsetof(NetPacket_Fixed<0x01d8>, hair_color) == 28"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, clothes_color) == 30, "offsetof(NetPacket_Fixed<0x01d8>, clothes_color) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, head_dir) == 32, "offsetof(NetPacket_Fixed<0x01d8>, head_dir) == 32"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, unused2) == 33, "offsetof(NetPacket_Fixed<0x01d8>, unused2) == 33"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, guild_id) == 34, "offsetof(NetPacket_Fixed<0x01d8>, guild_id) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, guild_emblem_id) == 38, "offsetof(NetPacket_Fixed<0x01d8>, guild_emblem_id) == 38"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, manner) == 40, "offsetof(NetPacket_Fixed<0x01d8>, manner) == 40"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, opt3) == 42, "offsetof(NetPacket_Fixed<0x01d8>, opt3) == 42"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, karma) == 44, "offsetof(NetPacket_Fixed<0x01d8>, karma) == 44"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, sex) == 45, "offsetof(NetPacket_Fixed<0x01d8>, sex) == 45"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, pos) == 46, "offsetof(NetPacket_Fixed<0x01d8>, pos) == 46"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, gm_bits) == 49, "offsetof(NetPacket_Fixed<0x01d8>, gm_bits) == 49"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, dead_sit) == 51, "offsetof(NetPacket_Fixed<0x01d8>, dead_sit) == 51"); +static_assert(offsetof(NetPacket_Fixed<0x01d8>, unused) == 52, "offsetof(NetPacket_Fixed<0x01d8>, unused) == 52"); +static_assert(sizeof(NetPacket_Fixed<0x01d8>) == 54, "sizeof(NetPacket_Fixed<0x01d8>) == 54"); +static_assert(alignof(NetPacket_Fixed<0x01d8>) == 1, "alignof(NetPacket_Fixed<0x01d8>) == 1"); + +template<> +struct NetPacket_Fixed<0x01d9> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 speed; + Little16 opt1; + Little16 opt2; + Little16 option; + Little16 species; + Little16 hair_style; + Little16 weapon; + Little16 shield; + Little16 head_bottom; + Little16 head_top; + Little16 head_mid; + Little16 hair_color; + Little16 clothes_color; + Byte head_dir; + Byte unused2; + Little32 guild_id; + Little16 guild_emblem_id; + Little16 manner; + Little16 opt3; + Byte karma; + Byte sex; + NetPosition1 pos; + Little16 gm_bits; + Little16 unused; +}; +static_assert(offsetof(NetPacket_Fixed<0x01d9>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x01d9>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, block_id) == 2, "offsetof(NetPacket_Fixed<0x01d9>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, speed) == 6, "offsetof(NetPacket_Fixed<0x01d9>, speed) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, opt1) == 8, "offsetof(NetPacket_Fixed<0x01d9>, opt1) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, opt2) == 10, "offsetof(NetPacket_Fixed<0x01d9>, opt2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, option) == 12, "offsetof(NetPacket_Fixed<0x01d9>, option) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, species) == 14, "offsetof(NetPacket_Fixed<0x01d9>, species) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, hair_style) == 16, "offsetof(NetPacket_Fixed<0x01d9>, hair_style) == 16"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, weapon) == 18, "offsetof(NetPacket_Fixed<0x01d9>, weapon) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, shield) == 20, "offsetof(NetPacket_Fixed<0x01d9>, shield) == 20"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, head_bottom) == 22, "offsetof(NetPacket_Fixed<0x01d9>, head_bottom) == 22"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, head_top) == 24, "offsetof(NetPacket_Fixed<0x01d9>, head_top) == 24"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, head_mid) == 26, "offsetof(NetPacket_Fixed<0x01d9>, head_mid) == 26"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, hair_color) == 28, "offsetof(NetPacket_Fixed<0x01d9>, hair_color) == 28"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, clothes_color) == 30, "offsetof(NetPacket_Fixed<0x01d9>, clothes_color) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, head_dir) == 32, "offsetof(NetPacket_Fixed<0x01d9>, head_dir) == 32"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, unused2) == 33, "offsetof(NetPacket_Fixed<0x01d9>, unused2) == 33"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, guild_id) == 34, "offsetof(NetPacket_Fixed<0x01d9>, guild_id) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, guild_emblem_id) == 38, "offsetof(NetPacket_Fixed<0x01d9>, guild_emblem_id) == 38"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, manner) == 40, "offsetof(NetPacket_Fixed<0x01d9>, manner) == 40"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, opt3) == 42, "offsetof(NetPacket_Fixed<0x01d9>, opt3) == 42"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, karma) == 44, "offsetof(NetPacket_Fixed<0x01d9>, karma) == 44"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, sex) == 45, "offsetof(NetPacket_Fixed<0x01d9>, sex) == 45"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, pos) == 46, "offsetof(NetPacket_Fixed<0x01d9>, pos) == 46"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, gm_bits) == 49, "offsetof(NetPacket_Fixed<0x01d9>, gm_bits) == 49"); +static_assert(offsetof(NetPacket_Fixed<0x01d9>, unused) == 51, "offsetof(NetPacket_Fixed<0x01d9>, unused) == 51"); +static_assert(sizeof(NetPacket_Fixed<0x01d9>) == 53, "sizeof(NetPacket_Fixed<0x01d9>) == 53"); +static_assert(alignof(NetPacket_Fixed<0x01d9>) == 1, "alignof(NetPacket_Fixed<0x01d9>) == 1"); + +template<> +struct NetPacket_Fixed<0x01da> +{ + Little16 magic_packet_id; + Little32 block_id; + Little16 speed; + Little16 opt1; + Little16 opt2; + Little16 option; + Little16 species; + Little16 hair_style; + Little16 weapon; + Little16 shield; + Little16 head_bottom; + Little32 tick; + Little16 head_top; + Little16 head_mid; + Little16 hair_color; + Little16 clothes_color; + Byte head_dir; + Byte unused2; + Little32 guild_id; + Little16 guild_emblem_id; + Little16 manner; + Little16 opt3; + Byte karma; + Byte sex; + NetPosition2 pos2; + Little16 gm_bits; + Byte five; + Little16 unused; +}; +static_assert(offsetof(NetPacket_Fixed<0x01da>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x01da>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, block_id) == 2, "offsetof(NetPacket_Fixed<0x01da>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, speed) == 6, "offsetof(NetPacket_Fixed<0x01da>, speed) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, opt1) == 8, "offsetof(NetPacket_Fixed<0x01da>, opt1) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, opt2) == 10, "offsetof(NetPacket_Fixed<0x01da>, opt2) == 10"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, option) == 12, "offsetof(NetPacket_Fixed<0x01da>, option) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, species) == 14, "offsetof(NetPacket_Fixed<0x01da>, species) == 14"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, hair_style) == 16, "offsetof(NetPacket_Fixed<0x01da>, hair_style) == 16"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, weapon) == 18, "offsetof(NetPacket_Fixed<0x01da>, weapon) == 18"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, shield) == 20, "offsetof(NetPacket_Fixed<0x01da>, shield) == 20"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, head_bottom) == 22, "offsetof(NetPacket_Fixed<0x01da>, head_bottom) == 22"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, tick) == 24, "offsetof(NetPacket_Fixed<0x01da>, tick) == 24"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, head_top) == 28, "offsetof(NetPacket_Fixed<0x01da>, head_top) == 28"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, head_mid) == 30, "offsetof(NetPacket_Fixed<0x01da>, head_mid) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, hair_color) == 32, "offsetof(NetPacket_Fixed<0x01da>, hair_color) == 32"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, clothes_color) == 34, "offsetof(NetPacket_Fixed<0x01da>, clothes_color) == 34"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, head_dir) == 36, "offsetof(NetPacket_Fixed<0x01da>, head_dir) == 36"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, unused2) == 37, "offsetof(NetPacket_Fixed<0x01da>, unused2) == 37"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, guild_id) == 38, "offsetof(NetPacket_Fixed<0x01da>, guild_id) == 38"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, guild_emblem_id) == 42, "offsetof(NetPacket_Fixed<0x01da>, guild_emblem_id) == 42"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, manner) == 44, "offsetof(NetPacket_Fixed<0x01da>, manner) == 44"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, opt3) == 46, "offsetof(NetPacket_Fixed<0x01da>, opt3) == 46"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, karma) == 48, "offsetof(NetPacket_Fixed<0x01da>, karma) == 48"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, sex) == 49, "offsetof(NetPacket_Fixed<0x01da>, sex) == 49"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, pos2) == 50, "offsetof(NetPacket_Fixed<0x01da>, pos2) == 50"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, gm_bits) == 55, "offsetof(NetPacket_Fixed<0x01da>, gm_bits) == 55"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, five) == 57, "offsetof(NetPacket_Fixed<0x01da>, five) == 57"); +static_assert(offsetof(NetPacket_Fixed<0x01da>, unused) == 58, "offsetof(NetPacket_Fixed<0x01da>, unused) == 58"); +static_assert(sizeof(NetPacket_Fixed<0x01da>) == 60, "sizeof(NetPacket_Fixed<0x01da>) == 60"); +static_assert(alignof(NetPacket_Fixed<0x01da>) == 1, "alignof(NetPacket_Fixed<0x01da>) == 1"); + +template<> +struct NetPacket_Fixed<0x01de> +{ + Little16 magic_packet_id; + Little16 skill_id; + Little32 src_id; + Little32 dst_id; + Little32 tick; + Little32 sdelay; + Little32 ddelay; + Little32 damage; + Little16 skill_level; + Little16 div; + Byte type_or_hit; +}; +static_assert(offsetof(NetPacket_Fixed<0x01de>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x01de>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x01de>, skill_id) == 2, "offsetof(NetPacket_Fixed<0x01de>, skill_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x01de>, src_id) == 4, "offsetof(NetPacket_Fixed<0x01de>, src_id) == 4"); +static_assert(offsetof(NetPacket_Fixed<0x01de>, dst_id) == 8, "offsetof(NetPacket_Fixed<0x01de>, dst_id) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x01de>, tick) == 12, "offsetof(NetPacket_Fixed<0x01de>, tick) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x01de>, sdelay) == 16, "offsetof(NetPacket_Fixed<0x01de>, sdelay) == 16"); +static_assert(offsetof(NetPacket_Fixed<0x01de>, ddelay) == 20, "offsetof(NetPacket_Fixed<0x01de>, ddelay) == 20"); +static_assert(offsetof(NetPacket_Fixed<0x01de>, damage) == 24, "offsetof(NetPacket_Fixed<0x01de>, damage) == 24"); +static_assert(offsetof(NetPacket_Fixed<0x01de>, skill_level) == 28, "offsetof(NetPacket_Fixed<0x01de>, skill_level) == 28"); +static_assert(offsetof(NetPacket_Fixed<0x01de>, div) == 30, "offsetof(NetPacket_Fixed<0x01de>, div) == 30"); +static_assert(offsetof(NetPacket_Fixed<0x01de>, type_or_hit) == 32, "offsetof(NetPacket_Fixed<0x01de>, type_or_hit) == 32"); +static_assert(sizeof(NetPacket_Fixed<0x01de>) == 33, "sizeof(NetPacket_Fixed<0x01de>) == 33"); +static_assert(alignof(NetPacket_Fixed<0x01de>) == 1, "alignof(NetPacket_Fixed<0x01de>) == 1"); + +template<> +struct NetPacket_Head<0x01ee> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x01ee>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x01ee>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x01ee>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x01ee>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x01ee>) == 4, "sizeof(NetPacket_Head<0x01ee>) == 4"); +static_assert(alignof(NetPacket_Head<0x01ee>) == 1, "alignof(NetPacket_Head<0x01ee>) == 1"); +template<> +struct NetPacket_Repeat<0x01ee> +{ + Little16 ioff2; + Little16 name_id; + Byte item_type; + Byte identify; + Little16 amount; + Little16 epos; + Little16 card0; + Little16 card1; + Little16 card2; + Little16 card3; +}; +static_assert(offsetof(NetPacket_Repeat<0x01ee>, ioff2) == 0, "offsetof(NetPacket_Repeat<0x01ee>, ioff2) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x01ee>, name_id) == 2, "offsetof(NetPacket_Repeat<0x01ee>, name_id) == 2"); +static_assert(offsetof(NetPacket_Repeat<0x01ee>, item_type) == 4, "offsetof(NetPacket_Repeat<0x01ee>, item_type) == 4"); +static_assert(offsetof(NetPacket_Repeat<0x01ee>, identify) == 5, "offsetof(NetPacket_Repeat<0x01ee>, identify) == 5"); +static_assert(offsetof(NetPacket_Repeat<0x01ee>, amount) == 6, "offsetof(NetPacket_Repeat<0x01ee>, amount) == 6"); +static_assert(offsetof(NetPacket_Repeat<0x01ee>, epos) == 8, "offsetof(NetPacket_Repeat<0x01ee>, epos) == 8"); +static_assert(offsetof(NetPacket_Repeat<0x01ee>, card0) == 10, "offsetof(NetPacket_Repeat<0x01ee>, card0) == 10"); +static_assert(offsetof(NetPacket_Repeat<0x01ee>, card1) == 12, "offsetof(NetPacket_Repeat<0x01ee>, card1) == 12"); +static_assert(offsetof(NetPacket_Repeat<0x01ee>, card2) == 14, "offsetof(NetPacket_Repeat<0x01ee>, card2) == 14"); +static_assert(offsetof(NetPacket_Repeat<0x01ee>, card3) == 16, "offsetof(NetPacket_Repeat<0x01ee>, card3) == 16"); +static_assert(sizeof(NetPacket_Repeat<0x01ee>) == 18, "sizeof(NetPacket_Repeat<0x01ee>) == 18"); +static_assert(alignof(NetPacket_Repeat<0x01ee>) == 1, "alignof(NetPacket_Repeat<0x01ee>) == 1"); + +template<> +struct NetPacket_Head<0x01f0> +{ + Little16 magic_packet_id; + Little16 magic_packet_length; +}; +static_assert(offsetof(NetPacket_Head<0x01f0>, magic_packet_id) == 0, "offsetof(NetPacket_Head<0x01f0>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Head<0x01f0>, magic_packet_length) == 2, "offsetof(NetPacket_Head<0x01f0>, magic_packet_length) == 2"); +static_assert(sizeof(NetPacket_Head<0x01f0>) == 4, "sizeof(NetPacket_Head<0x01f0>) == 4"); +static_assert(alignof(NetPacket_Head<0x01f0>) == 1, "alignof(NetPacket_Head<0x01f0>) == 1"); +template<> +struct NetPacket_Repeat<0x01f0> +{ + Little16 soff1; + Little16 name_id; + Byte item_type; + Byte identify; + Little16 amount; + Little16 epos_zero; + Little16 card0; + Little16 card1; + Little16 card2; + Little16 card3; +}; +static_assert(offsetof(NetPacket_Repeat<0x01f0>, soff1) == 0, "offsetof(NetPacket_Repeat<0x01f0>, soff1) == 0"); +static_assert(offsetof(NetPacket_Repeat<0x01f0>, name_id) == 2, "offsetof(NetPacket_Repeat<0x01f0>, name_id) == 2"); +static_assert(offsetof(NetPacket_Repeat<0x01f0>, item_type) == 4, "offsetof(NetPacket_Repeat<0x01f0>, item_type) == 4"); +static_assert(offsetof(NetPacket_Repeat<0x01f0>, identify) == 5, "offsetof(NetPacket_Repeat<0x01f0>, identify) == 5"); +static_assert(offsetof(NetPacket_Repeat<0x01f0>, amount) == 6, "offsetof(NetPacket_Repeat<0x01f0>, amount) == 6"); +static_assert(offsetof(NetPacket_Repeat<0x01f0>, epos_zero) == 8, "offsetof(NetPacket_Repeat<0x01f0>, epos_zero) == 8"); +static_assert(offsetof(NetPacket_Repeat<0x01f0>, card0) == 10, "offsetof(NetPacket_Repeat<0x01f0>, card0) == 10"); +static_assert(offsetof(NetPacket_Repeat<0x01f0>, card1) == 12, "offsetof(NetPacket_Repeat<0x01f0>, card1) == 12"); +static_assert(offsetof(NetPacket_Repeat<0x01f0>, card2) == 14, "offsetof(NetPacket_Repeat<0x01f0>, card2) == 14"); +static_assert(offsetof(NetPacket_Repeat<0x01f0>, card3) == 16, "offsetof(NetPacket_Repeat<0x01f0>, card3) == 16"); +static_assert(sizeof(NetPacket_Repeat<0x01f0>) == 18, "sizeof(NetPacket_Repeat<0x01f0>) == 18"); +static_assert(alignof(NetPacket_Repeat<0x01f0>) == 1, "alignof(NetPacket_Repeat<0x01f0>) == 1"); + +template<> +struct NetPacket_Fixed<0x020c> +{ + Little16 magic_packet_id; + Little32 block_id; + IP4Address ip; +}; +static_assert(offsetof(NetPacket_Fixed<0x020c>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x020c>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x020c>, block_id) == 2, "offsetof(NetPacket_Fixed<0x020c>, block_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x020c>, ip) == 6, "offsetof(NetPacket_Fixed<0x020c>, ip) == 6"); +static_assert(sizeof(NetPacket_Fixed<0x020c>) == 10, "sizeof(NetPacket_Fixed<0x020c>) == 10"); +static_assert(alignof(NetPacket_Fixed<0x020c>) == 1, "alignof(NetPacket_Fixed<0x020c>) == 1"); + +template<> +struct NetPacket_Fixed<0x0212> +{ + Little16 magic_packet_id; + Little32 npc_id; + Little16 command; + Little32 id; + Little16 x; + Little16 y; +}; +static_assert(offsetof(NetPacket_Fixed<0x0212>, magic_packet_id) == 0, "offsetof(NetPacket_Fixed<0x0212>, magic_packet_id) == 0"); +static_assert(offsetof(NetPacket_Fixed<0x0212>, npc_id) == 2, "offsetof(NetPacket_Fixed<0x0212>, npc_id) == 2"); +static_assert(offsetof(NetPacket_Fixed<0x0212>, command) == 6, "offsetof(NetPacket_Fixed<0x0212>, command) == 6"); +static_assert(offsetof(NetPacket_Fixed<0x0212>, id) == 8, "offsetof(NetPacket_Fixed<0x0212>, id) == 8"); +static_assert(offsetof(NetPacket_Fixed<0x0212>, x) == 12, "offsetof(NetPacket_Fixed<0x0212>, x) == 12"); +static_assert(offsetof(NetPacket_Fixed<0x0212>, y) == 14, "offsetof(NetPacket_Fixed<0x0212>, y) == 14"); +static_assert(sizeof(NetPacket_Fixed<0x0212>) == 16, "sizeof(NetPacket_Fixed<0x0212>) == 16"); +static_assert(alignof(NetPacket_Fixed<0x0212>) == 1, "alignof(NetPacket_Fixed<0x0212>) == 1"); + + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0072> *network, Packet_Fixed<0x0072> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->login_id1, native.login_id1); + rv &= native_to_network(&network->client_tick, native.client_tick); + rv &= native_to_network(&network->sex, native.sex); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0072> *native, NetPacket_Fixed<0x0072> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->login_id1, network.login_id1); + rv &= network_to_native(&native->client_tick, network.client_tick); + rv &= network_to_native(&native->sex, network.sex); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0073> *network, Packet_Fixed<0x0073> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->tick, native.tick); + rv &= native_to_network(&network->pos, native.pos); + rv &= native_to_network(&network->five1, native.five1); + rv &= native_to_network(&network->five2, native.five2); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0073> *native, NetPacket_Fixed<0x0073> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->tick, network.tick); + rv &= network_to_native(&native->pos, network.pos); + rv &= network_to_native(&native->five1, network.five1); + rv &= network_to_native(&native->five2, network.five2); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0078> *network, Packet_Fixed<0x0078> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->speed, native.speed); + rv &= native_to_network(&network->opt1, native.opt1); + rv &= native_to_network(&network->opt2, native.opt2); + rv &= native_to_network(&network->option, native.option); + rv &= native_to_network(&network->species, native.species); + rv &= native_to_network(&network->unused_hair_style, native.unused_hair_style); + rv &= native_to_network(&network->unused_weapon, native.unused_weapon); + rv &= native_to_network(&network->unused_head_bottom_or_species_again, native.unused_head_bottom_or_species_again); + rv &= native_to_network(&network->unused_shield_or_part_of_guild_emblem, native.unused_shield_or_part_of_guild_emblem); + rv &= native_to_network(&network->unused_head_top_or_unused_part_of_guild_emblem, native.unused_head_top_or_unused_part_of_guild_emblem); + rv &= native_to_network(&network->unused_head_mid_or_part_of_guild_id, native.unused_head_mid_or_part_of_guild_id); + rv &= native_to_network(&network->unused_hair_color_or_part_of_guild_id, native.unused_hair_color_or_part_of_guild_id); + rv &= native_to_network(&network->unused_clothes_color, native.unused_clothes_color); + rv &= native_to_network(&network->unused_1, native.unused_1); + rv &= native_to_network(&network->unused_2, native.unused_2); + rv &= native_to_network(&network->unused_pos_again, native.unused_pos_again); + rv &= native_to_network(&network->unused_4b, native.unused_4b); + rv &= native_to_network(&network->unused_5, native.unused_5); + rv &= native_to_network(&network->unused_zero_1, native.unused_zero_1); + rv &= native_to_network(&network->unused_zero_2, native.unused_zero_2); + rv &= native_to_network(&network->unused_sex, native.unused_sex); + rv &= native_to_network(&network->pos, native.pos); + rv &= native_to_network(&network->five1, native.five1); + rv &= native_to_network(&network->five2, native.five2); + rv &= native_to_network(&network->zero, native.zero); + rv &= native_to_network(&network->level, native.level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0078> *native, NetPacket_Fixed<0x0078> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->speed, network.speed); + rv &= network_to_native(&native->opt1, network.opt1); + rv &= network_to_native(&native->opt2, network.opt2); + rv &= network_to_native(&native->option, network.option); + rv &= network_to_native(&native->species, network.species); + rv &= network_to_native(&native->unused_hair_style, network.unused_hair_style); + rv &= network_to_native(&native->unused_weapon, network.unused_weapon); + rv &= network_to_native(&native->unused_head_bottom_or_species_again, network.unused_head_bottom_or_species_again); + rv &= network_to_native(&native->unused_shield_or_part_of_guild_emblem, network.unused_shield_or_part_of_guild_emblem); + rv &= network_to_native(&native->unused_head_top_or_unused_part_of_guild_emblem, network.unused_head_top_or_unused_part_of_guild_emblem); + rv &= network_to_native(&native->unused_head_mid_or_part_of_guild_id, network.unused_head_mid_or_part_of_guild_id); + rv &= network_to_native(&native->unused_hair_color_or_part_of_guild_id, network.unused_hair_color_or_part_of_guild_id); + rv &= network_to_native(&native->unused_clothes_color, network.unused_clothes_color); + rv &= network_to_native(&native->unused_1, network.unused_1); + rv &= network_to_native(&native->unused_2, network.unused_2); + rv &= network_to_native(&native->unused_pos_again, network.unused_pos_again); + rv &= network_to_native(&native->unused_4b, network.unused_4b); + rv &= network_to_native(&native->unused_5, network.unused_5); + rv &= network_to_native(&native->unused_zero_1, network.unused_zero_1); + rv &= network_to_native(&native->unused_zero_2, network.unused_zero_2); + rv &= network_to_native(&native->unused_sex, network.unused_sex); + rv &= network_to_native(&native->pos, network.pos); + rv &= network_to_native(&native->five1, network.five1); + rv &= network_to_native(&native->five2, network.five2); + rv &= network_to_native(&native->zero, network.zero); + rv &= network_to_native(&native->level, network.level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x007b> *network, Packet_Fixed<0x007b> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->speed, native.speed); + rv &= native_to_network(&network->opt1, native.opt1); + rv &= native_to_network(&network->opt2, native.opt2); + rv &= native_to_network(&network->option, native.option); + rv &= native_to_network(&network->mob_class, native.mob_class); + rv &= native_to_network(&network->unused_hair_style, native.unused_hair_style); + rv &= native_to_network(&network->unused_weapon, native.unused_weapon); + rv &= native_to_network(&network->unused_head_bottom, native.unused_head_bottom); + rv &= native_to_network(&network->tick_and_maybe_part_of_guild_emblem, native.tick_and_maybe_part_of_guild_emblem); + rv &= native_to_network(&network->unused_shield_or_maybe_part_of_guild_emblem, native.unused_shield_or_maybe_part_of_guild_emblem); + rv &= native_to_network(&network->unused_head_top_or_maybe_part_of_guild_id, native.unused_head_top_or_maybe_part_of_guild_id); + rv &= native_to_network(&network->unused_head_mid_or_maybe_part_of_guild_id, native.unused_head_mid_or_maybe_part_of_guild_id); + rv &= native_to_network(&network->unused_hair_color, native.unused_hair_color); + rv &= native_to_network(&network->unused_clothes_color, native.unused_clothes_color); + rv &= native_to_network(&network->unused_1, native.unused_1); + rv &= native_to_network(&network->unused_2, native.unused_2); + rv &= native_to_network(&network->unused_3, native.unused_3); + rv &= native_to_network(&network->unused_4, native.unused_4); + rv &= native_to_network(&network->unused_5, native.unused_5); + rv &= native_to_network(&network->unused_zero_1, native.unused_zero_1); + rv &= native_to_network(&network->unused_zero_2, native.unused_zero_2); + rv &= native_to_network(&network->unused_sex, native.unused_sex); + rv &= native_to_network(&network->pos2, native.pos2); + rv &= native_to_network(&network->zero, native.zero); + rv &= native_to_network(&network->five1, native.five1); + rv &= native_to_network(&network->five2, native.five2); + rv &= native_to_network(&network->level, native.level); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x007b> *native, NetPacket_Fixed<0x007b> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->speed, network.speed); + rv &= network_to_native(&native->opt1, network.opt1); + rv &= network_to_native(&native->opt2, network.opt2); + rv &= network_to_native(&native->option, network.option); + rv &= network_to_native(&native->mob_class, network.mob_class); + rv &= network_to_native(&native->unused_hair_style, network.unused_hair_style); + rv &= network_to_native(&native->unused_weapon, network.unused_weapon); + rv &= network_to_native(&native->unused_head_bottom, network.unused_head_bottom); + rv &= network_to_native(&native->tick_and_maybe_part_of_guild_emblem, network.tick_and_maybe_part_of_guild_emblem); + rv &= network_to_native(&native->unused_shield_or_maybe_part_of_guild_emblem, network.unused_shield_or_maybe_part_of_guild_emblem); + rv &= network_to_native(&native->unused_head_top_or_maybe_part_of_guild_id, network.unused_head_top_or_maybe_part_of_guild_id); + rv &= network_to_native(&native->unused_head_mid_or_maybe_part_of_guild_id, network.unused_head_mid_or_maybe_part_of_guild_id); + rv &= network_to_native(&native->unused_hair_color, network.unused_hair_color); + rv &= network_to_native(&native->unused_clothes_color, network.unused_clothes_color); + rv &= network_to_native(&native->unused_1, network.unused_1); + rv &= network_to_native(&native->unused_2, network.unused_2); + rv &= network_to_native(&native->unused_3, network.unused_3); + rv &= network_to_native(&native->unused_4, network.unused_4); + rv &= network_to_native(&native->unused_5, network.unused_5); + rv &= network_to_native(&native->unused_zero_1, network.unused_zero_1); + rv &= network_to_native(&native->unused_zero_2, network.unused_zero_2); + rv &= network_to_native(&native->unused_sex, network.unused_sex); + rv &= network_to_native(&native->pos2, network.pos2); + rv &= network_to_native(&native->zero, network.zero); + rv &= network_to_native(&native->five1, network.five1); + rv &= network_to_native(&native->five2, network.five2); + rv &= network_to_native(&native->level, network.level); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x007c> *network, Packet_Fixed<0x007c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->speed, native.speed); + rv &= native_to_network(&network->opt1, native.opt1); + rv &= native_to_network(&network->opt2, native.opt2); + rv &= native_to_network(&network->option, native.option); + rv &= native_to_network(&network->unknown_1, native.unknown_1); + rv &= native_to_network(&network->unknown_2, native.unknown_2); + rv &= native_to_network(&network->unknown_3, native.unknown_3); + rv &= native_to_network(&network->species, native.species); + rv &= native_to_network(&network->unknown_4, native.unknown_4); + rv &= native_to_network(&network->unknown_5, native.unknown_5); + rv &= native_to_network(&network->unknown_6, native.unknown_6); + rv &= native_to_network(&network->unknown_7, native.unknown_7); + rv &= native_to_network(&network->unknown_8, native.unknown_8); + rv &= native_to_network(&network->unknown_9, native.unknown_9); + rv &= native_to_network(&network->unknown_10, native.unknown_10); + rv &= native_to_network(&network->pos, native.pos); + rv &= native_to_network(&network->unknown_11, native.unknown_11); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x007c> *native, NetPacket_Fixed<0x007c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->speed, network.speed); + rv &= network_to_native(&native->opt1, network.opt1); + rv &= network_to_native(&native->opt2, network.opt2); + rv &= network_to_native(&native->option, network.option); + rv &= network_to_native(&native->unknown_1, network.unknown_1); + rv &= network_to_native(&native->unknown_2, network.unknown_2); + rv &= network_to_native(&native->unknown_3, network.unknown_3); + rv &= network_to_native(&native->species, network.species); + rv &= network_to_native(&native->unknown_4, network.unknown_4); + rv &= network_to_native(&native->unknown_5, network.unknown_5); + rv &= network_to_native(&native->unknown_6, network.unknown_6); + rv &= network_to_native(&native->unknown_7, network.unknown_7); + rv &= network_to_native(&native->unknown_8, network.unknown_8); + rv &= network_to_native(&native->unknown_9, network.unknown_9); + rv &= network_to_native(&native->unknown_10, network.unknown_10); + rv &= network_to_native(&native->pos, network.pos); + rv &= network_to_native(&native->unknown_11, network.unknown_11); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x007d> *network, Packet_Fixed<0x007d> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x007d> *native, NetPacket_Fixed<0x007d> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x007e> *network, Packet_Fixed<0x007e> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->client_tick, native.client_tick); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x007e> *native, NetPacket_Fixed<0x007e> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->client_tick, network.client_tick); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x007f> *network, Packet_Fixed<0x007f> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->tick, native.tick); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x007f> *native, NetPacket_Fixed<0x007f> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->tick, network.tick); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0080> *network, Packet_Fixed<0x0080> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->type, native.type); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0080> *native, NetPacket_Fixed<0x0080> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->type, network.type); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0085> *network, Packet_Fixed<0x0085> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->pos, native.pos); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0085> *native, NetPacket_Fixed<0x0085> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->pos, network.pos); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0087> *network, Packet_Fixed<0x0087> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->tick, native.tick); + rv &= native_to_network(&network->pos2, native.pos2); + rv &= native_to_network(&network->zero, native.zero); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0087> *native, NetPacket_Fixed<0x0087> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->tick, network.tick); + rv &= network_to_native(&native->pos2, network.pos2); + rv &= network_to_native(&native->zero, network.zero); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0088> *network, Packet_Fixed<0x0088> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0088> *native, NetPacket_Fixed<0x0088> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0089> *network, Packet_Fixed<0x0089> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->target_id, native.target_id); + rv &= native_to_network(&network->action, native.action); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0089> *native, NetPacket_Fixed<0x0089> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->target_id, network.target_id); + rv &= network_to_native(&native->action, network.action); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x008a> *network, Packet_Fixed<0x008a> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->src_id, native.src_id); + rv &= native_to_network(&network->dst_id, native.dst_id); + rv &= native_to_network(&network->tick, native.tick); + rv &= native_to_network(&network->sdelay, native.sdelay); + rv &= native_to_network(&network->ddelay, native.ddelay); + rv &= native_to_network(&network->damage, native.damage); + rv &= native_to_network(&network->div, native.div); + rv &= native_to_network(&network->damage_type, native.damage_type); + rv &= native_to_network(&network->damage2, native.damage2); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x008a> *native, NetPacket_Fixed<0x008a> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->src_id, network.src_id); + rv &= network_to_native(&native->dst_id, network.dst_id); + rv &= network_to_native(&native->tick, network.tick); + rv &= network_to_native(&native->sdelay, network.sdelay); + rv &= network_to_native(&native->ddelay, network.ddelay); + rv &= network_to_native(&native->damage, network.damage); + rv &= network_to_native(&native->div, network.div); + rv &= network_to_native(&native->damage_type, network.damage_type); + rv &= network_to_native(&native->damage2, network.damage2); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x008c> *network, Packet_Head<0x008c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x008c> *native, NetPacket_Head<0x008c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x008c> *network, Packet_Repeat<0x008c> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x008c> *native, NetPacket_Repeat<0x008c> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x008d> *network, Packet_Head<0x008d> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x008d> *native, NetPacket_Head<0x008d> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x008d> *network, Packet_Repeat<0x008d> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x008d> *native, NetPacket_Repeat<0x008d> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x008e> *network, Packet_Head<0x008e> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x008e> *native, NetPacket_Head<0x008e> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x008e> *network, Packet_Repeat<0x008e> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x008e> *native, NetPacket_Repeat<0x008e> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0090> *network, Packet_Fixed<0x0090> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->unused, native.unused); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0090> *native, NetPacket_Fixed<0x0090> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->unused, network.unused); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0091> *network, Packet_Fixed<0x0091> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0091> *native, NetPacket_Fixed<0x0091> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0092> *network, Packet_Fixed<0x0092> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + rv &= native_to_network(&network->ip, native.ip); + rv &= native_to_network(&network->port, native.port); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0092> *native, NetPacket_Fixed<0x0092> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + rv &= network_to_native(&native->ip, network.ip); + rv &= network_to_native(&native->port, network.port); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0094> *network, Packet_Fixed<0x0094> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0094> *native, NetPacket_Fixed<0x0094> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0095> *network, Packet_Fixed<0x0095> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->char_name, native.char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0095> *native, NetPacket_Fixed<0x0095> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->char_name, network.char_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x0096> *network, Packet_Head<0x0096> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->target_name, native.target_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x0096> *native, NetPacket_Head<0x0096> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->target_name, network.target_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x0096> *network, Packet_Repeat<0x0096> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x0096> *native, NetPacket_Repeat<0x0096> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x0097> *network, Packet_Head<0x0097> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->char_name, native.char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x0097> *native, NetPacket_Head<0x0097> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->char_name, network.char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x0097> *network, Packet_Repeat<0x0097> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x0097> *native, NetPacket_Repeat<0x0097> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0098> *network, Packet_Fixed<0x0098> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0098> *native, NetPacket_Fixed<0x0098> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x009a> *network, Packet_Head<0x009a> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x009a> *native, NetPacket_Head<0x009a> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x009a> *network, Packet_Repeat<0x009a> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x009a> *native, NetPacket_Repeat<0x009a> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x009b> *network, Packet_Fixed<0x009b> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->unused, native.unused); + rv &= native_to_network(&network->client_dir, native.client_dir); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x009b> *native, NetPacket_Fixed<0x009b> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->unused, network.unused); + rv &= network_to_native(&native->client_dir, network.client_dir); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x009c> *network, Packet_Fixed<0x009c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->zero, native.zero); + rv &= native_to_network(&network->client_dir, native.client_dir); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x009c> *native, NetPacket_Fixed<0x009c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->zero, network.zero); + rv &= network_to_native(&native->client_dir, network.client_dir); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x009d> *network, Packet_Fixed<0x009d> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->name_id, native.name_id); + rv &= native_to_network(&network->identify, native.identify); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + rv &= native_to_network(&network->amount, native.amount); + rv &= native_to_network(&network->subx, native.subx); + rv &= native_to_network(&network->suby, native.suby); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x009d> *native, NetPacket_Fixed<0x009d> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->name_id, network.name_id); + rv &= network_to_native(&native->identify, network.identify); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + rv &= network_to_native(&native->amount, network.amount); + rv &= network_to_native(&native->subx, network.subx); + rv &= network_to_native(&native->suby, network.suby); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x009e> *network, Packet_Fixed<0x009e> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->name_id, native.name_id); + rv &= native_to_network(&network->identify, native.identify); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + rv &= native_to_network(&network->subx, native.subx); + rv &= native_to_network(&network->suby, native.suby); + rv &= native_to_network(&network->amount, native.amount); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x009e> *native, NetPacket_Fixed<0x009e> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->name_id, network.name_id); + rv &= network_to_native(&native->identify, network.identify); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + rv &= network_to_native(&native->subx, network.subx); + rv &= network_to_native(&native->suby, network.suby); + rv &= network_to_native(&native->amount, network.amount); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x009f> *network, Packet_Fixed<0x009f> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->object_id, native.object_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x009f> *native, NetPacket_Fixed<0x009f> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->object_id, network.object_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00a0> *network, Packet_Fixed<0x00a0> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->amount, native.amount); + rv &= native_to_network(&network->name_id, native.name_id); + rv &= native_to_network(&network->identify, native.identify); + rv &= native_to_network(&network->broken_or_attribute, native.broken_or_attribute); + rv &= native_to_network(&network->refine, native.refine); + rv &= native_to_network(&network->card0, native.card0); + rv &= native_to_network(&network->card1, native.card1); + rv &= native_to_network(&network->card2, native.card2); + rv &= native_to_network(&network->card3, native.card3); + rv &= native_to_network(&network->epos, native.epos); + rv &= native_to_network(&network->item_type, native.item_type); + rv &= native_to_network(&network->pickup_fail, native.pickup_fail); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00a0> *native, NetPacket_Fixed<0x00a0> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->amount, network.amount); + rv &= network_to_native(&native->name_id, network.name_id); + rv &= network_to_native(&native->identify, network.identify); + rv &= network_to_native(&native->broken_or_attribute, network.broken_or_attribute); + rv &= network_to_native(&native->refine, network.refine); + rv &= network_to_native(&native->card0, network.card0); + rv &= network_to_native(&native->card1, network.card1); + rv &= network_to_native(&native->card2, network.card2); + rv &= network_to_native(&native->card3, network.card3); + rv &= network_to_native(&native->epos, network.epos); + rv &= network_to_native(&native->item_type, network.item_type); + rv &= network_to_native(&native->pickup_fail, network.pickup_fail); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00a1> *network, Packet_Fixed<0x00a1> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00a1> *native, NetPacket_Fixed<0x00a1> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00a2> *network, Packet_Fixed<0x00a2> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->amount, native.amount); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00a2> *native, NetPacket_Fixed<0x00a2> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->amount, network.amount); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x00a4> *network, Packet_Head<0x00a4> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x00a4> *native, NetPacket_Head<0x00a4> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x00a4> *network, Packet_Repeat<0x00a4> native) +{ + bool rv = true; + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->name_id, native.name_id); + rv &= native_to_network(&network->item_type, native.item_type); + rv &= native_to_network(&network->identify, native.identify); + rv &= native_to_network(&network->epos_pc, native.epos_pc); + rv &= native_to_network(&network->epos_inv, native.epos_inv); + rv &= native_to_network(&network->broken_or_attribute, native.broken_or_attribute); + rv &= native_to_network(&network->refine, native.refine); + rv &= native_to_network(&network->card0, native.card0); + rv &= native_to_network(&network->card1, native.card1); + rv &= native_to_network(&network->card2, native.card2); + rv &= native_to_network(&network->card3, native.card3); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x00a4> *native, NetPacket_Repeat<0x00a4> network) +{ + bool rv = true; + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->name_id, network.name_id); + rv &= network_to_native(&native->item_type, network.item_type); + rv &= network_to_native(&native->identify, network.identify); + rv &= network_to_native(&native->epos_pc, network.epos_pc); + rv &= network_to_native(&native->epos_inv, network.epos_inv); + rv &= network_to_native(&native->broken_or_attribute, network.broken_or_attribute); + rv &= network_to_native(&native->refine, network.refine); + rv &= network_to_native(&native->card0, network.card0); + rv &= network_to_native(&native->card1, network.card1); + rv &= network_to_native(&native->card2, network.card2); + rv &= network_to_native(&native->card3, network.card3); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x00a6> *network, Packet_Head<0x00a6> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x00a6> *native, NetPacket_Head<0x00a6> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x00a6> *network, Packet_Repeat<0x00a6> native) +{ + bool rv = true; + rv &= native_to_network(&network->soff1, native.soff1); + rv &= native_to_network(&network->name_id, native.name_id); + rv &= native_to_network(&network->item_type, native.item_type); + rv &= native_to_network(&network->identify, native.identify); + rv &= native_to_network(&network->epos_id, native.epos_id); + rv &= native_to_network(&network->epos_stor, native.epos_stor); + rv &= native_to_network(&network->broken_or_attribute, native.broken_or_attribute); + rv &= native_to_network(&network->refine, native.refine); + rv &= native_to_network(&network->card0, native.card0); + rv &= native_to_network(&network->card1, native.card1); + rv &= native_to_network(&network->card2, native.card2); + rv &= native_to_network(&network->card3, native.card3); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x00a6> *native, NetPacket_Repeat<0x00a6> network) +{ + bool rv = true; + rv &= network_to_native(&native->soff1, network.soff1); + rv &= network_to_native(&native->name_id, network.name_id); + rv &= network_to_native(&native->item_type, network.item_type); + rv &= network_to_native(&native->identify, network.identify); + rv &= network_to_native(&native->epos_id, network.epos_id); + rv &= network_to_native(&native->epos_stor, network.epos_stor); + rv &= network_to_native(&native->broken_or_attribute, network.broken_or_attribute); + rv &= network_to_native(&native->refine, network.refine); + rv &= network_to_native(&native->card0, network.card0); + rv &= network_to_native(&native->card1, network.card1); + rv &= network_to_native(&native->card2, network.card2); + rv &= network_to_native(&native->card3, network.card3); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00a7> *network, Packet_Fixed<0x00a7> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->unused_id, native.unused_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00a7> *native, NetPacket_Fixed<0x00a7> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->unused_id, network.unused_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00a8> *network, Packet_Fixed<0x00a8> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->amount, native.amount); + rv &= native_to_network(&network->ok, native.ok); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00a8> *native, NetPacket_Fixed<0x00a8> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->amount, network.amount); + rv &= network_to_native(&native->ok, network.ok); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00a9> *network, Packet_Fixed<0x00a9> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->epos_ignored, native.epos_ignored); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00a9> *native, NetPacket_Fixed<0x00a9> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->epos_ignored, network.epos_ignored); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00aa> *network, Packet_Fixed<0x00aa> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->epos, native.epos); + rv &= native_to_network(&network->ok, native.ok); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00aa> *native, NetPacket_Fixed<0x00aa> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->epos, network.epos); + rv &= network_to_native(&native->ok, network.ok); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00ab> *network, Packet_Fixed<0x00ab> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00ab> *native, NetPacket_Fixed<0x00ab> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00ac> *network, Packet_Fixed<0x00ac> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->epos, native.epos); + rv &= native_to_network(&network->ok, native.ok); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00ac> *native, NetPacket_Fixed<0x00ac> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->epos, network.epos); + rv &= network_to_native(&native->ok, network.ok); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00af> *network, Packet_Fixed<0x00af> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->amount, native.amount); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00af> *native, NetPacket_Fixed<0x00af> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->amount, network.amount); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00b0> *network, Packet_Fixed<0x00b0> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->sp_type, native.sp_type); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00b0> *native, NetPacket_Fixed<0x00b0> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->sp_type, network.sp_type); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00b1> *network, Packet_Fixed<0x00b1> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->sp_type, native.sp_type); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00b1> *native, NetPacket_Fixed<0x00b1> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->sp_type, network.sp_type); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00b2> *network, Packet_Fixed<0x00b2> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00b2> *native, NetPacket_Fixed<0x00b2> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00b3> *network, Packet_Fixed<0x00b3> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->one, native.one); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00b3> *native, NetPacket_Fixed<0x00b3> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->one, network.one); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x00b4> *network, Packet_Head<0x00b4> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x00b4> *native, NetPacket_Head<0x00b4> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x00b4> *network, Packet_Repeat<0x00b4> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x00b4> *native, NetPacket_Repeat<0x00b4> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00b5> *network, Packet_Fixed<0x00b5> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00b5> *native, NetPacket_Fixed<0x00b5> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00b6> *network, Packet_Fixed<0x00b6> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00b6> *native, NetPacket_Fixed<0x00b6> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x00b7> *network, Packet_Head<0x00b7> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x00b7> *native, NetPacket_Head<0x00b7> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x00b7> *network, Packet_Repeat<0x00b7> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x00b7> *native, NetPacket_Repeat<0x00b7> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00b8> *network, Packet_Fixed<0x00b8> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->npc_id, native.npc_id); + rv &= native_to_network(&network->menu_entry, native.menu_entry); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00b8> *native, NetPacket_Fixed<0x00b8> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->npc_id, network.npc_id); + rv &= network_to_native(&native->menu_entry, network.menu_entry); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00b9> *network, Packet_Fixed<0x00b9> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->npc_id, native.npc_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00b9> *native, NetPacket_Fixed<0x00b9> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->npc_id, network.npc_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00bb> *network, Packet_Fixed<0x00bb> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->asp, native.asp); + rv &= native_to_network(&network->unused, native.unused); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00bb> *native, NetPacket_Fixed<0x00bb> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->asp, network.asp); + rv &= network_to_native(&native->unused, network.unused); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00bc> *network, Packet_Fixed<0x00bc> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->sp_type, native.sp_type); + rv &= native_to_network(&network->ok, native.ok); + rv &= native_to_network(&network->val, native.val); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00bc> *native, NetPacket_Fixed<0x00bc> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->sp_type, network.sp_type); + rv &= network_to_native(&native->ok, network.ok); + rv &= network_to_native(&native->val, network.val); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00bd> *network, Packet_Fixed<0x00bd> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->status_point, native.status_point); + rv &= native_to_network(&network->str_attr, native.str_attr); + rv &= native_to_network(&network->str_upd, native.str_upd); + rv &= native_to_network(&network->agi_attr, native.agi_attr); + rv &= native_to_network(&network->agi_upd, native.agi_upd); + rv &= native_to_network(&network->vit_attr, native.vit_attr); + rv &= native_to_network(&network->vit_upd, native.vit_upd); + rv &= native_to_network(&network->int_attr, native.int_attr); + rv &= native_to_network(&network->int_upd, native.int_upd); + rv &= native_to_network(&network->dex_attr, native.dex_attr); + rv &= native_to_network(&network->dex_upd, native.dex_upd); + rv &= native_to_network(&network->luk_attr, native.luk_attr); + rv &= native_to_network(&network->luk_upd, native.luk_upd); + rv &= native_to_network(&network->atk_sum, native.atk_sum); + rv &= native_to_network(&network->watk2, native.watk2); + rv &= native_to_network(&network->matk1, native.matk1); + rv &= native_to_network(&network->matk2, native.matk2); + rv &= native_to_network(&network->def, native.def); + rv &= native_to_network(&network->def2, native.def2); + rv &= native_to_network(&network->mdef, native.mdef); + rv &= native_to_network(&network->mdef2, native.mdef2); + rv &= native_to_network(&network->hit, native.hit); + rv &= native_to_network(&network->flee, native.flee); + rv &= native_to_network(&network->flee2, native.flee2); + rv &= native_to_network(&network->critical, native.critical); + rv &= native_to_network(&network->karma, native.karma); + rv &= native_to_network(&network->manner, native.manner); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00bd> *native, NetPacket_Fixed<0x00bd> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->status_point, network.status_point); + rv &= network_to_native(&native->str_attr, network.str_attr); + rv &= network_to_native(&native->str_upd, network.str_upd); + rv &= network_to_native(&native->agi_attr, network.agi_attr); + rv &= network_to_native(&native->agi_upd, network.agi_upd); + rv &= network_to_native(&native->vit_attr, network.vit_attr); + rv &= network_to_native(&native->vit_upd, network.vit_upd); + rv &= network_to_native(&native->int_attr, network.int_attr); + rv &= network_to_native(&native->int_upd, network.int_upd); + rv &= network_to_native(&native->dex_attr, network.dex_attr); + rv &= network_to_native(&native->dex_upd, network.dex_upd); + rv &= network_to_native(&native->luk_attr, network.luk_attr); + rv &= network_to_native(&native->luk_upd, network.luk_upd); + rv &= network_to_native(&native->atk_sum, network.atk_sum); + rv &= network_to_native(&native->watk2, network.watk2); + rv &= network_to_native(&native->matk1, network.matk1); + rv &= network_to_native(&native->matk2, network.matk2); + rv &= network_to_native(&native->def, network.def); + rv &= network_to_native(&native->def2, network.def2); + rv &= network_to_native(&native->mdef, network.mdef); + rv &= network_to_native(&native->mdef2, network.mdef2); + rv &= network_to_native(&native->hit, network.hit); + rv &= network_to_native(&native->flee, network.flee); + rv &= network_to_native(&native->flee2, network.flee2); + rv &= network_to_native(&native->critical, network.critical); + rv &= network_to_native(&native->karma, network.karma); + rv &= network_to_native(&native->manner, network.manner); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00be> *network, Packet_Fixed<0x00be> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->sp_type, native.sp_type); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00be> *native, NetPacket_Fixed<0x00be> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->sp_type, network.sp_type); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00bf> *network, Packet_Fixed<0x00bf> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->emote, native.emote); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00bf> *native, NetPacket_Fixed<0x00bf> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->emote, network.emote); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00c0> *network, Packet_Fixed<0x00c0> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->type, native.type); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00c0> *native, NetPacket_Fixed<0x00c0> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->type, network.type); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00c1> *network, Packet_Fixed<0x00c1> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00c1> *native, NetPacket_Fixed<0x00c1> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00c2> *network, Packet_Fixed<0x00c2> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->users, native.users); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00c2> *native, NetPacket_Fixed<0x00c2> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->users, network.users); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00c4> *network, Packet_Fixed<0x00c4> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00c4> *native, NetPacket_Fixed<0x00c4> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00c5> *network, Packet_Fixed<0x00c5> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->type, native.type); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00c5> *native, NetPacket_Fixed<0x00c5> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->type, network.type); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x00c6> *network, Packet_Head<0x00c6> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x00c6> *native, NetPacket_Head<0x00c6> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x00c6> *network, Packet_Repeat<0x00c6> native) +{ + bool rv = true; + rv &= native_to_network(&network->base_price, native.base_price); + rv &= native_to_network(&network->actual_price, native.actual_price); + rv &= native_to_network(&network->type, native.type); + rv &= native_to_network(&network->name_id, native.name_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x00c6> *native, NetPacket_Repeat<0x00c6> network) +{ + bool rv = true; + rv &= network_to_native(&native->base_price, network.base_price); + rv &= network_to_native(&native->actual_price, network.actual_price); + rv &= network_to_native(&native->type, network.type); + rv &= network_to_native(&native->name_id, network.name_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x00c7> *network, Packet_Head<0x00c7> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x00c7> *native, NetPacket_Head<0x00c7> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x00c7> *network, Packet_Repeat<0x00c7> native) +{ + bool rv = true; + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->base_price, native.base_price); + rv &= native_to_network(&network->actual_price, native.actual_price); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x00c7> *native, NetPacket_Repeat<0x00c7> network) +{ + bool rv = true; + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->base_price, network.base_price); + rv &= network_to_native(&native->actual_price, network.actual_price); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x00c8> *network, Packet_Head<0x00c8> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x00c8> *native, NetPacket_Head<0x00c8> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x00c8> *network, Packet_Repeat<0x00c8> native) +{ + bool rv = true; + rv &= native_to_network(&network->count, native.count); + rv &= native_to_network(&network->name_id, native.name_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x00c8> *native, NetPacket_Repeat<0x00c8> network) +{ + bool rv = true; + rv &= network_to_native(&native->count, network.count); + rv &= network_to_native(&native->name_id, network.name_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x00c9> *network, Packet_Head<0x00c9> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x00c9> *native, NetPacket_Head<0x00c9> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x00c9> *network, Packet_Repeat<0x00c9> native) +{ + bool rv = true; + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->count, native.count); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x00c9> *native, NetPacket_Repeat<0x00c9> network) +{ + bool rv = true; + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->count, network.count); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00ca> *network, Packet_Fixed<0x00ca> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->fail, native.fail); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00ca> *native, NetPacket_Fixed<0x00ca> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->fail, network.fail); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00cb> *network, Packet_Fixed<0x00cb> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->fail, native.fail); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00cb> *native, NetPacket_Fixed<0x00cb> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->fail, network.fail); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00cd> *network, Packet_Fixed<0x00cd> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00cd> *native, NetPacket_Fixed<0x00cd> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00e4> *network, Packet_Fixed<0x00e4> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00e4> *native, NetPacket_Fixed<0x00e4> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00e5> *network, Packet_Fixed<0x00e5> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_name, native.char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00e5> *native, NetPacket_Fixed<0x00e5> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_name, network.char_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00e6> *network, Packet_Fixed<0x00e6> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->type, native.type); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00e6> *native, NetPacket_Fixed<0x00e6> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->type, network.type); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00e7> *network, Packet_Fixed<0x00e7> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->type, native.type); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00e7> *native, NetPacket_Fixed<0x00e7> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->type, network.type); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00e8> *network, Packet_Fixed<0x00e8> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->zeny_or_ioff2, native.zeny_or_ioff2); + rv &= native_to_network(&network->amount, native.amount); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00e8> *native, NetPacket_Fixed<0x00e8> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->zeny_or_ioff2, network.zeny_or_ioff2); + rv &= network_to_native(&native->amount, network.amount); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00e9> *network, Packet_Fixed<0x00e9> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->amount, native.amount); + rv &= native_to_network(&network->name_id, native.name_id); + rv &= native_to_network(&network->identify, native.identify); + rv &= native_to_network(&network->broken_or_attribute, native.broken_or_attribute); + rv &= native_to_network(&network->refine, native.refine); + rv &= native_to_network(&network->card0, native.card0); + rv &= native_to_network(&network->card1, native.card1); + rv &= native_to_network(&network->card2, native.card2); + rv &= native_to_network(&network->card3, native.card3); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00e9> *native, NetPacket_Fixed<0x00e9> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->amount, network.amount); + rv &= network_to_native(&native->name_id, network.name_id); + rv &= network_to_native(&native->identify, network.identify); + rv &= network_to_native(&native->broken_or_attribute, network.broken_or_attribute); + rv &= network_to_native(&native->refine, network.refine); + rv &= network_to_native(&native->card0, network.card0); + rv &= network_to_native(&native->card1, network.card1); + rv &= network_to_native(&native->card2, network.card2); + rv &= network_to_native(&native->card3, network.card3); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00eb> *network, Packet_Fixed<0x00eb> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00eb> *native, NetPacket_Fixed<0x00eb> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00ec> *network, Packet_Fixed<0x00ec> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->fail, native.fail); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00ec> *native, NetPacket_Fixed<0x00ec> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->fail, network.fail); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00ed> *network, Packet_Fixed<0x00ed> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00ed> *native, NetPacket_Fixed<0x00ed> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00ee> *network, Packet_Fixed<0x00ee> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00ee> *native, NetPacket_Fixed<0x00ee> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00ef> *network, Packet_Fixed<0x00ef> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00ef> *native, NetPacket_Fixed<0x00ef> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00f0> *network, Packet_Fixed<0x00f0> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->fail, native.fail); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00f0> *native, NetPacket_Fixed<0x00f0> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->fail, network.fail); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00f2> *network, Packet_Fixed<0x00f2> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->current_slots, native.current_slots); + rv &= native_to_network(&network->max_slots, native.max_slots); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00f2> *native, NetPacket_Fixed<0x00f2> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->current_slots, network.current_slots); + rv &= network_to_native(&native->max_slots, network.max_slots); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00f3> *network, Packet_Fixed<0x00f3> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->amount, native.amount); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00f3> *native, NetPacket_Fixed<0x00f3> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->amount, network.amount); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00f4> *network, Packet_Fixed<0x00f4> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->soff1, native.soff1); + rv &= native_to_network(&network->amount, native.amount); + rv &= native_to_network(&network->name_id, native.name_id); + rv &= native_to_network(&network->identify, native.identify); + rv &= native_to_network(&network->broken_or_attribute, native.broken_or_attribute); + rv &= native_to_network(&network->refine, native.refine); + rv &= native_to_network(&network->card0, native.card0); + rv &= native_to_network(&network->card1, native.card1); + rv &= native_to_network(&network->card2, native.card2); + rv &= native_to_network(&network->card3, native.card3); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00f4> *native, NetPacket_Fixed<0x00f4> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->soff1, network.soff1); + rv &= network_to_native(&native->amount, network.amount); + rv &= network_to_native(&native->name_id, network.name_id); + rv &= network_to_native(&native->identify, network.identify); + rv &= network_to_native(&native->broken_or_attribute, network.broken_or_attribute); + rv &= network_to_native(&native->refine, network.refine); + rv &= network_to_native(&native->card0, network.card0); + rv &= network_to_native(&native->card1, network.card1); + rv &= network_to_native(&native->card2, network.card2); + rv &= network_to_native(&native->card3, network.card3); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00f5> *network, Packet_Fixed<0x00f5> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->soff1, native.soff1); + rv &= native_to_network(&network->amount, native.amount); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00f5> *native, NetPacket_Fixed<0x00f5> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->soff1, network.soff1); + rv &= network_to_native(&native->amount, network.amount); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00f6> *network, Packet_Fixed<0x00f6> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->soff1, native.soff1); + rv &= native_to_network(&network->amount, native.amount); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00f6> *native, NetPacket_Fixed<0x00f6> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->soff1, network.soff1); + rv &= network_to_native(&native->amount, network.amount); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00f7> *network, Packet_Fixed<0x00f7> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00f7> *native, NetPacket_Fixed<0x00f7> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00f8> *network, Packet_Fixed<0x00f8> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00f8> *native, NetPacket_Fixed<0x00f8> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00f9> *network, Packet_Fixed<0x00f9> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->party_name, native.party_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00f9> *native, NetPacket_Fixed<0x00f9> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->party_name, network.party_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00fa> *network, Packet_Fixed<0x00fa> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00fa> *native, NetPacket_Fixed<0x00fa> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x00fb> *network, Packet_Head<0x00fb> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->party_name, native.party_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x00fb> *native, NetPacket_Head<0x00fb> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->party_name, network.party_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x00fb> *network, Packet_Repeat<0x00fb> native) +{ + bool rv = true; + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->map_name, native.map_name); + rv &= native_to_network(&network->leader, native.leader); + rv &= native_to_network(&network->online, native.online); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x00fb> *native, NetPacket_Repeat<0x00fb> network) +{ + bool rv = true; + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->map_name, network.map_name); + rv &= network_to_native(&native->leader, network.leader); + rv &= network_to_native(&native->online, network.online); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00fc> *network, Packet_Fixed<0x00fc> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00fc> *native, NetPacket_Fixed<0x00fc> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00fd> *network, Packet_Fixed<0x00fd> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00fd> *native, NetPacket_Fixed<0x00fd> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00fe> *network, Packet_Fixed<0x00fe> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->party_name, native.party_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00fe> *native, NetPacket_Fixed<0x00fe> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->party_name, network.party_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x00ff> *network, Packet_Fixed<0x00ff> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x00ff> *native, NetPacket_Fixed<0x00ff> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0100> *network, Packet_Fixed<0x0100> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0100> *native, NetPacket_Fixed<0x0100> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0101> *network, Packet_Fixed<0x0101> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->exp, native.exp); + rv &= native_to_network(&network->item, native.item); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0101> *native, NetPacket_Fixed<0x0101> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->exp, network.exp); + rv &= network_to_native(&native->item, network.item); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0102> *network, Packet_Fixed<0x0102> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->exp, native.exp); + rv &= native_to_network(&network->item, native.item); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0102> *native, NetPacket_Fixed<0x0102> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->exp, network.exp); + rv &= network_to_native(&native->item, network.item); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0103> *network, Packet_Fixed<0x0103> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->unused_char_name, native.unused_char_name); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0103> *native, NetPacket_Fixed<0x0103> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->unused_char_name, network.unused_char_name); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0105> *network, Packet_Fixed<0x0105> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0105> *native, NetPacket_Fixed<0x0105> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0106> *network, Packet_Fixed<0x0106> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->hp, native.hp); + rv &= native_to_network(&network->max_hp, native.max_hp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0106> *native, NetPacket_Fixed<0x0106> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->hp, network.hp); + rv &= network_to_native(&native->max_hp, network.max_hp); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0107> *network, Packet_Fixed<0x0107> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0107> *native, NetPacket_Fixed<0x0107> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x0108> *network, Packet_Head<0x0108> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x0108> *native, NetPacket_Head<0x0108> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x0108> *network, Packet_Repeat<0x0108> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x0108> *native, NetPacket_Repeat<0x0108> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x0109> *network, Packet_Head<0x0109> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->account_id, native.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x0109> *native, NetPacket_Head<0x0109> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->account_id, network.account_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x0109> *network, Packet_Repeat<0x0109> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x0109> *native, NetPacket_Repeat<0x0109> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x010c> *network, Packet_Fixed<0x010c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x010c> *native, NetPacket_Fixed<0x010c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x010e> *network, Packet_Fixed<0x010e> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->skill_id, native.skill_id); + rv &= native_to_network(&network->level, native.level); + rv &= native_to_network(&network->sp, native.sp); + rv &= native_to_network(&network->range, native.range); + rv &= native_to_network(&network->can_raise, native.can_raise); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x010e> *native, NetPacket_Fixed<0x010e> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->skill_id, network.skill_id); + rv &= network_to_native(&native->level, network.level); + rv &= network_to_native(&native->sp, network.sp); + rv &= network_to_native(&native->range, network.range); + rv &= network_to_native(&native->can_raise, network.can_raise); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x010f> *network, Packet_Head<0x010f> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x010f> *native, NetPacket_Head<0x010f> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x010f> *network, Packet_Repeat<0x010f> native) +{ + bool rv = true; + rv &= native_to_network(&network->info, native.info); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x010f> *native, NetPacket_Repeat<0x010f> network) +{ + bool rv = true; + rv &= network_to_native(&native->info, network.info); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0110> *network, Packet_Fixed<0x0110> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->skill_id, native.skill_id); + rv &= native_to_network(&network->btype, native.btype); + rv &= native_to_network(&network->zero1, native.zero1); + rv &= native_to_network(&network->zero2, native.zero2); + rv &= native_to_network(&network->type, native.type); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0110> *native, NetPacket_Fixed<0x0110> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->skill_id, network.skill_id); + rv &= network_to_native(&native->btype, network.btype); + rv &= network_to_native(&native->zero1, network.zero1); + rv &= network_to_native(&native->zero2, network.zero2); + rv &= network_to_native(&native->type, network.type); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0112> *network, Packet_Fixed<0x0112> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->skill_id, native.skill_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0112> *native, NetPacket_Fixed<0x0112> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->skill_id, network.skill_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0118> *network, Packet_Fixed<0x0118> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0118> *native, NetPacket_Fixed<0x0118> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0119> *network, Packet_Fixed<0x0119> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->opt1, native.opt1); + rv &= native_to_network(&network->opt2, native.opt2); + rv &= native_to_network(&network->option, native.option); + rv &= native_to_network(&network->zero, native.zero); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0119> *native, NetPacket_Fixed<0x0119> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->opt1, network.opt1); + rv &= network_to_native(&native->opt2, network.opt2); + rv &= network_to_native(&native->option, network.option); + rv &= network_to_native(&native->zero, network.zero); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0139> *network, Packet_Fixed<0x0139> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->bl_x, native.bl_x); + rv &= native_to_network(&network->bl_y, native.bl_y); + rv &= native_to_network(&network->sd_x, native.sd_x); + rv &= native_to_network(&network->sd_y, native.sd_y); + rv &= native_to_network(&network->range, native.range); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0139> *native, NetPacket_Fixed<0x0139> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->bl_x, network.bl_x); + rv &= network_to_native(&native->bl_y, network.bl_y); + rv &= network_to_native(&native->sd_x, network.sd_x); + rv &= network_to_native(&native->sd_y, network.sd_y); + rv &= network_to_native(&native->range, network.range); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x013a> *network, Packet_Fixed<0x013a> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->attack_range, native.attack_range); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x013a> *native, NetPacket_Fixed<0x013a> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->attack_range, network.attack_range); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x013b> *network, Packet_Fixed<0x013b> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->type, native.type); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x013b> *native, NetPacket_Fixed<0x013b> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->type, network.type); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x013c> *network, Packet_Fixed<0x013c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x013c> *native, NetPacket_Fixed<0x013c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0141> *network, Packet_Fixed<0x0141> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->sp_type, native.sp_type); + rv &= native_to_network(&network->zero, native.zero); + rv &= native_to_network(&network->value_status, native.value_status); + rv &= native_to_network(&network->value_b_e, native.value_b_e); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0141> *native, NetPacket_Fixed<0x0141> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->sp_type, network.sp_type); + rv &= network_to_native(&native->zero, network.zero); + rv &= network_to_native(&native->value_status, network.value_status); + rv &= network_to_native(&native->value_b_e, network.value_b_e); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0142> *network, Packet_Fixed<0x0142> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0142> *native, NetPacket_Fixed<0x0142> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0143> *network, Packet_Fixed<0x0143> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->input_int_value, native.input_int_value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0143> *native, NetPacket_Fixed<0x0143> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->input_int_value, network.input_int_value); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0146> *network, Packet_Fixed<0x0146> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0146> *native, NetPacket_Fixed<0x0146> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0147> *network, Packet_Fixed<0x0147> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->info, native.info); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0147> *native, NetPacket_Fixed<0x0147> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->info, network.info); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0148> *network, Packet_Fixed<0x0148> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->type, native.type); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0148> *native, NetPacket_Fixed<0x0148> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->type, network.type); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x014d> *network, Packet_Fixed<0x014d> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x014d> *native, NetPacket_Fixed<0x014d> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x018a> *network, Packet_Fixed<0x018a> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->unused, native.unused); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x018a> *native, NetPacket_Fixed<0x018a> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->unused, network.unused); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x018b> *network, Packet_Fixed<0x018b> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->okay, native.okay); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x018b> *native, NetPacket_Fixed<0x018b> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->okay, network.okay); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0195> *network, Packet_Fixed<0x0195> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->party_name, native.party_name); + rv &= native_to_network(&network->guild_name, native.guild_name); + rv &= native_to_network(&network->guild_pos, native.guild_pos); + rv &= native_to_network(&network->guild_pos_again, native.guild_pos_again); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0195> *native, NetPacket_Fixed<0x0195> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->party_name, network.party_name); + rv &= network_to_native(&native->guild_name, network.guild_name); + rv &= network_to_native(&native->guild_pos, network.guild_pos); + rv &= network_to_native(&native->guild_pos_again, network.guild_pos_again); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0196> *network, Packet_Fixed<0x0196> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->sc_type, native.sc_type); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->flag, native.flag); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0196> *native, NetPacket_Fixed<0x0196> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->sc_type, network.sc_type); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->flag, network.flag); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x019b> *network, Packet_Fixed<0x019b> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->type, native.type); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x019b> *native, NetPacket_Fixed<0x019b> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->type, network.type); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x01b1> *network, Packet_Fixed<0x01b1> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->amount, native.amount); + rv &= native_to_network(&network->fail, native.fail); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x01b1> *native, NetPacket_Fixed<0x01b1> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->amount, network.amount); + rv &= network_to_native(&native->fail, network.fail); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x01c8> *network, Packet_Fixed<0x01c8> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->name_id, native.name_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->amount, native.amount); + rv &= native_to_network(&network->ok, native.ok); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x01c8> *native, NetPacket_Fixed<0x01c8> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->name_id, network.name_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->amount, network.amount); + rv &= network_to_native(&native->ok, network.ok); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x01d4> *network, Packet_Fixed<0x01d4> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x01d4> *native, NetPacket_Fixed<0x01d4> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x01d5> *network, Packet_Head<0x01d5> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + rv &= native_to_network(&network->block_id, native.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x01d5> *native, NetPacket_Head<0x01d5> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + rv &= network_to_native(&native->block_id, network.block_id); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x01d5> *network, Packet_Repeat<0x01d5> native) +{ + bool rv = true; + rv &= native_to_network(&network->c, native.c); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x01d5> *native, NetPacket_Repeat<0x01d5> network) +{ + bool rv = true; + rv &= network_to_native(&native->c, network.c); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x01d7> *network, Packet_Fixed<0x01d7> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->look_type, native.look_type); + rv &= native_to_network(&network->weapon_or_name_id_or_value, native.weapon_or_name_id_or_value); + rv &= native_to_network(&network->shield, native.shield); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x01d7> *native, NetPacket_Fixed<0x01d7> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->look_type, network.look_type); + rv &= network_to_native(&native->weapon_or_name_id_or_value, network.weapon_or_name_id_or_value); + rv &= network_to_native(&native->shield, network.shield); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x01d8> *network, Packet_Fixed<0x01d8> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->speed, native.speed); + rv &= native_to_network(&network->opt1, native.opt1); + rv &= native_to_network(&network->opt2, native.opt2); + rv &= native_to_network(&network->option, native.option); + rv &= native_to_network(&network->species, native.species); + rv &= native_to_network(&network->hair_style, native.hair_style); + rv &= native_to_network(&network->weapon, native.weapon); + rv &= native_to_network(&network->shield, native.shield); + rv &= native_to_network(&network->head_bottom, native.head_bottom); + rv &= native_to_network(&network->head_top, native.head_top); + rv &= native_to_network(&network->head_mid, native.head_mid); + rv &= native_to_network(&network->hair_color, native.hair_color); + rv &= native_to_network(&network->clothes_color, native.clothes_color); + rv &= native_to_network(&network->head_dir, native.head_dir); + rv &= native_to_network(&network->unused2, native.unused2); + rv &= native_to_network(&network->guild_id, native.guild_id); + rv &= native_to_network(&network->guild_emblem_id, native.guild_emblem_id); + rv &= native_to_network(&network->manner, native.manner); + rv &= native_to_network(&network->opt3, native.opt3); + rv &= native_to_network(&network->karma, native.karma); + rv &= native_to_network(&network->sex, native.sex); + rv &= native_to_network(&network->pos, native.pos); + rv &= native_to_network(&network->gm_bits, native.gm_bits); + rv &= native_to_network(&network->dead_sit, native.dead_sit); + rv &= native_to_network(&network->unused, native.unused); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x01d8> *native, NetPacket_Fixed<0x01d8> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->speed, network.speed); + rv &= network_to_native(&native->opt1, network.opt1); + rv &= network_to_native(&native->opt2, network.opt2); + rv &= network_to_native(&native->option, network.option); + rv &= network_to_native(&native->species, network.species); + rv &= network_to_native(&native->hair_style, network.hair_style); + rv &= network_to_native(&native->weapon, network.weapon); + rv &= network_to_native(&native->shield, network.shield); + rv &= network_to_native(&native->head_bottom, network.head_bottom); + rv &= network_to_native(&native->head_top, network.head_top); + rv &= network_to_native(&native->head_mid, network.head_mid); + rv &= network_to_native(&native->hair_color, network.hair_color); + rv &= network_to_native(&native->clothes_color, network.clothes_color); + rv &= network_to_native(&native->head_dir, network.head_dir); + rv &= network_to_native(&native->unused2, network.unused2); + rv &= network_to_native(&native->guild_id, network.guild_id); + rv &= network_to_native(&native->guild_emblem_id, network.guild_emblem_id); + rv &= network_to_native(&native->manner, network.manner); + rv &= network_to_native(&native->opt3, network.opt3); + rv &= network_to_native(&native->karma, network.karma); + rv &= network_to_native(&native->sex, network.sex); + rv &= network_to_native(&native->pos, network.pos); + rv &= network_to_native(&native->gm_bits, network.gm_bits); + rv &= network_to_native(&native->dead_sit, network.dead_sit); + rv &= network_to_native(&native->unused, network.unused); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x01d9> *network, Packet_Fixed<0x01d9> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->speed, native.speed); + rv &= native_to_network(&network->opt1, native.opt1); + rv &= native_to_network(&network->opt2, native.opt2); + rv &= native_to_network(&network->option, native.option); + rv &= native_to_network(&network->species, native.species); + rv &= native_to_network(&network->hair_style, native.hair_style); + rv &= native_to_network(&network->weapon, native.weapon); + rv &= native_to_network(&network->shield, native.shield); + rv &= native_to_network(&network->head_bottom, native.head_bottom); + rv &= native_to_network(&network->head_top, native.head_top); + rv &= native_to_network(&network->head_mid, native.head_mid); + rv &= native_to_network(&network->hair_color, native.hair_color); + rv &= native_to_network(&network->clothes_color, native.clothes_color); + rv &= native_to_network(&network->head_dir, native.head_dir); + rv &= native_to_network(&network->unused2, native.unused2); + rv &= native_to_network(&network->guild_id, native.guild_id); + rv &= native_to_network(&network->guild_emblem_id, native.guild_emblem_id); + rv &= native_to_network(&network->manner, native.manner); + rv &= native_to_network(&network->opt3, native.opt3); + rv &= native_to_network(&network->karma, native.karma); + rv &= native_to_network(&network->sex, native.sex); + rv &= native_to_network(&network->pos, native.pos); + rv &= native_to_network(&network->gm_bits, native.gm_bits); + rv &= native_to_network(&network->unused, native.unused); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x01d9> *native, NetPacket_Fixed<0x01d9> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->speed, network.speed); + rv &= network_to_native(&native->opt1, network.opt1); + rv &= network_to_native(&native->opt2, network.opt2); + rv &= network_to_native(&native->option, network.option); + rv &= network_to_native(&native->species, network.species); + rv &= network_to_native(&native->hair_style, network.hair_style); + rv &= network_to_native(&native->weapon, network.weapon); + rv &= network_to_native(&native->shield, network.shield); + rv &= network_to_native(&native->head_bottom, network.head_bottom); + rv &= network_to_native(&native->head_top, network.head_top); + rv &= network_to_native(&native->head_mid, network.head_mid); + rv &= network_to_native(&native->hair_color, network.hair_color); + rv &= network_to_native(&native->clothes_color, network.clothes_color); + rv &= network_to_native(&native->head_dir, network.head_dir); + rv &= network_to_native(&native->unused2, network.unused2); + rv &= network_to_native(&native->guild_id, network.guild_id); + rv &= network_to_native(&native->guild_emblem_id, network.guild_emblem_id); + rv &= network_to_native(&native->manner, network.manner); + rv &= network_to_native(&native->opt3, network.opt3); + rv &= network_to_native(&native->karma, network.karma); + rv &= network_to_native(&native->sex, network.sex); + rv &= network_to_native(&native->pos, network.pos); + rv &= network_to_native(&native->gm_bits, network.gm_bits); + rv &= network_to_native(&native->unused, network.unused); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x01da> *network, Packet_Fixed<0x01da> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->speed, native.speed); + rv &= native_to_network(&network->opt1, native.opt1); + rv &= native_to_network(&network->opt2, native.opt2); + rv &= native_to_network(&network->option, native.option); + rv &= native_to_network(&network->species, native.species); + rv &= native_to_network(&network->hair_style, native.hair_style); + rv &= native_to_network(&network->weapon, native.weapon); + rv &= native_to_network(&network->shield, native.shield); + rv &= native_to_network(&network->head_bottom, native.head_bottom); + rv &= native_to_network(&network->tick, native.tick); + rv &= native_to_network(&network->head_top, native.head_top); + rv &= native_to_network(&network->head_mid, native.head_mid); + rv &= native_to_network(&network->hair_color, native.hair_color); + rv &= native_to_network(&network->clothes_color, native.clothes_color); + rv &= native_to_network(&network->head_dir, native.head_dir); + rv &= native_to_network(&network->unused2, native.unused2); + rv &= native_to_network(&network->guild_id, native.guild_id); + rv &= native_to_network(&network->guild_emblem_id, native.guild_emblem_id); + rv &= native_to_network(&network->manner, native.manner); + rv &= native_to_network(&network->opt3, native.opt3); + rv &= native_to_network(&network->karma, native.karma); + rv &= native_to_network(&network->sex, native.sex); + rv &= native_to_network(&network->pos2, native.pos2); + rv &= native_to_network(&network->gm_bits, native.gm_bits); + rv &= native_to_network(&network->five, native.five); + rv &= native_to_network(&network->unused, native.unused); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x01da> *native, NetPacket_Fixed<0x01da> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->speed, network.speed); + rv &= network_to_native(&native->opt1, network.opt1); + rv &= network_to_native(&native->opt2, network.opt2); + rv &= network_to_native(&native->option, network.option); + rv &= network_to_native(&native->species, network.species); + rv &= network_to_native(&native->hair_style, network.hair_style); + rv &= network_to_native(&native->weapon, network.weapon); + rv &= network_to_native(&native->shield, network.shield); + rv &= network_to_native(&native->head_bottom, network.head_bottom); + rv &= network_to_native(&native->tick, network.tick); + rv &= network_to_native(&native->head_top, network.head_top); + rv &= network_to_native(&native->head_mid, network.head_mid); + rv &= network_to_native(&native->hair_color, network.hair_color); + rv &= network_to_native(&native->clothes_color, network.clothes_color); + rv &= network_to_native(&native->head_dir, network.head_dir); + rv &= network_to_native(&native->unused2, network.unused2); + rv &= network_to_native(&native->guild_id, network.guild_id); + rv &= network_to_native(&native->guild_emblem_id, network.guild_emblem_id); + rv &= network_to_native(&native->manner, network.manner); + rv &= network_to_native(&native->opt3, network.opt3); + rv &= network_to_native(&native->karma, network.karma); + rv &= network_to_native(&native->sex, network.sex); + rv &= network_to_native(&native->pos2, network.pos2); + rv &= network_to_native(&native->gm_bits, network.gm_bits); + rv &= network_to_native(&native->five, network.five); + rv &= network_to_native(&native->unused, network.unused); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x01de> *network, Packet_Fixed<0x01de> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->skill_id, native.skill_id); + rv &= native_to_network(&network->src_id, native.src_id); + rv &= native_to_network(&network->dst_id, native.dst_id); + rv &= native_to_network(&network->tick, native.tick); + rv &= native_to_network(&network->sdelay, native.sdelay); + rv &= native_to_network(&network->ddelay, native.ddelay); + rv &= native_to_network(&network->damage, native.damage); + rv &= native_to_network(&network->skill_level, native.skill_level); + rv &= native_to_network(&network->div, native.div); + rv &= native_to_network(&network->type_or_hit, native.type_or_hit); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x01de> *native, NetPacket_Fixed<0x01de> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->skill_id, network.skill_id); + rv &= network_to_native(&native->src_id, network.src_id); + rv &= network_to_native(&native->dst_id, network.dst_id); + rv &= network_to_native(&native->tick, network.tick); + rv &= network_to_native(&native->sdelay, network.sdelay); + rv &= network_to_native(&native->ddelay, network.ddelay); + rv &= network_to_native(&native->damage, network.damage); + rv &= network_to_native(&native->skill_level, network.skill_level); + rv &= network_to_native(&native->div, network.div); + rv &= network_to_native(&native->type_or_hit, network.type_or_hit); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x01ee> *network, Packet_Head<0x01ee> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x01ee> *native, NetPacket_Head<0x01ee> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x01ee> *network, Packet_Repeat<0x01ee> native) +{ + bool rv = true; + rv &= native_to_network(&network->ioff2, native.ioff2); + rv &= native_to_network(&network->name_id, native.name_id); + rv &= native_to_network(&network->item_type, native.item_type); + rv &= native_to_network(&network->identify, native.identify); + rv &= native_to_network(&network->amount, native.amount); + rv &= native_to_network(&network->epos, native.epos); + rv &= native_to_network(&network->card0, native.card0); + rv &= native_to_network(&network->card1, native.card1); + rv &= native_to_network(&network->card2, native.card2); + rv &= native_to_network(&network->card3, native.card3); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x01ee> *native, NetPacket_Repeat<0x01ee> network) +{ + bool rv = true; + rv &= network_to_native(&native->ioff2, network.ioff2); + rv &= network_to_native(&native->name_id, network.name_id); + rv &= network_to_native(&native->item_type, network.item_type); + rv &= network_to_native(&native->identify, network.identify); + rv &= network_to_native(&native->amount, network.amount); + rv &= network_to_native(&native->epos, network.epos); + rv &= network_to_native(&native->card0, network.card0); + rv &= network_to_native(&native->card1, network.card1); + rv &= network_to_native(&native->card2, network.card2); + rv &= network_to_native(&native->card3, network.card3); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Head<0x01f0> *network, Packet_Head<0x01f0> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->magic_packet_length, native.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Head<0x01f0> *native, NetPacket_Head<0x01f0> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->magic_packet_length, network.magic_packet_length); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Repeat<0x01f0> *network, Packet_Repeat<0x01f0> native) +{ + bool rv = true; + rv &= native_to_network(&network->soff1, native.soff1); + rv &= native_to_network(&network->name_id, native.name_id); + rv &= native_to_network(&network->item_type, native.item_type); + rv &= native_to_network(&network->identify, native.identify); + rv &= native_to_network(&network->amount, native.amount); + rv &= native_to_network(&network->epos_zero, native.epos_zero); + rv &= native_to_network(&network->card0, native.card0); + rv &= native_to_network(&network->card1, native.card1); + rv &= native_to_network(&network->card2, native.card2); + rv &= native_to_network(&network->card3, native.card3); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Repeat<0x01f0> *native, NetPacket_Repeat<0x01f0> network) +{ + bool rv = true; + rv &= network_to_native(&native->soff1, network.soff1); + rv &= network_to_native(&native->name_id, network.name_id); + rv &= network_to_native(&native->item_type, network.item_type); + rv &= network_to_native(&native->identify, network.identify); + rv &= network_to_native(&native->amount, network.amount); + rv &= network_to_native(&native->epos_zero, network.epos_zero); + rv &= network_to_native(&native->card0, network.card0); + rv &= network_to_native(&native->card1, network.card1); + rv &= network_to_native(&native->card2, network.card2); + rv &= network_to_native(&native->card3, network.card3); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x020c> *network, Packet_Fixed<0x020c> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->block_id, native.block_id); + rv &= native_to_network(&network->ip, native.ip); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x020c> *native, NetPacket_Fixed<0x020c> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->block_id, network.block_id); + rv &= network_to_native(&native->ip, network.ip); + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPacket_Fixed<0x0212> *network, Packet_Fixed<0x0212> native) +{ + bool rv = true; + rv &= native_to_network(&network->magic_packet_id, native.magic_packet_id); + rv &= native_to_network(&network->npc_id, native.npc_id); + rv &= native_to_network(&network->command, native.command); + rv &= native_to_network(&network->id, native.id); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Packet_Fixed<0x0212> *native, NetPacket_Fixed<0x0212> network) +{ + bool rv = true; + rv &= network_to_native(&native->magic_packet_id, network.magic_packet_id); + rv &= network_to_native(&native->npc_id, network.npc_id); + rv &= network_to_native(&native->command, network.command); + rv &= network_to_native(&native->id, network.id); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + return rv; +} + +} // namespace tmwa diff --git a/src/proto2/map-user_test.cpp b/src/proto2/map-user_test.cpp new file mode 100644 index 0000000..75d39d5 --- /dev/null +++ b/src/proto2/map-user_test.cpp @@ -0,0 +1,27 @@ +#include "map-user.hpp" +// map-user_test.cpp - TMWA network protocol: map/user +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +// This is a generated file, edit tools/protocol.py instead + +#include "../poison.hpp" + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/proto2/types.hpp b/src/proto2/types.hpp new file mode 100644 index 0000000..516889a --- /dev/null +++ b/src/proto2/types.hpp @@ -0,0 +1,1421 @@ +#pragma once +// proto2/types.hpp - Forward declarations of packet component types +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include "../generic/array.hpp" +#include "../mmo/consts.hpp" + +//TODO split the includes +#include <cstdint> +#include "../ints/little.hpp" +#include "../strings/vstring.hpp" +#include "../net/ip.hpp" +#include "../net/timer.t.hpp" +#include "../mmo/consts.hpp" +#include "../mmo/enums.hpp" +#include "../mmo/human_time_diff.hpp" +#include "../mmo/ids.hpp" +#include "../mmo/strs.hpp" +#include "../mmo/utils.hpp" +#include "../mmo/version.hpp" +#include "../login/login.t.hpp" +#include "../map/clif.t.hpp" +#include "../map/skill.t.hpp" + +namespace tmwa +{ +template<class T> +bool native_to_network(T *network, T native) +{ + *network = native; + return true; +} +template<class T> +bool network_to_native(T *native, T network) +{ + *native = network; + return true; +} +template<class T, size_t N> +struct NetArray +{ + T data[N]; +}; +template<class T, class U, class I> +bool native_to_network(NetArray<T, I::alloc_size> *network, GenericArray<U, I> native) +{ + for (size_t i = 0; i < I::alloc_size; ++i) + { + if (!native_to_network(&(*network).data[i], native[I::offset_to_index(i)])) + return false; + } + return true; +} +template<class T, class U, class I> +bool network_to_native(GenericArray<U, I> *native, NetArray<T, I::alloc_size> network) +{ + for (size_t i = 0; i < I::alloc_size; ++i) + { + if (!network_to_native(&(*native)[I::offset_to_index(i)], network.data[i])) + return false; + } + return true; +} + +template<size_t N> +struct NetString +{ + char data[N]; +}; +template<size_t N> +bool native_to_network(NetString<N> *network, VString<N-1> native) +{ + // basically WBUF_STRING + char *const begin = network->data; + char *const end = begin + N; + char *const mid = std::copy(native.begin(), native.end(), begin); + std::fill(mid, end, '\0'); + return true; +} +template<size_t N> +bool network_to_native(VString<N-1> *native, NetString<N> network) +{ + // basically RBUF_STRING + const char *const begin = network.data; + const char *const end = begin + N; + const char *const mid = std::find(begin, end, '\0'); + *native = XString(begin, mid, nullptr); + return true; +} + +inline +bool native_to_network(NetString<24> *network, CharName native) +{ + VString<23> tmp = native.to__actual(); + bool rv = native_to_network(network, tmp); + return rv; +} +inline +bool network_to_native(CharName *native, NetString<24> network) +{ + VString<23> tmp; + bool rv = network_to_native(&tmp, network); + *native = stringish<CharName>(tmp); + return rv; +} + +inline +bool native_to_network(NetString<16> *network, MapName native) +{ + XString tmp = native; + bool rv = native_to_network(network, VString<15>(tmp)); + return rv; +} +inline +bool network_to_native(MapName *native, NetString<16> network) +{ + VString<15> tmp; + bool rv = network_to_native(&tmp, network); + *native = stringish<MapName>(tmp); + return rv; +} + +template<class T, size_t N> +struct SkewedLength +{ + T data; +}; +template<class T, size_t N, class U> +bool native_to_network(SkewedLength<T, N> *network, U native) +{ + native -= N; + return native_to_network(&network->data, native); +} +template<class T, size_t N, class U> +bool network_to_native(U *native, SkewedLength<T, N> network) +{ + bool rv = network_to_native(native, network.data); + *native += N; + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(Byte *network, DIR native) +{ + bool rv = true; + uint8_t tmp = static_cast<uint8_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(DIR *native, Byte network) +{ + bool rv = true; + uint8_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<DIR>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Byte *network, BeingRemoveWhy native) +{ + bool rv = true; + uint8_t tmp = static_cast<uint8_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(BeingRemoveWhy *native, Byte network) +{ + bool rv = true; + uint8_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<BeingRemoveWhy>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, Opt1 native) +{ + bool rv = true; + uint16_t tmp = static_cast<uint16_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Opt1 *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<Opt1>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, Opt2 native) +{ + bool rv = true; + uint16_t tmp = static_cast<uint16_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Opt2 *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<Opt2>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, Opt3 native) +{ + bool rv = true; + uint16_t tmp = static_cast<uint16_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Opt3 *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<Opt3>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Byte *network, ItemType native) +{ + bool rv = true; + uint8_t tmp = static_cast<uint8_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(ItemType *native, Byte network) +{ + bool rv = true; + uint8_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<ItemType>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Byte *network, PickupFail native) +{ + bool rv = true; + uint8_t tmp = static_cast<uint8_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(PickupFail *native, Byte network) +{ + bool rv = true; + uint8_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<PickupFail>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Byte *network, DamageType native) +{ + bool rv = true; + uint8_t tmp = static_cast<uint8_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(DamageType *native, Byte network) +{ + bool rv = true; + uint8_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<DamageType>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, SP native) +{ + bool rv = true; + uint16_t tmp = static_cast<uint16_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(SP *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<SP>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Byte *network, LOOK native) +{ + bool rv = true; + uint8_t tmp = static_cast<uint8_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(LOOK *native, Byte network) +{ + bool rv = true; + uint8_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<LOOK>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, SkillID native) +{ + bool rv = true; + uint16_t tmp = static_cast<uint16_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(SkillID *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<SkillID>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, StatusChange native) +{ + bool rv = true; + uint16_t tmp = static_cast<uint16_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(StatusChange *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<StatusChange>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, SkillFlags native) +{ + bool rv = true; + uint16_t tmp = static_cast<uint16_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(SkillFlags *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<SkillFlags>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Byte *network, SEX native) +{ + bool rv = true; + uint8_t tmp = static_cast<uint8_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(SEX *native, Byte network) +{ + bool rv = true; + uint8_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<SEX>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, Option native) +{ + bool rv = true; + uint16_t tmp = static_cast<uint16_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Option *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<Option>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, EPOS native) +{ + bool rv = true; + uint16_t tmp = static_cast<uint16_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(EPOS *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<EPOS>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, ItemLook native) +{ + bool rv = true; + uint16_t tmp = static_cast<uint16_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(ItemLook *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<ItemLook>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, Species native) +{ + bool rv = true; + uint16_t tmp = unwrap<Species>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Species *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = wrap<Species>(tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little32 *network, AccountId native) +{ + bool rv = true; + uint32_t tmp = unwrap<AccountId>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(AccountId *native, Little32 network) +{ + bool rv = true; + uint32_t tmp; + rv &= network_to_native(&tmp, network); + *native = wrap<AccountId>(tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little32 *network, CharId native) +{ + bool rv = true; + uint32_t tmp = unwrap<CharId>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(CharId *native, Little32 network) +{ + bool rv = true; + uint32_t tmp; + rv &= network_to_native(&tmp, network); + *native = wrap<CharId>(tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little32 *network, PartyId native) +{ + bool rv = true; + uint32_t tmp = unwrap<PartyId>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(PartyId *native, Little32 network) +{ + bool rv = true; + uint32_t tmp; + rv &= network_to_native(&tmp, network); + *native = wrap<PartyId>(tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little16 *network, ItemNameId native) +{ + bool rv = true; + uint16_t tmp = unwrap<ItemNameId>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(ItemNameId *native, Little16 network) +{ + bool rv = true; + uint16_t tmp; + rv &= network_to_native(&tmp, network); + *native = wrap<ItemNameId>(tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little32 *network, ItemNameId native) +{ + bool rv = true; + uint32_t tmp = unwrap<ItemNameId>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(ItemNameId *native, Little32 network) +{ + bool rv = true; + uint32_t tmp; + rv &= network_to_native(&tmp, network); + *native = wrap<ItemNameId>(tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool native_to_network(Little32 *network, BlockId native) +{ + bool rv = true; + uint32_t tmp = unwrap<BlockId>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(BlockId *native, Little32 network) +{ + bool rv = true; + uint32_t tmp; + rv &= network_to_native(&tmp, network); + *native = wrap<BlockId>(tmp); + return rv; +} +struct NetHumanTimeDiff +{ + Little16 year; + Little16 month; + Little16 day; + Little16 hour; + Little16 minute; + Little16 second; +}; +inline __attribute__((warn_unused_result)) +bool native_to_network(NetHumanTimeDiff *network, HumanTimeDiff native) +{ + bool rv = true; + int16_t year = native.year; rv &= native_to_network(&network->year, year); + int16_t month = native.month; rv &= native_to_network(&network->month, month); + int16_t day = native.day; rv &= native_to_network(&network->day, day); + int16_t hour = native.hour; rv &= native_to_network(&network->hour, hour); + int16_t minute = native.minute; rv &= native_to_network(&network->minute, minute); + int16_t second = native.second; rv &= native_to_network(&network->second, second); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(HumanTimeDiff *native, NetHumanTimeDiff network) +{ + bool rv = true; + int16_t year; rv &= network_to_native(&year, network.year); native->year = year; + int16_t month; rv &= network_to_native(&month, network.month); native->month = month; + int16_t day; rv &= network_to_native(&day, network.day); native->day = day; + int16_t hour; rv &= network_to_native(&hour, network.hour); native->hour = hour; + int16_t minute; rv &= network_to_native(&minute, network.minute); native->minute = minute; + int16_t second; rv &= network_to_native(&second, network.second); native->second = second; + return rv; +} + +struct NetVersion +{ + Byte major; + Byte minor; + Byte patch; + Byte devel; + Byte flags; + Byte which; + Little16 vend; +}; +inline __attribute__((warn_unused_result)) +bool native_to_network(NetVersion *network, Version native) +{ + bool rv = true; + uint8_t major = native.major; rv &= native_to_network(&network->major, major); + uint8_t minor = native.minor; rv &= native_to_network(&network->minor, minor); + uint8_t patch = native.patch; rv &= native_to_network(&network->patch, patch); + uint8_t devel = native.devel; rv &= native_to_network(&network->devel, devel); + uint8_t flags = native.flags; rv &= native_to_network(&network->flags, flags); + uint8_t which = native.which; rv &= native_to_network(&network->which, which); + uint16_t vend = native.vend; rv &= native_to_network(&network->vend, vend); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Version *native, NetVersion network) +{ + bool rv = true; + uint8_t major; rv &= network_to_native(&major, network.major); native->major = major; + uint8_t minor; rv &= network_to_native(&minor, network.minor); native->minor = minor; + uint8_t patch; rv &= network_to_native(&patch, network.patch); native->patch = patch; + uint8_t devel; rv &= network_to_native(&devel, network.devel); native->devel = devel; + uint8_t flags; rv &= network_to_native(&flags, network.flags); native->flags = flags; + uint8_t which; rv &= network_to_native(&which, network.which); native->which = which; + uint16_t vend; rv &= network_to_native(&vend, network.vend); native->vend = vend; + return rv; +} + +inline __attribute__((warn_unused_result)) +bool native_to_network(Byte *network, VERSION_2 native) +{ + bool rv = true; + uint8_t tmp = static_cast<uint8_t>(native); + rv &= native_to_network(network, tmp); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(VERSION_2 *native, Byte network) +{ + bool rv = true; + uint8_t tmp; + rv &= network_to_native(&tmp, network); + *native = static_cast<VERSION_2>(tmp); + // TODO this is what really should be doing a checked cast + return rv; +} +struct Stats6 +{ + uint8_t str = {}; + uint8_t agi = {}; + uint8_t vit = {}; + uint8_t int_ = {}; + uint8_t dex = {}; + uint8_t luk = {}; +}; +struct NetStats6 +{ + Byte str; + Byte agi; + Byte vit; + Byte int_; + Byte dex; + Byte luk; +}; +static_assert(offsetof(NetStats6, str) == 0, "offsetof(NetStats6, str) == 0"); +static_assert(offsetof(NetStats6, agi) == 1, "offsetof(NetStats6, agi) == 1"); +static_assert(offsetof(NetStats6, vit) == 2, "offsetof(NetStats6, vit) == 2"); +static_assert(offsetof(NetStats6, int_) == 3, "offsetof(NetStats6, int_) == 3"); +static_assert(offsetof(NetStats6, dex) == 4, "offsetof(NetStats6, dex) == 4"); +static_assert(offsetof(NetStats6, luk) == 5, "offsetof(NetStats6, luk) == 5"); +static_assert(sizeof(NetStats6) == 6, "sizeof(NetStats6) == 6"); +static_assert(alignof(NetStats6) == 1, "alignof(NetStats6) == 1"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetStats6 *network, Stats6 native) +{ + bool rv = true; + rv &= native_to_network(&network->str, native.str); + rv &= native_to_network(&network->agi, native.agi); + rv &= native_to_network(&network->vit, native.vit); + rv &= native_to_network(&network->int_, native.int_); + rv &= native_to_network(&network->dex, native.dex); + rv &= native_to_network(&network->luk, native.luk); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Stats6 *native, NetStats6 network) +{ + bool rv = true; + rv &= network_to_native(&native->str, network.str); + rv &= network_to_native(&native->agi, network.agi); + rv &= network_to_native(&native->vit, network.vit); + rv &= network_to_native(&native->int_, network.int_); + rv &= network_to_native(&native->dex, network.dex); + rv &= network_to_native(&native->luk, network.luk); + return rv; +} + +struct CharSelect +{ + CharId char_id = {}; + uint32_t base_exp = {}; + uint32_t zeny = {}; + uint32_t job_exp = {}; + uint32_t job_level = {}; + ItemNameId shoes = {}; + ItemNameId gloves = {}; + ItemNameId cape = {}; + ItemNameId misc1 = {}; + Option option = {}; + uint16_t unused = {}; + uint32_t karma = {}; + uint32_t manner = {}; + uint16_t status_point = {}; + uint16_t hp = {}; + uint16_t max_hp = {}; + uint16_t sp = {}; + uint16_t max_sp = {}; + uint16_t speed = {}; + Species species = {}; + uint16_t hair_style = {}; + uint16_t weapon = {}; + uint16_t base_level = {}; + uint16_t skill_point = {}; + ItemNameId head_bottom = {}; + ItemNameId shield = {}; + ItemNameId head_top = {}; + ItemNameId head_mid = {}; + uint16_t hair_color = {}; + ItemNameId misc2 = {}; + CharName char_name = {}; + Stats6 stats = {}; + uint8_t char_num = {}; + uint8_t unused2 = {}; +}; +struct NetCharSelect +{ + Little32 char_id; + Little32 base_exp; + Little32 zeny; + Little32 job_exp; + Little32 job_level; + Little16 shoes; + Little16 gloves; + Little16 cape; + Little16 misc1; + Little16 option; + Little16 unused; + Little32 karma; + Little32 manner; + Little16 status_point; + Little16 hp; + Little16 max_hp; + Little16 sp; + Little16 max_sp; + Little16 speed; + Little16 species; + Little16 hair_style; + Little16 weapon; + Little16 base_level; + Little16 skill_point; + Little16 head_bottom; + Little16 shield; + Little16 head_top; + Little16 head_mid; + Little16 hair_color; + Little16 misc2; + NetString<sizeof(CharName)> char_name; + NetStats6 stats; + Byte char_num; + Byte unused2; +}; +static_assert(offsetof(NetCharSelect, char_id) == 0, "offsetof(NetCharSelect, char_id) == 0"); +static_assert(offsetof(NetCharSelect, base_exp) == 4, "offsetof(NetCharSelect, base_exp) == 4"); +static_assert(offsetof(NetCharSelect, zeny) == 8, "offsetof(NetCharSelect, zeny) == 8"); +static_assert(offsetof(NetCharSelect, job_exp) == 12, "offsetof(NetCharSelect, job_exp) == 12"); +static_assert(offsetof(NetCharSelect, job_level) == 16, "offsetof(NetCharSelect, job_level) == 16"); +static_assert(offsetof(NetCharSelect, shoes) == 20, "offsetof(NetCharSelect, shoes) == 20"); +static_assert(offsetof(NetCharSelect, gloves) == 22, "offsetof(NetCharSelect, gloves) == 22"); +static_assert(offsetof(NetCharSelect, cape) == 24, "offsetof(NetCharSelect, cape) == 24"); +static_assert(offsetof(NetCharSelect, misc1) == 26, "offsetof(NetCharSelect, misc1) == 26"); +static_assert(offsetof(NetCharSelect, option) == 28, "offsetof(NetCharSelect, option) == 28"); +static_assert(offsetof(NetCharSelect, unused) == 30, "offsetof(NetCharSelect, unused) == 30"); +static_assert(offsetof(NetCharSelect, karma) == 32, "offsetof(NetCharSelect, karma) == 32"); +static_assert(offsetof(NetCharSelect, manner) == 36, "offsetof(NetCharSelect, manner) == 36"); +static_assert(offsetof(NetCharSelect, status_point) == 40, "offsetof(NetCharSelect, status_point) == 40"); +static_assert(offsetof(NetCharSelect, hp) == 42, "offsetof(NetCharSelect, hp) == 42"); +static_assert(offsetof(NetCharSelect, max_hp) == 44, "offsetof(NetCharSelect, max_hp) == 44"); +static_assert(offsetof(NetCharSelect, sp) == 46, "offsetof(NetCharSelect, sp) == 46"); +static_assert(offsetof(NetCharSelect, max_sp) == 48, "offsetof(NetCharSelect, max_sp) == 48"); +static_assert(offsetof(NetCharSelect, speed) == 50, "offsetof(NetCharSelect, speed) == 50"); +static_assert(offsetof(NetCharSelect, species) == 52, "offsetof(NetCharSelect, species) == 52"); +static_assert(offsetof(NetCharSelect, hair_style) == 54, "offsetof(NetCharSelect, hair_style) == 54"); +static_assert(offsetof(NetCharSelect, weapon) == 56, "offsetof(NetCharSelect, weapon) == 56"); +static_assert(offsetof(NetCharSelect, base_level) == 58, "offsetof(NetCharSelect, base_level) == 58"); +static_assert(offsetof(NetCharSelect, skill_point) == 60, "offsetof(NetCharSelect, skill_point) == 60"); +static_assert(offsetof(NetCharSelect, head_bottom) == 62, "offsetof(NetCharSelect, head_bottom) == 62"); +static_assert(offsetof(NetCharSelect, shield) == 64, "offsetof(NetCharSelect, shield) == 64"); +static_assert(offsetof(NetCharSelect, head_top) == 66, "offsetof(NetCharSelect, head_top) == 66"); +static_assert(offsetof(NetCharSelect, head_mid) == 68, "offsetof(NetCharSelect, head_mid) == 68"); +static_assert(offsetof(NetCharSelect, hair_color) == 70, "offsetof(NetCharSelect, hair_color) == 70"); +static_assert(offsetof(NetCharSelect, misc2) == 72, "offsetof(NetCharSelect, misc2) == 72"); +static_assert(offsetof(NetCharSelect, char_name) == 74, "offsetof(NetCharSelect, char_name) == 74"); +static_assert(offsetof(NetCharSelect, stats) == 98, "offsetof(NetCharSelect, stats) == 98"); +static_assert(offsetof(NetCharSelect, char_num) == 104, "offsetof(NetCharSelect, char_num) == 104"); +static_assert(offsetof(NetCharSelect, unused2) == 105, "offsetof(NetCharSelect, unused2) == 105"); +static_assert(sizeof(NetCharSelect) == 106, "sizeof(NetCharSelect) == 106"); +static_assert(alignof(NetCharSelect) == 1, "alignof(NetCharSelect) == 1"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetCharSelect *network, CharSelect native) +{ + bool rv = true; + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->base_exp, native.base_exp); + rv &= native_to_network(&network->zeny, native.zeny); + rv &= native_to_network(&network->job_exp, native.job_exp); + rv &= native_to_network(&network->job_level, native.job_level); + rv &= native_to_network(&network->shoes, native.shoes); + rv &= native_to_network(&network->gloves, native.gloves); + rv &= native_to_network(&network->cape, native.cape); + rv &= native_to_network(&network->misc1, native.misc1); + rv &= native_to_network(&network->option, native.option); + rv &= native_to_network(&network->unused, native.unused); + rv &= native_to_network(&network->karma, native.karma); + rv &= native_to_network(&network->manner, native.manner); + rv &= native_to_network(&network->status_point, native.status_point); + rv &= native_to_network(&network->hp, native.hp); + rv &= native_to_network(&network->max_hp, native.max_hp); + rv &= native_to_network(&network->sp, native.sp); + rv &= native_to_network(&network->max_sp, native.max_sp); + rv &= native_to_network(&network->speed, native.speed); + rv &= native_to_network(&network->species, native.species); + rv &= native_to_network(&network->hair_style, native.hair_style); + rv &= native_to_network(&network->weapon, native.weapon); + rv &= native_to_network(&network->base_level, native.base_level); + rv &= native_to_network(&network->skill_point, native.skill_point); + rv &= native_to_network(&network->head_bottom, native.head_bottom); + rv &= native_to_network(&network->shield, native.shield); + rv &= native_to_network(&network->head_top, native.head_top); + rv &= native_to_network(&network->head_mid, native.head_mid); + rv &= native_to_network(&network->hair_color, native.hair_color); + rv &= native_to_network(&network->misc2, native.misc2); + rv &= native_to_network(&network->char_name, native.char_name); + rv &= native_to_network(&network->stats, native.stats); + rv &= native_to_network(&network->char_num, native.char_num); + rv &= native_to_network(&network->unused2, native.unused2); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(CharSelect *native, NetCharSelect network) +{ + bool rv = true; + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->base_exp, network.base_exp); + rv &= network_to_native(&native->zeny, network.zeny); + rv &= network_to_native(&native->job_exp, network.job_exp); + rv &= network_to_native(&native->job_level, network.job_level); + rv &= network_to_native(&native->shoes, network.shoes); + rv &= network_to_native(&native->gloves, network.gloves); + rv &= network_to_native(&native->cape, network.cape); + rv &= network_to_native(&native->misc1, network.misc1); + rv &= network_to_native(&native->option, network.option); + rv &= network_to_native(&native->unused, network.unused); + rv &= network_to_native(&native->karma, network.karma); + rv &= network_to_native(&native->manner, network.manner); + rv &= network_to_native(&native->status_point, network.status_point); + rv &= network_to_native(&native->hp, network.hp); + rv &= network_to_native(&native->max_hp, network.max_hp); + rv &= network_to_native(&native->sp, network.sp); + rv &= network_to_native(&native->max_sp, network.max_sp); + rv &= network_to_native(&native->speed, network.speed); + rv &= network_to_native(&native->species, network.species); + rv &= network_to_native(&native->hair_style, network.hair_style); + rv &= network_to_native(&native->weapon, network.weapon); + rv &= network_to_native(&native->base_level, network.base_level); + rv &= network_to_native(&native->skill_point, network.skill_point); + rv &= network_to_native(&native->head_bottom, network.head_bottom); + rv &= network_to_native(&native->shield, network.shield); + rv &= network_to_native(&native->head_top, network.head_top); + rv &= network_to_native(&native->head_mid, network.head_mid); + rv &= network_to_native(&native->hair_color, network.hair_color); + rv &= network_to_native(&native->misc2, network.misc2); + rv &= network_to_native(&native->char_name, network.char_name); + rv &= network_to_native(&native->stats, network.stats); + rv &= network_to_native(&native->char_num, network.char_num); + rv &= network_to_native(&native->unused2, network.unused2); + return rv; +} + +struct SkillInfo +{ + SkillID skill_id = {}; + uint16_t type_or_inf = {}; + SkillFlags flags = {}; + uint16_t level = {}; + uint16_t sp = {}; + uint16_t range = {}; + VString<23> unused = {}; + uint8_t can_raise = {}; +}; +struct NetSkillInfo +{ + Little16 skill_id; + Little16 type_or_inf; + Little16 flags; + Little16 level; + Little16 sp; + Little16 range; + NetString<sizeof(VString<23>)> unused; + Byte can_raise; +}; +static_assert(offsetof(NetSkillInfo, skill_id) == 0, "offsetof(NetSkillInfo, skill_id) == 0"); +static_assert(offsetof(NetSkillInfo, type_or_inf) == 2, "offsetof(NetSkillInfo, type_or_inf) == 2"); +static_assert(offsetof(NetSkillInfo, flags) == 4, "offsetof(NetSkillInfo, flags) == 4"); +static_assert(offsetof(NetSkillInfo, level) == 6, "offsetof(NetSkillInfo, level) == 6"); +static_assert(offsetof(NetSkillInfo, sp) == 8, "offsetof(NetSkillInfo, sp) == 8"); +static_assert(offsetof(NetSkillInfo, range) == 10, "offsetof(NetSkillInfo, range) == 10"); +static_assert(offsetof(NetSkillInfo, unused) == 12, "offsetof(NetSkillInfo, unused) == 12"); +static_assert(offsetof(NetSkillInfo, can_raise) == 36, "offsetof(NetSkillInfo, can_raise) == 36"); +static_assert(sizeof(NetSkillInfo) == 37, "sizeof(NetSkillInfo) == 37"); +static_assert(alignof(NetSkillInfo) == 1, "alignof(NetSkillInfo) == 1"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetSkillInfo *network, SkillInfo native) +{ + bool rv = true; + rv &= native_to_network(&network->skill_id, native.skill_id); + rv &= native_to_network(&network->type_or_inf, native.type_or_inf); + rv &= native_to_network(&network->flags, native.flags); + rv &= native_to_network(&network->level, native.level); + rv &= native_to_network(&network->sp, native.sp); + rv &= native_to_network(&network->range, native.range); + rv &= native_to_network(&network->unused, native.unused); + rv &= native_to_network(&network->can_raise, native.can_raise); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(SkillInfo *native, NetSkillInfo network) +{ + bool rv = true; + rv &= network_to_native(&native->skill_id, network.skill_id); + rv &= network_to_native(&native->type_or_inf, network.type_or_inf); + rv &= network_to_native(&native->flags, network.flags); + rv &= network_to_native(&native->level, network.level); + rv &= network_to_native(&native->sp, network.sp); + rv &= network_to_native(&native->range, network.range); + rv &= network_to_native(&native->unused, network.unused); + rv &= network_to_native(&native->can_raise, network.can_raise); + return rv; +} + +struct Item +{ + ItemNameId nameid = {}; + int16_t amount = {}; + EPOS equip = {}; +}; +struct NetItem +{ + Little16 nameid; + Little16 amount; + Little16 equip; +}; +static_assert(alignof(NetItem) == 1, "alignof(NetItem) == 1"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetItem *network, Item native) +{ + bool rv = true; + rv &= native_to_network(&network->nameid, native.nameid); + rv &= native_to_network(&network->amount, native.amount); + rv &= native_to_network(&network->equip, native.equip); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Item *native, NetItem network) +{ + bool rv = true; + rv &= network_to_native(&native->nameid, network.nameid); + rv &= network_to_native(&native->amount, network.amount); + rv &= network_to_native(&native->equip, network.equip); + return rv; +} + +struct Point +{ + MapName map_ = {}; + int16_t x = {}; + int16_t y = {}; + Point() = default; + Point(MapName _map_, int16_t _x, int16_t _y) : map_(_map_), x(_x), y(_y) {} +}; +struct NetPoint +{ + NetString<sizeof(MapName)> map_; + Little16 x; + Little16 y; +}; +static_assert(alignof(NetPoint) == 1, "alignof(NetPoint) == 1"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPoint *network, Point native) +{ + bool rv = true; + rv &= native_to_network(&network->map_, native.map_); + rv &= native_to_network(&network->x, native.x); + rv &= native_to_network(&network->y, native.y); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Point *native, NetPoint network) +{ + bool rv = true; + rv &= network_to_native(&native->map_, network.map_); + rv &= network_to_native(&native->x, network.x); + rv &= network_to_native(&native->y, network.y); + return rv; +} + +struct SkillValue +{ + uint16_t lv = {}; + SkillFlags flags = {}; +}; +struct NetSkillValue +{ + Little16 lv; + Little16 flags; +}; +static_assert(alignof(NetSkillValue) == 1, "alignof(NetSkillValue) == 1"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetSkillValue *network, SkillValue native) +{ + bool rv = true; + rv &= native_to_network(&network->lv, native.lv); + rv &= native_to_network(&network->flags, native.flags); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(SkillValue *native, NetSkillValue network) +{ + bool rv = true; + rv &= network_to_native(&native->lv, network.lv); + rv &= network_to_native(&native->flags, network.flags); + return rv; +} + +struct GlobalReg +{ + VarName str = {}; + int32_t value = {}; +}; +struct NetGlobalReg +{ + NetString<sizeof(VarName)> str; + Little32 value; +}; +static_assert(alignof(NetGlobalReg) == 1, "alignof(NetGlobalReg) == 1"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetGlobalReg *network, GlobalReg native) +{ + bool rv = true; + rv &= native_to_network(&network->str, native.str); + rv &= native_to_network(&network->value, native.value); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(GlobalReg *native, NetGlobalReg network) +{ + bool rv = true; + rv &= network_to_native(&native->str, network.str); + rv &= network_to_native(&native->value, network.value); + return rv; +} + +struct CharKey +{ + CharName name = {}; + AccountId account_id = {}; + CharId char_id = {}; + uint8_t char_num = {}; +}; +struct NetCharKey +{ + NetString<sizeof(CharName)> name; + Little32 account_id; + Little32 char_id; + Byte char_num; +}; +static_assert(alignof(NetCharKey) == 1, "alignof(NetCharKey) == 1"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetCharKey *network, CharKey native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->char_id, native.char_id); + rv &= native_to_network(&network->char_num, native.char_num); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(CharKey *native, NetCharKey network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->char_id, network.char_id); + rv &= network_to_native(&native->char_num, network.char_num); + return rv; +} + +struct CharData +{ + CharId partner_id = {}; + int32_t base_exp = {}; + int32_t job_exp = {}; + int32_t zeny = {}; + Species species = {}; + int16_t status_point = {}; + int16_t skill_point = {}; + int32_t hp = {}; + int32_t max_hp = {}; + int32_t sp = {}; + int32_t max_sp = {}; + Option option = {}; + int16_t karma = {}; + int16_t manner = {}; + int16_t hair = {}; + int16_t hair_color = {}; + int16_t clothes_color = {}; + PartyId party_id = {}; + ItemLook weapon = {}; + ItemNameId shield = {}; + ItemNameId head_top = {}; + ItemNameId head_mid = {}; + ItemNameId head_bottom = {}; + uint8_t base_level = {}; + uint8_t job_level = {}; + earray<int16_t, ATTR, ATTR::COUNT> attrs = {}; + SEX sex = {}; + IP4Address mapip = {}; + uint16_t mapport = {}; + Point last_point = {}; + Point save_point = {}; + GenericArray<Item, InventoryIndexing<IOff0, MAX_INVENTORY>> inventory = {}; + earray<SkillValue, SkillID, MAX_SKILL> skill = {}; + int32_t global_reg_num = {}; + Array<GlobalReg, GLOBAL_REG_NUM> global_reg = {}; + int32_t account_reg_num = {}; + Array<GlobalReg, ACCOUNT_REG_NUM> account_reg = {}; + int32_t account_reg2_num = {}; + Array<GlobalReg, ACCOUNT_REG2_NUM> account_reg2 = {}; +}; +struct NetCharData +{ + Little32 partner_id; + Little32 base_exp; + Little32 job_exp; + Little32 zeny; + Little16 species; + Little16 status_point; + Little16 skill_point; + Little32 hp; + Little32 max_hp; + Little32 sp; + Little32 max_sp; + Little16 option; + Little16 karma; + Little16 manner; + Little16 hair; + Little16 hair_color; + Little16 clothes_color; + Little32 party_id; + Little16 weapon; + Little16 shield; + Little16 head_top; + Little16 head_mid; + Little16 head_bottom; + Byte base_level; + Byte job_level; + NetArray<Little16, static_cast<size_t>(ATTR::COUNT)> attrs; + Byte sex; + IP4Address mapip; + Little16 mapport; + NetPoint last_point; + NetPoint save_point; + NetArray<NetItem, MAX_INVENTORY> inventory; + NetArray<NetSkillValue, static_cast<size_t>(MAX_SKILL)> skill; + Little32 global_reg_num; + NetArray<NetGlobalReg, GLOBAL_REG_NUM> global_reg; + Little32 account_reg_num; + NetArray<NetGlobalReg, ACCOUNT_REG_NUM> account_reg; + Little32 account_reg2_num; + NetArray<NetGlobalReg, ACCOUNT_REG2_NUM> account_reg2; +}; +static_assert(alignof(NetCharData) == 1, "alignof(NetCharData) == 1"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetCharData *network, CharData native) +{ + bool rv = true; + rv &= native_to_network(&network->partner_id, native.partner_id); + rv &= native_to_network(&network->base_exp, native.base_exp); + rv &= native_to_network(&network->job_exp, native.job_exp); + rv &= native_to_network(&network->zeny, native.zeny); + rv &= native_to_network(&network->species, native.species); + rv &= native_to_network(&network->status_point, native.status_point); + rv &= native_to_network(&network->skill_point, native.skill_point); + rv &= native_to_network(&network->hp, native.hp); + rv &= native_to_network(&network->max_hp, native.max_hp); + rv &= native_to_network(&network->sp, native.sp); + rv &= native_to_network(&network->max_sp, native.max_sp); + rv &= native_to_network(&network->option, native.option); + rv &= native_to_network(&network->karma, native.karma); + rv &= native_to_network(&network->manner, native.manner); + rv &= native_to_network(&network->hair, native.hair); + rv &= native_to_network(&network->hair_color, native.hair_color); + rv &= native_to_network(&network->clothes_color, native.clothes_color); + rv &= native_to_network(&network->party_id, native.party_id); + rv &= native_to_network(&network->weapon, native.weapon); + rv &= native_to_network(&network->shield, native.shield); + rv &= native_to_network(&network->head_top, native.head_top); + rv &= native_to_network(&network->head_mid, native.head_mid); + rv &= native_to_network(&network->head_bottom, native.head_bottom); + rv &= native_to_network(&network->base_level, native.base_level); + rv &= native_to_network(&network->job_level, native.job_level); + rv &= native_to_network(&network->attrs, native.attrs); + rv &= native_to_network(&network->sex, native.sex); + rv &= native_to_network(&network->mapip, native.mapip); + rv &= native_to_network(&network->mapport, native.mapport); + rv &= native_to_network(&network->last_point, native.last_point); + rv &= native_to_network(&network->save_point, native.save_point); + rv &= native_to_network(&network->inventory, native.inventory); + rv &= native_to_network(&network->skill, native.skill); + rv &= native_to_network(&network->global_reg_num, native.global_reg_num); + rv &= native_to_network(&network->global_reg, native.global_reg); + rv &= native_to_network(&network->account_reg_num, native.account_reg_num); + rv &= native_to_network(&network->account_reg, native.account_reg); + rv &= native_to_network(&network->account_reg2_num, native.account_reg2_num); + rv &= native_to_network(&network->account_reg2, native.account_reg2); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(CharData *native, NetCharData network) +{ + bool rv = true; + rv &= network_to_native(&native->partner_id, network.partner_id); + rv &= network_to_native(&native->base_exp, network.base_exp); + rv &= network_to_native(&native->job_exp, network.job_exp); + rv &= network_to_native(&native->zeny, network.zeny); + rv &= network_to_native(&native->species, network.species); + rv &= network_to_native(&native->status_point, network.status_point); + rv &= network_to_native(&native->skill_point, network.skill_point); + rv &= network_to_native(&native->hp, network.hp); + rv &= network_to_native(&native->max_hp, network.max_hp); + rv &= network_to_native(&native->sp, network.sp); + rv &= network_to_native(&native->max_sp, network.max_sp); + rv &= network_to_native(&native->option, network.option); + rv &= network_to_native(&native->karma, network.karma); + rv &= network_to_native(&native->manner, network.manner); + rv &= network_to_native(&native->hair, network.hair); + rv &= network_to_native(&native->hair_color, network.hair_color); + rv &= network_to_native(&native->clothes_color, network.clothes_color); + rv &= network_to_native(&native->party_id, network.party_id); + rv &= network_to_native(&native->weapon, network.weapon); + rv &= network_to_native(&native->shield, network.shield); + rv &= network_to_native(&native->head_top, network.head_top); + rv &= network_to_native(&native->head_mid, network.head_mid); + rv &= network_to_native(&native->head_bottom, network.head_bottom); + rv &= network_to_native(&native->base_level, network.base_level); + rv &= network_to_native(&native->job_level, network.job_level); + rv &= network_to_native(&native->attrs, network.attrs); + rv &= network_to_native(&native->sex, network.sex); + rv &= network_to_native(&native->mapip, network.mapip); + rv &= network_to_native(&native->mapport, network.mapport); + rv &= network_to_native(&native->last_point, network.last_point); + rv &= network_to_native(&native->save_point, network.save_point); + rv &= network_to_native(&native->inventory, network.inventory); + rv &= network_to_native(&native->skill, network.skill); + rv &= network_to_native(&native->global_reg_num, network.global_reg_num); + rv &= network_to_native(&native->global_reg, network.global_reg); + rv &= network_to_native(&native->account_reg_num, network.account_reg_num); + rv &= network_to_native(&native->account_reg, network.account_reg); + rv &= network_to_native(&native->account_reg2_num, network.account_reg2_num); + rv &= network_to_native(&native->account_reg2, network.account_reg2); + return rv; +} + +struct NetPartyMember +{ + Little32 account_id; + NetString<sizeof(CharName)> name; + NetString<sizeof(MapName)> map; + Little32 leader; + Little32 online; + Little32 lv; +}; +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPartyMember *network, PartyMember native) +{ + bool rv = true; + AccountId account_id = native.account_id; rv &= native_to_network(&network->account_id, account_id); + CharName name = native.name; rv &= native_to_network(&network->name, name); + MapName map = native.map; rv &= native_to_network(&network->map, map); + int32_t leader = native.leader; rv &= native_to_network(&network->leader, leader); + int32_t online = native.online; rv &= native_to_network(&network->online, online); + int32_t lv = native.lv; rv &= native_to_network(&network->lv, lv); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(PartyMember *native, NetPartyMember network) +{ + bool rv = true; + AccountId account_id; rv &= network_to_native(&account_id, network.account_id); native->account_id = account_id; + CharName name; rv &= network_to_native(&name, network.name); native->name = name; + MapName map; rv &= network_to_native(&map, network.map); native->map = map; + int32_t leader; rv &= network_to_native(&leader, network.leader); native->leader = leader; + int32_t online; rv &= network_to_native(&online, network.online); native->online = online; + int32_t lv; rv &= network_to_native(&lv, network.lv); native->lv = lv; + return rv; +} + +struct PartyMost +{ + PartyName name = {}; + int32_t exp = {}; + int32_t item = {}; + Array<PartyMember, MAX_PARTY> member = {}; +}; +struct NetPartyMost +{ + NetString<sizeof(PartyName)> name; + Little32 exp; + Little32 item; + NetArray<NetPartyMember, MAX_PARTY> member; +}; +static_assert(alignof(NetPartyMost) == 1, "alignof(NetPartyMost) == 1"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetPartyMost *network, PartyMost native) +{ + bool rv = true; + rv &= native_to_network(&network->name, native.name); + rv &= native_to_network(&network->exp, native.exp); + rv &= native_to_network(&network->item, native.item); + rv &= native_to_network(&network->member, native.member); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(PartyMost *native, NetPartyMost network) +{ + bool rv = true; + rv &= network_to_native(&native->name, network.name); + rv &= network_to_native(&native->exp, network.exp); + rv &= network_to_native(&native->item, network.item); + rv &= network_to_native(&native->member, network.member); + return rv; +} + +struct Storage +{ + bool dirty = {}; + AccountId account_id = {}; + int16_t storage_status = {}; + int16_t storage_amount = {}; + GenericArray<Item, InventoryIndexing<SOff0, MAX_STORAGE>> storage_ = {}; +}; +struct NetStorage +{ + bool dirty; + Little32 account_id; + Little16 storage_status; + Little16 storage_amount; + NetArray<NetItem, MAX_STORAGE> storage_; +}; +static_assert(alignof(NetStorage) == 1, "alignof(NetStorage) == 1"); +inline __attribute__((warn_unused_result)) +bool native_to_network(NetStorage *network, Storage native) +{ + bool rv = true; + rv &= native_to_network(&network->dirty, native.dirty); + rv &= native_to_network(&network->account_id, native.account_id); + rv &= native_to_network(&network->storage_status, native.storage_status); + rv &= native_to_network(&network->storage_amount, native.storage_amount); + rv &= native_to_network(&network->storage_, native.storage_); + return rv; +} +inline __attribute__((warn_unused_result)) +bool network_to_native(Storage *native, NetStorage network) +{ + bool rv = true; + rv &= network_to_native(&native->dirty, network.dirty); + rv &= network_to_native(&native->account_id, network.account_id); + rv &= network_to_native(&native->storage_status, network.storage_status); + rv &= network_to_native(&native->storage_amount, network.storage_amount); + rv &= network_to_native(&native->storage_, network.storage_); + return rv; +} + +} // namespace tmwa diff --git a/src/range/fwd.hpp b/src/range/fwd.hpp new file mode 100644 index 0000000..646eadb --- /dev/null +++ b/src/range/fwd.hpp @@ -0,0 +1,29 @@ +#pragma once +// range/fwd.hpp - list of type names for range lib +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +// meh, add more when I feel like it +template<class T> +class Slice; +} // namespace tmwa diff --git a/src/range/slice.cpp b/src/range/slice.cpp index 5e00233..f93c19f 100644 --- a/src/range/slice.cpp +++ b/src/range/slice.cpp @@ -19,3 +19,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/range/slice.hpp b/src/range/slice.hpp index f645595..da52e5f 100644 --- a/src/range/slice.hpp +++ b/src/range/slice.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_GENERIC_SLICE_HPP -#define TMWA_GENERIC_SLICE_HPP +#pragma once // slice.hpp - a borrowed array // // Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,14 +18,16 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstddef> +#include <cstddef> -# include <type_traits> +#include <type_traits> +#include <vector> -# include <vector> +namespace tmwa +{ template<class T> class Slice { @@ -68,7 +69,6 @@ public: Slice pslice(size_t b, size_t e) const; Slice islice(iterator b, iterator e) const; }; +} // namespace tmwa -# include "slice.tcc" - -#endif // TMWA_GENERIC_SLICE_HPP +#include "slice.tcc" diff --git a/src/range/slice.tcc b/src/range/slice.tcc index 3a1ceb5..a1c136f 100644 --- a/src/range/slice.tcc +++ b/src/range/slice.tcc @@ -1,4 +1,4 @@ -// strings/base.tcc - Inline functions for strings/base.hpp +// ranges/slice.tcc - Inline functions for strings/base.hpp // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> // @@ -19,8 +19,9 @@ #include <cassert> -#include <algorithm> +namespace tmwa +{ // simple pointer-wrapping iterator template<class T> class Slice<T>::iterator @@ -214,3 +215,4 @@ Slice<T> Slice<T>::islice(iterator b, iterator e) const { return Slice(&*b, &*e); } +} // namespace tmwa diff --git a/src/range/slice_test.cpp b/src/range/slice_test.cpp index f59bf84..d31d973 100644 --- a/src/range/slice_test.cpp +++ b/src/range/slice_test.cpp @@ -22,6 +22,9 @@ #include "../poison.hpp" + +namespace tmwa +{ TEST(slice, slice) { int init[] = {1, 2, 3, 4, 5}; @@ -107,3 +110,4 @@ TEST(slice, cast) EXPECT_EQ(foos.size(), slice.size()); EXPECT_EQ(&foos.end()[-1], &slice.end()[-1]); } +} // namespace tmwa diff --git a/src/sanity.hpp b/src/sanity.hpp index f29a7c3..c00d9b2 100644 --- a/src/sanity.hpp +++ b/src/sanity.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_SANITY_HPP -#define TMWA_SANITY_HPP +#pragma once // sanity.hpp - Keep spatulas out of the build environment. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,32 +18,33 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# if 0 -# include "../sanity.hpp" -# endif +// just mention "fwd.hpp" to make formatter happy -# ifndef __cplusplus -# error "Please compile in C++ mode" -# endif // __cplusplus -# if __GNUC__ < 4 -# error "Your compiler is absolutely ancient. You have no chance ..." -# endif // __GNUC__ < 4 +namespace tmwa +{ +#ifndef __cplusplus +# error "Please compile in C++ mode" +#endif // __cplusplus -# if __GNUC__ == 4 +#if __GNUC__ < 4 +# error "Your compiler is absolutely ancient. You have no chance ..." +#endif // __GNUC__ < 4 + +#if __GNUC__ == 4 // clang identifies as GCC 4.2, but is mostly okay. // Until a bug-free release of it happens, though, I won't recommend it. -// (patched) clang 3.1 would be the requirement -# if __GNUC_MINOR__ < 6 && !defined(__clang__) -# error "Please upgrade to at least GCC 4.6" -# endif // __GNUC_MINOR__ < 6 && !defined(__clang__) -# endif // __GNUC__ == 4 +// clang 3.2 is the minimum that the CI builds are using +# if __GNUC_MINOR__ < 7 && !defined(__clang__) +# error "Please upgrade to at least GCC 4.7" +# endif // __GNUC_MINOR__ < 7 && !defined(__clang__) +#endif // __GNUC__ == 4 -# if not defined(__i386__) and not defined(__x86_64__) +#if not defined(__i386__) and not defined(__x86_64__) // Known platform dependencies: // endianness for the [RW]FIFO.* macros // possibly, some signal-handling -# error "Unsupported platform, we use x86 / amd64 only" -# endif // not __i386__ - -#endif // TMWA_SANITY_HPP +// some integer sizes (partially fixed for the x32 ABI) +# error "Unsupported platform, we use x86 / amd64 only" +#endif // not __i386__ +} // namespace tmwa diff --git a/src/compat/alg.cpp b/src/sexpr/bind.cpp index 8cfd00a..d8d0caa 100644 --- a/src/compat/alg.cpp +++ b/src/sexpr/bind.cpp @@ -1,5 +1,5 @@ -#include "alg.hpp" -// alg.cpp - Silly math stuff. +#include "bind.hpp" +// bind.cpp - Just include the header file. // // Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> // @@ -19,3 +19,11 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../poison.hpp" + + +namespace tmwa +{ +namespace sexpr +{ +} // namespace sexpr +} // namespace tmwa diff --git a/src/sexpr/bind.hpp b/src/sexpr/bind.hpp new file mode 100644 index 0000000..79d7cae --- /dev/null +++ b/src/sexpr/bind.hpp @@ -0,0 +1,48 @@ +#pragma once +// bind.hpp - Like std::bind, but with arbitrary arguments. +// +// Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <utility> + +#include "fwd.hpp" + + +namespace tmwa +{ +namespace sexpr +{ + template<class F, class T> + struct VariadicBind + { + // note: may be lvalue references + F&& f; + T&& t; + template<class... A> + auto operator()(A&&... a) -> decltype(std::forward<F>(f)(std::forward<T>(t), std::forward<A>(a)...)) + { + return std::forward<F>(f)(std::forward<T>(t), std::forward<A>(a)...); + } + }; + template<class F, class T> + VariadicBind<F, T> bind_variadic(F&& func, T&& arg1) + { + return VariadicBind<F, T>{std::forward<F>(func), std::forward<T>(arg1)}; + } +} // namespace sexpr +} // namespace tmwa diff --git a/src/sexpr/fwd.hpp b/src/sexpr/fwd.hpp new file mode 100644 index 0000000..580b322 --- /dev/null +++ b/src/sexpr/fwd.hpp @@ -0,0 +1,27 @@ +#pragma once +// sexpr/fwd.hpp - list of type names for sexpr lib +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +// meh, add more when I feel like it +} // namespace tmwa diff --git a/src/sexpr/lexer.cpp b/src/sexpr/lexer.cpp index 8c1c380..ea1890e 100644 --- a/src/sexpr/lexer.cpp +++ b/src/sexpr/lexer.cpp @@ -19,23 +19,28 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../strings/mstring.hpp" +#include "../strings/vstring.hpp" +#include "../strings/literal.hpp" #include "../io/cxxstdio.hpp" #include "../poison.hpp" + +namespace tmwa +{ namespace sexpr { Lexeme Lexer::_adv() { - XString whitespace = " \t\n\r\v\f"; + LString whitespace = " \t\n\r\v\f"_s; while (true) { if (!_in.get(_span.begin)) { if (!_depth.empty()) { - _depth.back().error("Unmatched '('"); + _depth.back().error("Unmatched '('"_s); return TOK_ERROR; } return TOK_EOF; @@ -52,14 +57,14 @@ namespace sexpr switch (co) { case '(': - _string = "("; + _string = "("_s; _depth.push_back(_span.end); return TOK_OPEN; case ')': - _string = ")"; + _string = ")"_s; if (_depth.empty()) { - _span.end.error("Unmatched ')'"); + _span.end.error("Unmatched ')'"_s); return TOK_ERROR; } _depth.pop_back(); @@ -73,7 +78,7 @@ namespace sexpr { if (!_in.get(_span.end)) { - _span.error("EOF in string literal"); + _span.error("EOF in string literal"_s); return TOK_ERROR; } char ch = _span.end.ch(); @@ -89,7 +94,7 @@ namespace sexpr if (!_in.get(_span.end)) { - _span.end.error("EOF at backslash in string"); + _span.end.error("EOF at backslash in string"_s); return TOK_ERROR; } ch = _span.end.ch(); @@ -97,7 +102,7 @@ namespace sexpr switch (ch) { default: - _span.end.error("Unknown backslash sequence"); + _span.end.error("Unknown backslash sequence"_s); return TOK_ERROR; case 'a': collect += '\a'; break; case 'b': collect += '\b'; break; @@ -117,7 +122,7 @@ namespace sexpr tmp *= 16; if (!_in.get(_span.end)) { - _span.end.error("EOF after \\x in string"); + _span.end.error("EOF after \\x in string"_s); return TOK_ERROR; } char cx = _span.end.ch(); @@ -130,7 +135,7 @@ namespace sexpr tmp += cx - 'a' + 10; else { - _span.end.error("Non-hex char after \\x"); + _span.end.error("Non-hex char after \\x"_s); return TOK_ERROR; } } @@ -143,7 +148,7 @@ namespace sexpr } case '\'': case '\\': - _span.end.error("forbidden character"); + _span.end.error("forbidden character"_s); return TOK_ERROR; default: // this includes integers - they are differentiated in parsing @@ -168,7 +173,7 @@ namespace sexpr } _string = AString(collect); if (!_string.is_print()) - _span.error("String is not entirely printable"); + _span.error("String is not entirely printable"_s); return TOK_TOKEN; } } @@ -178,23 +183,23 @@ namespace sexpr { switch (c) { - case '\a': return {"\\a"}; - case '\b': return {"\\b"}; - case '\e': return {"\\e"}; - case '\f': return {"\\f"}; - //case '\n': return {"\\n"}; - case '\r': return {"\\r"}; - case '\t': return {"\\t"}; - case '\v': return {"\\v"}; - case '\\': return {"\\\\"}; - case '\"': return {"\\\""}; + case '\a': return "\\a"_s; + case '\b': return "\\b"_s; + case '\e': return "\\e"_s; + case '\f': return "\\f"_s; + //case '\n': return "\\n"_s; + case '\r': return "\\r"_s; + case '\t': return "\\t"_s; + case '\v': return "\\v"_s; + case '\\': return "\\\\"_s; + case '\"': return "\\\""_s; default: if (c == '\n') return c; if (' ' <= c && c <= '~') return c; else - return STRNPRINTF(5, "\\x%02x", static_cast<uint8_t>(c)); + return STRNPRINTF(5, "\\x%02x"_fmt, static_cast<uint8_t>(c)); } } AString escape(XString s) @@ -207,22 +212,23 @@ namespace sexpr return AString(m); } - ZString token_name(Lexeme tok) + LString token_name(Lexeme tok) { switch (tok) { case TOK_EOF: - return ZString("EOF"); + return "EOF"_s; case TOK_OPEN: - return ZString("OPEN"); + return "OPEN"_s; case TOK_CLOSE: - return ZString("CLOSE"); + return "CLOSE"_s; case TOK_STRING: - return ZString("STRING"); + return "STRING"_s; case TOK_TOKEN: - return ZString("TOKEN"); + return "TOKEN"_s; default: - return ZString("ERROR"); + return "ERROR"_s; } } } // namespace sexpr +} // namespace tmwa diff --git a/src/sexpr/lexer.hpp b/src/sexpr/lexer.hpp index 7bce620..63be72d 100644 --- a/src/sexpr/lexer.hpp +++ b/src/sexpr/lexer.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_SEXPR_LEXER_HPP -#define TMWA_SEXPR_LEXER_HPP +#pragma once // lexer.hpp - tokenize a stream of S-expressions // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,15 +18,21 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/astring.hpp" -# include "../strings/vstring.hpp" -# include "../strings/xstring.hpp" -# include "../strings/zstring.hpp" +#include <vector> -# include "../io/line.hpp" +#include "../strings/fwd.hpp" +#include "../strings/astring.hpp" +#include "../strings/zstring.hpp" +#include "../io/line.hpp" + +#include "fwd.hpp" + + +namespace tmwa +{ namespace sexpr { enum Lexeme @@ -67,7 +72,6 @@ namespace sexpr VString<4> escape(char c); AString escape(XString s); - ZString token_name(Lexeme tok); + LString token_name(Lexeme tok); } // namespace sexpr - -#endif // TMWA_SEXPR_LEXER_HPP +} // namespace tmwa diff --git a/src/sexpr/lexer_test.cpp b/src/sexpr/lexer_test.cpp index ade79af..fdb47f2 100644 --- a/src/sexpr/lexer_test.cpp +++ b/src/sexpr/lexer_test.cpp @@ -20,8 +20,15 @@ #include <gtest/gtest.h> +#include "../strings/vstring.hpp" + +#include "../tests/fdhack.hpp" + #include "../poison.hpp" + +namespace tmwa +{ static io::FD string_pipe(ZString sz) { @@ -40,69 +47,69 @@ io::FD string_pipe(ZString sz) TEST(sexpr, escape) { - EXPECT_EQ(sexpr::escape('\0'), "\\x00"); - EXPECT_EQ(sexpr::escape('\x1f'), "\\x1f"); - EXPECT_EQ(sexpr::escape('\x20'), " "); - EXPECT_EQ(sexpr::escape('\x7e'), "~"); - EXPECT_EQ(sexpr::escape('\x7f'), "\\x7f"); - EXPECT_EQ(sexpr::escape('\x80'), "\\x80"); - EXPECT_EQ(sexpr::escape('\xff'), "\\xff"); - EXPECT_EQ(sexpr::escape('\a'), "\\a"); - EXPECT_EQ(sexpr::escape('\b'), "\\b"); - EXPECT_EQ(sexpr::escape('\e'), "\\e"); - EXPECT_EQ(sexpr::escape('\f'), "\\f"); - //EXPECT_EQ(sexpr::escape('\n'), "\\n"); - EXPECT_EQ(sexpr::escape('\n'), "\n"); - EXPECT_EQ(sexpr::escape('\r'), "\\r"); - EXPECT_EQ(sexpr::escape('\t'), "\\t"); - EXPECT_EQ(sexpr::escape('\v'), "\\v"); - EXPECT_EQ(sexpr::escape('\\'), "\\\\"); - EXPECT_EQ(sexpr::escape('\"'), "\\\""); + EXPECT_EQ(sexpr::escape('\0'), "\\x00"_s); + EXPECT_EQ(sexpr::escape('\x1f'), "\\x1f"_s); + EXPECT_EQ(sexpr::escape('\x20'), " "_s); + EXPECT_EQ(sexpr::escape('\x7e'), "~"_s); + EXPECT_EQ(sexpr::escape('\x7f'), "\\x7f"_s); + EXPECT_EQ(sexpr::escape('\x80'), "\\x80"_s); + EXPECT_EQ(sexpr::escape('\xff'), "\\xff"_s); + EXPECT_EQ(sexpr::escape('\a'), "\\a"_s); + EXPECT_EQ(sexpr::escape('\b'), "\\b"_s); + EXPECT_EQ(sexpr::escape('\e'), "\\e"_s); + EXPECT_EQ(sexpr::escape('\f'), "\\f"_s); + //EXPECT_EQ(sexpr::escape('\n'), "\\n"_s); + EXPECT_EQ(sexpr::escape('\n'), "\n"_s); + EXPECT_EQ(sexpr::escape('\r'), "\\r"_s); + EXPECT_EQ(sexpr::escape('\t'), "\\t"_s); + EXPECT_EQ(sexpr::escape('\v'), "\\v"_s); + EXPECT_EQ(sexpr::escape('\\'), "\\\\"_s); + EXPECT_EQ(sexpr::escape('\"'), "\\\""_s); - EXPECT_EQ(sexpr::escape("\x1f\x20\x7e\x7f\x80\xff\a\b\e\f\r\t\v\\\""), - "\"\\x1f ~\\x7f\\x80\\xff\\a\\b\\e\\f\\r\\t\\v\\\\\\\"\""); + EXPECT_EQ(sexpr::escape("\x1f\x20\x7e\x7f\x80\xff\a\b\e\f\r\t\v\\\""_s), + "\"\\x1f ~\\x7f\\x80\\xff\\a\\b\\e\\f\\r\\t\\v\\\\\\\"\""_s); } TEST(sexpr, lexer) { io::LineSpan span; - sexpr::Lexer lexer("<lexer-test1>", string_pipe(" foo( ) 123\"\" \n")); + sexpr::Lexer lexer("<lexer-test1>"_s, string_pipe(" foo( ) 123\"\" \n"_s)); EXPECT_EQ(lexer.peek(), sexpr::TOK_TOKEN); - EXPECT_EQ(lexer.val_string(), "foo"); - EXPECT_EQ(lexer.span().message_str("error", "test"), + EXPECT_EQ(lexer.val_string(), "foo"_s); + EXPECT_EQ(lexer.span().message_str("error"_s, "test"_s), "<lexer-test1>:1:2: error: test\n" " foo( ) 123\"\" \n" - " ^~~\n" + " ^~~\n"_s ); lexer.adv(); EXPECT_EQ(lexer.peek(), sexpr::TOK_OPEN); - EXPECT_EQ(lexer.span().message_str("error", "test"), + EXPECT_EQ(lexer.span().message_str("error"_s, "test"_s), "<lexer-test1>:1:5: error: test\n" " foo( ) 123\"\" \n" - " ^\n" + " ^\n"_s ); lexer.adv(); EXPECT_EQ(lexer.peek(), sexpr::TOK_CLOSE); - EXPECT_EQ(lexer.span().message_str("error", "test"), + EXPECT_EQ(lexer.span().message_str("error"_s, "test"_s), "<lexer-test1>:1:7: error: test\n" " foo( ) 123\"\" \n" - " ^\n" + " ^\n"_s ); lexer.adv(); EXPECT_EQ(lexer.peek(), sexpr::TOK_TOKEN); - EXPECT_EQ(lexer.val_string(), "123"); - EXPECT_EQ(lexer.span().message_str("error", "test"), + EXPECT_EQ(lexer.val_string(), "123"_s); + EXPECT_EQ(lexer.span().message_str("error"_s, "test"_s), "<lexer-test1>:1:9: error: test\n" " foo( ) 123\"\" \n" - " ^~~\n" + " ^~~\n"_s ); lexer.adv(); EXPECT_EQ(lexer.peek(), sexpr::TOK_STRING); - EXPECT_EQ(lexer.val_string(), ""); - EXPECT_EQ(lexer.span().message_str("error", "test"), + EXPECT_EQ(lexer.val_string(), ""_s); + EXPECT_EQ(lexer.span().message_str("error"_s, "test"_s), "<lexer-test1>:1:12: error: test\n" " foo( ) 123\"\" \n" - " ^~\n" + " ^~\n"_s ); lexer.adv(); EXPECT_EQ(lexer.peek(), sexpr::TOK_EOF); @@ -110,24 +117,26 @@ TEST(sexpr, lexer) TEST(sexpr, lexbad) { + QuietFd q; { io::LineSpan span; - sexpr::Lexer lexer("<lexer-bad>", string_pipe("(\n")); + sexpr::Lexer lexer("<lexer-bad>"_s, string_pipe("(\n"_s)); EXPECT_EQ(lexer.peek(), sexpr::TOK_OPEN); lexer.adv(); EXPECT_EQ(lexer.peek(), sexpr::TOK_ERROR); } for (ZString bad : { - ZString(")\n"), - ZString("\"\n"), - ZString("'\n"), - ZString("\\\n"), - ZString("\"\\"), - ZString("\"\\z\""), + ZString(")\n"_s), + ZString("\"\n"_s), + ZString("'\n"_s), + ZString("\\\n"_s), + ZString("\"\\"_s), + ZString("\"\\z\""_s), }) { io::LineSpan span; - sexpr::Lexer lexer("<lexer-bad>", string_pipe(bad)); + sexpr::Lexer lexer("<lexer-bad>"_s, string_pipe(bad)); EXPECT_EQ(lexer.peek(), sexpr::TOK_ERROR); } } +} // namespace tmwa diff --git a/src/sexpr/main.cpp b/src/sexpr/main.cpp deleted file mode 100644 index 18cb8c2..0000000 --- a/src/sexpr/main.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// sexpr/main.cpp - Driver for new magic formatter. -// -// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <stack> -#include <map> - -#include "../io/cxxstdio.hpp" - -#include "lexer.hpp" -#include "parser.hpp" - -#include "../poison.hpp" - -enum Spacing -{ - LINES, - SIMPLE, - SPACES, - SPACES_1, - SPACES_2, - SPACES_3, - SPACES_4, -}; - -static -void do_spacing(bool& first, Spacing& sp, int depth) -{ - if (first) - { - first = false; - return; - } - switch (sp) - { - case LINES: - PRINTF("\n%*s", (depth - 1) * 4, ""); - return; - case SPACES: - case SIMPLE: - PRINTF(" "); - return; - case SPACES_1: - PRINTF(" "); - sp = LINES; - return; - case SPACES_2: - PRINTF(" "); - sp = SPACES_1; - return; - case SPACES_3: - PRINTF(" "); - sp = SPACES_2; - return; - case SPACES_4: - PRINTF(" "); - sp = SPACES_3; - return; - } -} - -static -void adjust_spacing(Spacing& sp, ZString val) -{ - std::map<ZString, Spacing> spaces = - { - {"BLOCK", LINES}, - {"GUARD", LINES}, - {"DISABLED", LINES}, - {"PROCEDURE", SPACES_2}, - {"SPELL", SPACES_4}, - {"IF", SPACES_1}, - {"set_script_variable", SPACES_2}, - }; - auto it = spaces.find(val); - if (it != spaces.end()) - sp = it->second; -} - -int main() -{ - if (1 == 1) - { - sexpr::Lexer lexer("/dev/stdin"); - sexpr::SExpr sexpr; - while (sexpr::parse(lexer, sexpr)) - { - PRINTF(""); - } - if (lexer.peek() != sexpr::TOK_EOF) - { - lexer.span().error(STRPRINTF("Incomplete: %s: %s\n", - sexpr::token_name(lexer.peek()), lexer.val_string())); - } - return 0; - } - - std::stack<Spacing> spacing; - spacing.push(LINES); - sexpr::Lexer lexer("/dev/stdin"); - bool first = true; - while (sexpr::Lexeme tok = lexer.peek()) - { - switch (tok) - { - case sexpr::TOK_OPEN: - if (spacing.top() == SIMPLE) - spacing.top() = LINES; - do_spacing(first, spacing.top(), spacing.size()); - PRINTF("("); - spacing.push(SIMPLE); - first = true; - break; - case sexpr::TOK_CLOSE: - PRINTF(")"); - spacing.pop(); - first = false; - break; - case sexpr::TOK_STRING: - do_spacing(first, spacing.top(), spacing.size()); - PRINTF("%s", sexpr::escape(lexer.val_string())); - break; - case sexpr::TOK_TOKEN: - do_spacing(first, spacing.top(), spacing.size()); - PRINTF("%s", lexer.val_string()); - adjust_spacing(spacing.top(), lexer.val_string()); - break; - default: - abort(); - } - lexer.adv(); - } - PRINTF("\n"); -} diff --git a/src/sexpr/parser.cpp b/src/sexpr/parser.cpp index 2068565..8768e14 100644 --- a/src/sexpr/parser.cpp +++ b/src/sexpr/parser.cpp @@ -18,8 +18,16 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include <cerrno> + +#include "../strings/zstring.hpp" +#include "../strings/xstring.hpp" + #include "../poison.hpp" + +namespace tmwa +{ namespace sexpr { bool token_is_int(ZString s, int64_t& out, bool& ok) @@ -77,3 +85,4 @@ namespace sexpr return rv; } } // namespace sexpr +} // namespace tmwa diff --git a/src/sexpr/parser.hpp b/src/sexpr/parser.hpp index 6097f78..feed636 100644 --- a/src/sexpr/parser.hpp +++ b/src/sexpr/parser.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_SEXPR_PARSER_HPP -#define TMWA_SEXPR_PARSER_HPP +#pragma once // parser.hpp - build a tree of S-expressions // // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,14 +18,21 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "../strings/zstring.hpp" +#include <cstdlib> -# include "../io/line.hpp" +#include "../strings/fwd.hpp" -# include "lexer.hpp" +#include "../io/line.hpp" +#include "lexer.hpp" + +#include "fwd.hpp" + + +namespace tmwa +{ namespace sexpr { enum Type @@ -76,5 +82,4 @@ namespace sexpr /// return false on error or eof, check lex.peek() == TOK_EOF to see bool parse(Lexer& lex, SExpr& out); } // namespace sexpr - -#endif // TMWA_SEXPR_PARSER_HPP +} // namespace tmwa diff --git a/src/sexpr/parser.py b/src/sexpr/parser.py index d638259..201f457 100644 --- a/src/sexpr/parser.py +++ b/src/sexpr/parser.py @@ -2,7 +2,7 @@ class SExpr(object): ''' print a SExpr ''' __slots__ = ('_value') - name = 'sexpr::SExpr' + name = 'tmwa::sexpr::SExpr' enabled = True def __init__(self, value): diff --git a/src/sexpr/parser_test.cpp b/src/sexpr/parser_test.cpp index d67d041..846d425 100644 --- a/src/sexpr/parser_test.cpp +++ b/src/sexpr/parser_test.cpp @@ -22,6 +22,9 @@ #include "../poison.hpp" + +namespace tmwa +{ static io::FD string_pipe(ZString sz) { @@ -42,11 +45,11 @@ TEST(sexpr, parser) { sexpr::SExpr s; io::LineSpan span; - sexpr::Lexer lexer("<parser-test1>", string_pipe(" foo( ) 123\"\" \n")); + sexpr::Lexer lexer("<parser-test1>"_s, string_pipe(" foo( ) 123\"\" \n"_s)); EXPECT_TRUE(sexpr::parse(lexer, s)); EXPECT_EQ(s._type, sexpr::TOKEN); - EXPECT_EQ(s._str, "foo"); + EXPECT_EQ(s._str, "foo"_s); EXPECT_TRUE(sexpr::parse(lexer, s)); EXPECT_EQ(s._type, sexpr::LIST); @@ -58,7 +61,7 @@ TEST(sexpr, parser) EXPECT_TRUE(sexpr::parse(lexer, s)); EXPECT_EQ(s._type, sexpr::STRING); - EXPECT_EQ(s._str, ""); + EXPECT_EQ(s._str, ""_s); EXPECT_FALSE(sexpr::parse(lexer, s)); EXPECT_EQ(lexer.peek(), sexpr::TOK_EOF); @@ -67,19 +70,19 @@ TEST(sexpr, parser) TEST(sexpr, parselist) { sexpr::SExpr s; - sexpr::Lexer lexer("<parser-test1>", string_pipe("(foo)(bar)\n")); + sexpr::Lexer lexer("<parser-test1>"_s, string_pipe("(foo)(bar)\n"_s)); EXPECT_TRUE(sexpr::parse(lexer, s)); EXPECT_EQ(s._type, sexpr::LIST); EXPECT_EQ(s._list.size(), 1); EXPECT_EQ(s._list[0]._type, sexpr::TOKEN); - EXPECT_EQ(s._list[0]._str, "foo"); + EXPECT_EQ(s._list[0]._str, "foo"_s); EXPECT_TRUE(sexpr::parse(lexer, s)); EXPECT_EQ(s._type, sexpr::LIST); EXPECT_EQ(s._list.size(), 1); EXPECT_EQ(s._list[0]._type, sexpr::TOKEN); - EXPECT_EQ(s._list[0]._str, "bar"); + EXPECT_EQ(s._list[0]._str, "bar"_s); EXPECT_FALSE(sexpr::parse(lexer, s)); EXPECT_EQ(lexer.peek(), sexpr::TOK_EOF); @@ -87,23 +90,24 @@ TEST(sexpr, parselist) TEST(sexpr, parsebad) { - for (ZString bad : { - ZString("(\n"), - ZString(")\n"), - ZString("\"\n"), - ZString("'\n"), - ZString("\\\n"), - ZString("\"\\"), - ZString("\"\\z\""), - ZString("(()\n"), - ZString("((\n"), - ZString("((\"\n"), + for (LString bad : { + "(\n"_s, + ")\n"_s, + "\"_s\n"_s, + "'\n"_s, + "\\\n"_s, + "\"_s\\"_s, + "\"_s\\z\""_s, + "(()\n"_s, + "((\n"_s, + "((\"\n"_s, }) { sexpr::SExpr s; io::LineSpan span; - sexpr::Lexer lexer("<parse-bad>", string_pipe(bad)); + sexpr::Lexer lexer("<parse-bad>"_s, string_pipe(bad)); EXPECT_FALSE(sexpr::parse(lexer, s)); EXPECT_EQ(lexer.peek(), sexpr::TOK_ERROR); } } +} // namespace tmwa diff --git a/src/sexpr/union.cpp b/src/sexpr/union.cpp new file mode 100644 index 0000000..6f65012 --- /dev/null +++ b/src/sexpr/union.cpp @@ -0,0 +1,44 @@ +#include "union.hpp" +// union.cpp - Just include the header file and try to instantiate. +// +// Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + + +namespace tmwa +{ +namespace sexpr +{ +namespace +{ + struct Foo + { + Foo(); + Foo(const Foo&); + Foo& operator = (const Foo&); + ~Foo(); + }; +} // anonymous namespace +static Union<int, Foo> u; + +static_assert(u.index<int>() == 0, "int"); +static_assert(u.index<Foo>() == 1, "Foo"); +static_assert(u.index<char>() == size_t(-1), "char"); +} // namespace sexpr +} // namespace tmwa diff --git a/src/sexpr/union.hpp b/src/sexpr/union.hpp new file mode 100644 index 0000000..6a0b6b0 --- /dev/null +++ b/src/sexpr/union.hpp @@ -0,0 +1,105 @@ +#pragma once +// union.hpp - A (unsafe!) convenience wrapper for classes in unions. +// +// Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <utility> +#include <type_traits> +#include <cstddef> +#include <new> + +#include "fwd.hpp" + + +namespace tmwa +{ +namespace sexpr +{ + template<class... T> + class Union; + + template<> + class Union<> + { + public: + template<class T> + constexpr static size_t index() + { + return -1; + } + Union() = default; + ~Union() = default; + Union(const Union&) = delete; + Union& operator = (const Union&) = delete; + }; + + template<class F, class... R> + class Union<F, R...> + { + static_assert(!std::is_const<F>::value, "union elements are not const"); + static_assert(!std::is_volatile<F>::value, "union elements are not volatile"); + static_assert(!std::is_reference<F>::value, "union elements are not references"); + static_assert(Union<R...>::template index<F>() == size_t(-1), "unions do not contain duplicates"); + union Impl + { + F first; + Union<R...> rest; + + Impl() {} + ~Impl() {} + } data; + public: + template<class T> + constexpr static size_t index() + { + return std::is_same<F, T>::value + ? 0 + : 1 + Union<R...>::template index<T>() + ?: -1; + } + template<class T> + void get(T*& p) { data.rest.get(p); } + void get(F*& p) { p = std::addressof(data.first); } + template<class T> + void get(const T*& p) const { data.rest.get(p); } + void get(const F*& p) const { p = std::addressof(data.first); } + + template<class T> + T *get() { T *out; get(out); return out; } + template<class T> + const T *get() const { const T *out; get(out); return out; } + + Union() = default; + ~Union() = default; + Union(const Union&) = delete; + Union& operator = (const Union&) = delete; + + template<class T, class... A> + void construct(A&&... a) + { + new (get<T>()) T(std::forward<A>(a)...); + } + + template<class T> + void destruct() + { + get<T>()->~T(); + } + }; +} // namespace sexpr +} // namespace tmwa diff --git a/src/compat/alg.hpp b/src/sexpr/variant.cpp index adf3f3f..b1f500a 100644 --- a/src/compat/alg.hpp +++ b/src/sexpr/variant.cpp @@ -1,6 +1,5 @@ -#ifndef TMWA_COMPAT_ALG_HPP -#define TMWA_COMPAT_ALG_HPP -// alg.hpp - Silly math stuff. +#include "variant.hpp" +// variant.cpp - Just include the header file. // // Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> // @@ -19,21 +18,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "../poison.hpp" -# include <type_traits> - -template<class A, class B> -typename std::common_type<A, B>::type min(A a, B b) +namespace tmwa { - return a < b ? a : b; -} - -template<class A, class B> -typename std::common_type<A, B>::type max(A a, B b) +namespace sexpr { - return b < a ? a : b; -} - -#endif // TMWA_COMPAT_ALG_HPP +namespace +{ + struct Foo + { + Foo() {} + ~Foo() {} + Foo(Foo&&) {} + Foo& operator = (Foo&&) { return *this; } + }; +} // anonymous namespace + static Variant<int, Foo> v; +} // namespace sexpr +} // namespace tmwa diff --git a/src/sexpr/variant.hpp b/src/sexpr/variant.hpp new file mode 100644 index 0000000..04f35dc --- /dev/null +++ b/src/sexpr/variant.hpp @@ -0,0 +1,116 @@ +#pragma once +// variant.hpp - A single value, multiple type container. Better than boost's. +// +// Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <type_traits> +#include <cstdint> +#include <cstddef> +#include <utility> + +#include "union.hpp" +#include "void.hpp" + +#include "fwd.hpp" + + +namespace tmwa +{ +namespace sexpr +{ +#define JOIN(a, b) a##b + +#define WITH_VAR(ty, var, expr) \ + for (bool JOIN(var, _guard) = true; JOIN(var, _guard); ) \ + for (ty var = expr; JOIN(var, _guard); JOIN(var, _guard) = false) +#define MATCH(expr) \ + WITH_VAR(auto&&, _match_var, expr) \ + switch (tmwa::sexpr::VariantFriend::get_state(_match_var)) +#define CASE(ty, var) \ + break; \ + case tmwa::sexpr::VariantFriend::get_state_for<ty, decltype(_match_var)>(): \ + WITH_VAR(ty, var, tmwa::sexpr::VariantFriend::unchecked_get<ty>(_match_var)) + + template<class... T> + class Variant + { + static_assert(sizeof...(T), "A variant must not be empty"); + }; + template<class D, class... T> + class Variant<D, T...> + { + constexpr static size_t state_count = 1 + sizeof...(T); + + // simplify things immensely + friend class VariantFriend; + + typedef Union<D, T...> DataType; + DataType data; + size_t state; + + void do_destruct(); + template<class C, class... A> + void do_construct(A&&... a); + public: + Variant(); + ~Variant(); + + void reset(); + template<class C, class... A> + void emplace(A&&... a); + + Variant(const Variant& r); + Variant(Variant&& r); + Variant& operator = (const Variant& r); + Variant& operator = (Variant&& r); + + template<class E> + Variant(E e) + { + do_construct<E, E>(std::move(e)); + } + + template<class E> + Variant& operator = (E e) + { + emplace<E, E>(std::move(e)); + return *this; + } + + // use these ONLY if only one type makes sense + // otherwise use apply + template<class E> + bool is() const; + + template<class E> + E *get_if(); + + template<class E> + const E *get_if() const; + }; + + template<class R, class F> + void apply(R& r, F&& f); + template<class R, class F, class V1, class... V> + void apply(R& r, F&& f, V1&& v1, V&&... v); + template<class F, class... V> + void apply(Void&& r, F&& f, V&&... v); +} // namespace sexpr +} // namespace tmwa + +#include "variant.tcc" diff --git a/src/sexpr/variant.tcc b/src/sexpr/variant.tcc new file mode 100644 index 0000000..424a8f1 --- /dev/null +++ b/src/sexpr/variant.tcc @@ -0,0 +1,293 @@ +// variant.tcc - implementation of inlines and templates in variant.hpp +// +// Copyright © 2012-2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <cassert> +#include "bind.hpp" + +namespace tmwa +{ +namespace sexpr +{ + class VariantFriend + { + public: + template<class U, class... T, class... A> + static void unchecked_do_construct(Variant<T...> *var, A&&... a) + { + var->template do_construct<U, A...>(std::forward<A>(a)...); + } + template<class E, class... T> + static E& unchecked_get(Variant<T...>& var) + { + return *var.data.template get<E>(); + } + template<class E, class... T> + static const E& unchecked_get(const Variant<T...>& var) + { + return *var.data.template get<E>(); + } + template<class E, class... T> + static E&& unchecked_get(Variant<T...>&& var) + { + return std::move(*var.data.template get<E>()); + } + template<class E, class... T> + static const E&& unchecked_get(const Variant<T...>&& var) + { + return std::move(*var.data.template get<E>()); + } + + template<class E, class R, class F, class V1, class... V> + static void _apply_unchecked(R& r, F&& f, V1&& v1, V&&... v) + { + apply(r, bind_variadic(std::forward<F>(f), VariantFriend::unchecked_get<E>(std::forward<V1>(v1))), std::forward<V>(v)...); + } + + template<class... T, class R, class F, class V1, class... V> + static void _apply_dispatch(const Variant<T...> *, R& r, F&& f, V1&& v1, V&&... v) + { + typedef void (*Function)(R&, F&&, V1&&, V&&...); + constexpr static Function dispatch[sizeof...(T)] = { _apply_unchecked<T, R, F, V1, V...>... }; + assert(v1.state < sizeof...(T)); + dispatch[v1.state](r, std::forward<F>(f), std::forward<V1>(v1), std::forward<V>(v)...); + } + + template<class... T> + static size_t get_state(const Variant<T...>& variant) + { + return variant.state; + } + + template<class W, class V> + constexpr static size_t get_state_for() + { + return std::remove_reference<V>::type::DataType::template index<W>(); + } + }; + + + struct Destruct + { + template<class U> + void operator ()(U& v) + { + v.~U(); + } + }; + + template<class D, class... T> + void Variant<D, T...>::do_destruct() + { + apply(Void(), Destruct(), *this); + } + + template<class D, class... T> + template<class C, class... A> + void Variant<D, T...>::do_construct(A&&... a) + { + try + { + data.template construct<C, A...>(std::forward<A>(a)...); + state = Union<D, T...>::template index<C>(); + } + catch(...) + { + static_assert(std::is_nothrow_constructible<D>::value, "first element is nothrow constructible"); + data.template construct<D>(); + state = 0; + throw; + } + } + + template<class D, class... T> + Variant<D, T...>::Variant() + { + do_construct<D>(); + state = 0; + } + + template<class D, class... T> + Variant<D, T...>::~Variant() + { + do_destruct(); + } + + template<class D, class... T> + void Variant<D, T...>::reset() + { + do_destruct(); + do_construct<D>(); + } + + template<class D, class... T> + template<class C, class... A> + void Variant<D, T...>::emplace(A&&... a) + { + do_destruct(); + do_construct<C, A...>(std::forward<A>(a)...); + } + + template<class... T> + class CopyConstruct + { + Variant<T...> *target; + public: + CopyConstruct(Variant<T...> *v) : target(v) {} + template<class U> + void operator ()(const U& u) + { + VariantFriend::unchecked_do_construct<U>(target, u); + } + }; + template<class... T> + class MoveConstruct + { + Variant<T...> *target; + public: + MoveConstruct(Variant<T...> *v) : target(v) {} + template<class U> + void operator ()(U&& u) + { + VariantFriend::unchecked_do_construct<U>(target, std::move(u)); + } + }; + + // assignment requires unchecked access + template<class... T> + class CopyAssign + { + Union<T...> *data; + public: + CopyAssign(Union<T...> *d) : data(d) {} + template<class U> + void operator ()(const U& u) + { + *data->template get<U>() = u; + } + }; + + template<class... T> + class MoveAssign + { + Union<T...> *data; + public: + MoveAssign(Union<T...> *d) : data(d) {} + template<class U> + void operator () (U&& u) + { + *data->template get<U>() = std::move(u); + } + }; + + template<class D, class... T> + Variant<D, T...>::Variant(const Variant& r) + { + apply(Void(), CopyConstruct<D, T...>(this), r); + } + + template<class D, class... T> + Variant<D, T...>::Variant(Variant&& r) + { + apply(Void(), MoveConstruct<D, T...>(this), std::move(r)); + } + + template<class D, class... T> + Variant<D, T...>& Variant<D, T...>::operator = (const Variant& r) + { + if (state == r.state) + apply(Void(), CopyAssign<D, T...>(this), r); + else + { + do_destruct(); + apply(Void(), CopyConstruct<D, T...>(this), r); + } + return *this; + } + + template<class D, class... T> + Variant<D, T...>& Variant<D, T...>::operator = (Variant&& r) + { + if (state == r.state) + apply(Void(), MoveAssign<D, T...>(&data), std::move(r)); + else + { + do_destruct(); + apply(Void(), MoveConstruct<D, T...>(this), std::move(r)); + } + return *this; + } + + template<class D, class... T> + template<class E> + bool Variant<D, T...>::is() const + { + return get_if<E>(); + } + + template<class D, class... T> + template<class E> + E *Variant<D, T...>::get_if() + { + if (state == Union<D, T...>::template index<E>()) + return data.template get<E>(); + return nullptr; + } + + template<class D, class... T> + template<class E> + const E *Variant<D, T...>::get_if() const + { + if (state == Union<D, T...>::template index<E>()) + return data.template get<E>(); + return nullptr; + } + + template<class R, class F> + void _apply_assign(std::true_type, R& r, F&& f) + { + std::forward<F>(f)(); + r = Void(); + } + + template<class R, class F> + void _apply_assign(std::false_type, R& r, F&& f) + { + r = std::forward<F>(f)(); + } + + template<class R, class F> + void apply(R& r, F&& f) + { + _apply_assign(std::is_void<decltype(std::forward<F>(f)())>(), r, std::forward<F>(f)); + } + + template<class R, class F, class V1, class... V> + void apply(R& r, F&& f, V1&& v1, V&&... v) + { + VariantFriend::_apply_dispatch(&v1, r, std::forward<F>(f), std::forward<V1>(v1), std::forward<V>(v)...); + } + + template<class F, class... V> + void apply(Void&& r, F&& f, V&&... v) + { + apply(r, std::forward<F>(f), std::forward<V>(v)...); + } + +} // namespace sexpr +} // namespace tmwa diff --git a/src/sexpr/variant_test.cpp b/src/sexpr/variant_test.cpp new file mode 100644 index 0000000..5a75780 --- /dev/null +++ b/src/sexpr/variant_test.cpp @@ -0,0 +1,123 @@ +#include "variant.hpp" +// variant_test.cpp - Testsuite for multi-type container that's better than boost's. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <gtest/gtest.h> + +#include "../strings/vstring.hpp" + +//#include "../poison.hpp" + + +namespace tmwa +{ + struct Tracker + { + int id, moves, copies; + + explicit + Tracker(int i) + : id(i), moves(0), copies(0) + {} + Tracker(Tracker&& rhs) + : id(rhs.id), moves(rhs.moves + 1), copies(rhs.copies) + { rhs.id = 0; } + Tracker(const Tracker& rhs) + : id(rhs.id), moves(rhs.moves), copies(rhs.copies + 1) + {} + Tracker& operator = (Tracker&& rhs) + { id = rhs.id; moves = rhs.moves + 1; copies = rhs.copies; rhs.id = 0; return *this; } + Tracker& operator = (const Tracker& rhs) + { id = rhs.id; moves = rhs.moves; copies = rhs.copies + 1; return *this; } + }; + struct Foo : Tracker + { + // needed for first param of variant + Foo() noexcept : Tracker(0) { abort(); } + + Foo(int i) : Tracker(i) {} + }; + struct Bar : Tracker + { + Bar(int i) : Tracker(i) {} + }; + struct Qux : Tracker + { + // needed for first param of variant + Qux() noexcept : Tracker(0) { abort(); } + + Qux(int i) : Tracker(i) {} + Qux(Qux&&) = default; + Qux(const Qux&) = delete; + Qux& operator = (Qux&&) = default; + Qux& operator = (const Qux&) = default; + }; + +TEST(variant, match) +{ + struct Sub : sexpr::Variant<Foo, Bar> + { + Sub() + : sexpr::Variant<Foo, Bar>(Foo(1)) + {} + }; + Sub v1; + MATCH (v1) + { + // This is not a public API, it's just for testing. + default: + FAIL(); + + CASE(Foo, f) + { + (void)f; + SUCCEED(); + } + CASE(Bar, b) + { + (void)b; + FAIL(); + } + } + v1.emplace<Bar>(2); + MATCH (v1) + { + // This is not a public API, it's just for testing. + default: + FAIL(); + + CASE(Foo, f) + { + (void)f; + FAIL(); + } + CASE(Bar, b) + { + (void)b; + SUCCEED(); + } + } +} + +TEST(variant, copymove) +{ + sexpr::Variant<Qux> moveonly(Qux(3)); + (void)moveonly; +} +} // namespace tmwa diff --git a/src/sexpr/void.cpp b/src/sexpr/void.cpp new file mode 100644 index 0000000..9f0eeb5 --- /dev/null +++ b/src/sexpr/void.cpp @@ -0,0 +1,29 @@ +#include "void.hpp" +// void.cpp - Just include the header file. +// +// Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + + +namespace tmwa +{ +namespace sexpr +{ +} // namespace sexpr +} // namespace tmwa diff --git a/src/sexpr/void.hpp b/src/sexpr/void.hpp new file mode 100644 index 0000000..a17de9d --- /dev/null +++ b/src/sexpr/void.hpp @@ -0,0 +1,40 @@ +#pragma once +// void.hpp - A type that represents nothing and anything. +// +// Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + + +namespace tmwa +{ +namespace sexpr +{ + struct Void + { + template<class T> + constexpr operator T() const noexcept { return T(); } + template<class T> + void operator = (T&&) noexcept {} + template<class T> + constexpr Void(T&&) noexcept {} + constexpr Void() noexcept; + }; + constexpr Void::Void() noexcept = default; +} // namespace sexpr +} // namespace tmwa diff --git a/src/shared/lib.cpp b/src/shared/lib.cpp new file mode 100644 index 0000000..a9dc9b1 --- /dev/null +++ b/src/shared/lib.cpp @@ -0,0 +1,80 @@ +#include <tmwa/shared.hpp> +// shared/lib.cpp - Public library to ensure install is working. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../conf/install.hpp" + +#include "../strings/literal.hpp" +#include "../strings/astring.hpp" +#include "../strings/zstring.hpp" + +#include "../io/cxxstdio.hpp" +#include "../io/dir.hpp" +#include "../io/read.hpp" +#include "../io/write.hpp" + +#include "../poison.hpp" + + +namespace tmwa +{ +#define PRINT_VAR(var) PRINTF("%s = %s\n"_fmt, #var##_s, var) + + static + void try_read(const io::DirFd& dirfd, ZString filename) + { + io::ReadFile rf(dirfd, filename); + if (!rf.is_open()) + abort(); + AString line; + if (!rf.getline(line)) + abort(); + } + + static + void try_write(const io::DirFd& dirfd, ZString filename) + { + io::WriteFile wf(dirfd, filename); + if (!wf.is_open()) + abort(); + wf.put_line("Hello, World!"_s); + if (!wf.close()) + abort(); + } + + void check_paths() + { + ZString portable_root(strings::really_construct_from_a_pointer, getenv("TMWA_PORTABLE") ?: "", nullptr); + bool portable = bool(portable_root); + if (!portable) + portable_root = "."_s; + + io::DirFd root(portable_root); + + io::DirFd etc(root, PACKAGESYSCONFDIR.xslice_t(portable)); + io::DirFd var(root, PACKAGELOCALSTATEDIR.xslice_t(portable)); + io::DirFd share(root, PACKAGEDATADIR.xslice_t(portable)); + + try_read(etc, "shared.conf"_s); + try_read(share, "shared.data"_s); + try_write(var, "shared.test"_s); + + // io::FD::open(); + } +} // namespace tmwa diff --git a/src/spell-convert/ast.cpp b/src/spell-convert/ast.cpp deleted file mode 100644 index e9ec19c..0000000 --- a/src/spell-convert/ast.cpp +++ /dev/null @@ -1,280 +0,0 @@ -#include "ast.hpp" -// ast.cpp - Hacky converter between magic formats. -// -// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include "../io/cxxstdio.hpp" - -#include "../poison.hpp" - -void Constant::dump() -{ - PRINTF("(CONST %s\n", name); - body->show(); - PRINTF(")\n"); -} -void Teleport::dump() -{ - PRINTF("(TELEPORT-ANCHOR %s\n", name); - ident->show(); - body->show(); - PRINTF(")\n"); -} -void Procedure::dump() -{ - PRINTF("(PROCEDURE %s\n", name); - PRINTF("("); - for (RString& a : *args) - PRINTF(" %s ", a); - PRINTF(")\n"); - for (Effect *f : *body) - { - f->print(); - } - PRINTF(")\n"); -} -void Spell::dump() -{ - PRINTF("(SPELL \n"); - PRINTF("("); - for (RString fl : *flags) - PRINTF(" %s ", fl); - PRINTF(")"); - PRINTF("%s", name); - ident->show(); - PRINTF("( %s %s )", arg->vartype, arg->varname); - for (Assignment *a : *body->lets) - { - PRINTF("(LET %s ", a->name); - a->body->show(); - PRINTF(")\n"); - } - for (SpellBod *b : *body->body) - { - b->say(); - } - PRINTF(")\n"); -} -void Assignment::dump() -{ - PRINTF("(SET %s\n", name); - body->show(); - PRINTF(")\n"); -} - -void EffectList::print() -{ - PRINTF("(BLOCK\n"); - for (Effect *ef : *body) - ef->print(); - PRINTF(")\n"); -} -void SimpleEffect::print() -{ - PRINTF("( %s )", text); -} -void ScriptEffect::print() -{ - PRINTF("(SCRIPT %s )", text); -} -void Assignment::print() -{ - PRINTF("(SET %s\n", name); - body->show(); - PRINTF(")\n"); -} -void ForeachEffect::print() -{ - PRINTF("(FOREACH %s %s ", selection, var); - expr->show(); - PRINTF("\n"); - effect->print(); - PRINTF(")"); -} -void ForEffect::print() -{ - PRINTF("(FOR %s", var); - low->show(); - high->show(); - effect->print(); - PRINTF(")"); -} -void IfEffect::print() -{ - PRINTF("(IF "); - cond->show(); - if_true->print(); - if (if_false_maybe) - if_false_maybe->print(); - PRINTF(")"); -} -void ExplicitCallEffect::print() -{ - PRINTF("(CALL %s ", userfunc); - for (Expression *x : *args) - x->show(); - PRINTF(")"); -} -void SleepEffect::print() -{ - PRINTF("(WAIT "); - time_->show(); - PRINTF(")"); -} -void CallExpr::print() -{ - PRINTF("(%s ", func); - for (Expression *x : *args) - x->show(); - PRINTF(")"); -} - -void SimpleExpr::show() -{ - PRINTF(" %s ", content); -} -void BinExpr::show() -{ - PRINTF("(%s ", op); - left->show(); - right->show(); - PRINTF(")"); -} -void CallExpr::show() -{ - PRINTF("(%s ", func); - for (Expression *x : *args) - x->show(); - PRINTF(")"); -} -void AreaLoc::show() -{ - PRINTF("(@ "); - loc->map->show(); - loc->x->show(); - loc->y->show(); - PRINTF(")"); -} -void AreaRect::show() -{ - PRINTF("(@+ "); - AreaLoc{loc}.show(); - width->show(); - height->show(); - PRINTF(")"); -} -void AreaBar::show() -{ - PRINTF("(TOWARD "); - AreaLoc{loc}.show(); - dir->show(); - width->show(); - depth->show(); - PRINTF(")"); -} - -void SpellBodGuarded::say() -{ - PRINTF("(=> "); - guard->declare(); - body->say(); - PRINTF(")"); -} -void SpellBodList::say() -{ - PRINTF("(|\n"); - for (SpellBod *b : *body) - b->say(); - PRINTF(")"); -} -void SpellBodEffect::say() -{ - PRINTF("(EFFECT\n"); - for (Effect *f : *body) - f->print(); - if (maybe_trigger) - { - PRINTF("(ATTRIGGER\n"); - for (Effect *f : *maybe_trigger) - f->print(); - PRINTF(")"); - } - if (maybe_end) - { - PRINTF("(ATEND\n"); - for (Effect *f : *maybe_end) - f->print(); - PRINTF(")"); - } - PRINTF(")"); -} - -void SpellGuardOr::declare() -{ - PRINTF("(OR\n"); - for (SpellGuard *sg : *any) - sg->declare(); - PRINTF(")"); -} -void SpellGuardList::declare() -{ - PRINTF("(GUARD\n"); - for (SpellGuard *sg : *all) - sg->declare(); - PRINTF(")"); -} -void SpellGuardRequire::declare() -{ - PRINTF("(REQUIRE "); - expr->show(); - PRINTF(")"); -} -static -void do_item(Item *itm) -{ - if (itm->count) - PRINTF("( %s %s )", itm->count, itm->item); - else - PRINTF(" %s ", itm->item); -} -void SpellGuardCatalysts::declare() -{ - PRINTF("(CATALYSTS "); - for (Item *itm : *items) - do_item(itm); - PRINTF(")"); -} -void SpellGuardComponents::declare() -{ - PRINTF("(COMPONENTS "); - for (Item *itm : *items) - do_item(itm); - PRINTF(")"); -} -void SpellGuardMana::declare() -{ - PRINTF("(MANA "); - sp->show(); - PRINTF(")"); -} -void SpellGuardCasttime::declare() -{ - PRINTF("(CASTTIME "); - time_->show(); - PRINTF(")"); -} diff --git a/src/spell-convert/ast.hpp b/src/spell-convert/ast.hpp deleted file mode 100644 index 3d2f282..0000000 --- a/src/spell-convert/ast.hpp +++ /dev/null @@ -1,465 +0,0 @@ -#ifndef TMWA_SPELL_CONVERT_AST_HPP -#define TMWA_SPELL_CONVERT_AST_HPP -// ast.hpp - Hacky converter between magic formats. -// -// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -# include "../sanity.hpp" - -# include <deque> -# include <vector> - -# include "../strings/rstring.hpp" - -# if __GNUC__ == 4 && __GNUC_MINOR__ == 6 -# define override -# endif - -// We just leak -# pragma GCC diagnostic ignored "-Wnon-virtual-dtor" - -struct TopLevel; -struct Constant; -struct Teleport; -struct Procedure; -struct Spell; -struct SpellArg; -struct Effect; -struct EffectList; -struct SimpleEffect; -struct ScriptEffect; -struct Assignment; -struct ForeachEffect; -struct ForEffect; -struct IfEffect; -struct ExplicitCallEffect; -struct SleepEffect; -struct SpellDef; -struct SpellBod; -struct SpellBodGuarded; -struct SpellBodList; -struct SpellBodEffect; -struct SpellGuard; -struct SpellGuardOr; -struct SpellGuardList; -struct SpellGuardRequire; -struct SpellGuardCatalysts; -struct SpellGuardComponents; -struct SpellGuardMana; -struct SpellGuardCasttime; -struct Item; -struct Expression; -struct SimpleExpr; -struct BinExpr; -struct CallExpr; -struct Location; -struct AreaLoc; -struct AreaRect; -struct AreaBar; - - -struct TopLevel -{ - virtual void dump() = 0; -}; - -struct Constant : TopLevel -{ - RString name; - Expression *body; - - Constant(RString n, Expression *b) - : name(n), body(b) - {} - - virtual void dump() override; -}; - -struct Teleport : TopLevel -{ - RString name; - Expression *ident; - Expression *body; - - Teleport(RString n, Expression *i, Expression *b) - : name(n), ident(i), body(b) - {} - - virtual void dump() override; -}; - -struct Procedure : TopLevel -{ - RString name; - std::vector<RString> *args; - std::deque<Effect *> *body; - - Procedure(RString n, std::vector<RString> *a, std::deque<Effect *> *b) - : name(n), args(a), body(b) - {} - - virtual void dump() override; -}; - -struct Spell : TopLevel -{ - std::vector<RString> *flags; - RString name; - SpellArg *arg; - Expression *ident; - SpellDef *body; - - Spell(std::vector<RString> *f, RString n, SpellArg *a, Expression *i, SpellDef *b) - : flags(f), name(n), arg(a), ident(i), body(b) - {} - - virtual void dump() override; -}; - -struct SpellArg -{ - RString varname; - RString vartype; - - SpellArg() : varname(), vartype() {} - SpellArg(RString n, RString t) : varname(n), vartype(t) {} -}; - -struct Effect -{ - virtual void print() = 0; -}; - -struct EffectList : Effect -{ - std::deque<Effect *> *body; - - EffectList(std::deque<Effect *> *b) - : body(b) - {} - - virtual void print() override; -}; -struct SimpleEffect : Effect -{ - RString text; - - SimpleEffect(RString t) : text(t) {} - - virtual void print() override; -}; -struct ScriptEffect : Effect -{ - RString text; - - ScriptEffect(RString t) : text(t) {} - - virtual void print() override; -}; - -struct Assignment : TopLevel, Effect -{ - RString name; - Expression *body; - - Assignment(RString n, Expression *b) - : name(n), body(b) - {} - - // toplevel - virtual void dump() override; - // effect - virtual void print() override; -}; - -struct ForeachEffect : Effect -{ - RString selection; - RString var; - Expression *expr; - Effect *effect; - - ForeachEffect(RString s, RString v, Expression *x, Effect *f) - : selection(s), var(v), expr(x), effect(f) - {} - - virtual void print() override; -}; - -struct ForEffect : Effect -{ - RString var; - Expression *low; - Expression *high; - Effect *effect; - - ForEffect(RString v, Expression *l, Expression *h, Effect *f) - : var(v), low(l), high(h), effect(f) - {} - - virtual void print() override; -}; - -struct IfEffect : Effect -{ - Expression *cond; - Effect *if_true; - Effect *if_false_maybe; - - IfEffect(Expression *c, Effect *t, Effect *f=nullptr) - : cond(c), if_true(t), if_false_maybe(f) - {} - - virtual void print() override; -}; - -struct ExplicitCallEffect : Effect -{ - RString userfunc; - std::vector<Expression *> *args; - - ExplicitCallEffect(RString f, std::vector<Expression *> *a) - : userfunc(f), args(a) - {} - - virtual void print() override; -}; - -struct SleepEffect : Effect -{ - Expression *time_; - - SleepEffect(Expression *t) - : time_(t) - {} - - virtual void print() override; -}; - -struct SpellDef -{ - std::vector<Assignment *> *lets; - std::vector<SpellBod *> *body; -}; - -struct SpellBod -{ - virtual void say() = 0; -}; - -struct SpellBodGuarded : SpellBod -{ - SpellGuard *guard; - SpellBod *body; - - SpellBodGuarded(SpellGuard *g, SpellBod *b) - : guard(g), body(b) - {} - - virtual void say() override; -}; - -struct SpellBodList : SpellBod -{ - std::vector<SpellBod *> *body; - - SpellBodList(std::vector<SpellBod *> *b) - : body(b) - {} - - virtual void say() override; -}; - -struct SpellBodEffect : SpellBod -{ - std::deque<Effect *> *body; - std::deque<Effect *> *maybe_trigger; - std::deque<Effect *> *maybe_end; - - SpellBodEffect(std::deque<Effect *> *b, std::deque<Effect *> *t, std::deque<Effect *> *e) - : body(b), maybe_trigger(t), maybe_end(e) - {} - - virtual void say() override; -}; - -struct SpellGuard -{ - virtual void declare() = 0; -}; - -struct SpellGuardOr : SpellGuard -{ - std::vector<SpellGuard *> *any; - - SpellGuardOr(std::vector<SpellGuard *> *a) : any(a) {} - SpellGuardOr(SpellGuard *left, SpellGuard *right) - : any(new std::vector<SpellGuard *>({left, right})) - {} - - virtual void declare() override; -}; -struct SpellGuardList : SpellGuard -{ - std::vector<SpellGuard *> *all; - - SpellGuardList(std::vector<SpellGuard *> *a) : all(a) {} - - virtual void declare() override; -}; -struct SpellGuardRequire : SpellGuard -{ - Expression *expr; - - SpellGuardRequire(Expression *x) : expr(x) {} - - virtual void declare() override; -}; -struct SpellGuardCatalysts : SpellGuard -{ - std::vector<Item *> *items; - - SpellGuardCatalysts(std::vector<Item *> *i) : items(i) {} - - virtual void declare() override; -}; -struct SpellGuardComponents : SpellGuard -{ - std::vector<Item *> *items; - - SpellGuardComponents(std::vector<Item *> *i) : items(i) {} - - virtual void declare() override; -}; -struct SpellGuardMana : SpellGuard -{ - Expression *sp; - - SpellGuardMana(Expression *x) : sp(x) {} - - virtual void declare() override; -}; -struct SpellGuardCasttime : SpellGuard -{ - Expression *time_; - - SpellGuardCasttime(Expression *x) : time_(x) {} - - virtual void declare() override; -}; - -struct Item -{ - RString count; - RString item; - - Item(RString c, RString i) : count(c), item(i) {} -}; - -struct Expression -{ - virtual void show() = 0; -}; - -struct SimpleExpr : Expression -{ - RString content; - - SimpleExpr(RString c) : content(c) {} - - virtual void show() override; -}; - -struct BinExpr : Expression -{ - Expression *left; - RString op; - Expression *right; - - BinExpr(Expression *l, RString o, Expression *r) - : left(l), op(o), right(r) - {} - - virtual void show() override; -}; - -struct CallExpr : Expression, Effect -{ - RString func; - std::vector<Expression *> *args; - - CallExpr(RString f, std::vector<Expression *> *a) - : func(f), args(a) - {} - - // expression - virtual void show() override; - // effect - virtual void print() override; -}; - -struct Location -{ - Expression *map; - Expression *x; - Expression *y; -}; - -struct AreaLoc : Expression -{ - Location *loc; - - AreaLoc(Location *l) - : loc(l) - {} - - virtual void show() override; -}; - -struct AreaRect : Expression -{ - Location *loc; - Expression *width; - Expression *height; - - AreaRect(Location *l, Expression *w, Expression *h) - : loc(l), width(w), height(h) - {} - - virtual void show() override; -}; - -struct AreaBar : Expression -{ - Location *loc; - Expression *dir; - Expression *width; - Expression *depth; - - AreaBar(Location *l, Expression *a, Expression *w, Expression *d) - : loc(l), dir(a), width(w), depth(d) - {} - - virtual void show() override; -}; - -# ifdef override -# undef override -# endif - -#endif // TMWA_SPELL_CONVERT_AST_HPP diff --git a/src/spell-convert/lexer.cpp b/src/spell-convert/lexer.cpp deleted file mode 100644 index e06817f..0000000 --- a/src/spell-convert/lexer.cpp +++ /dev/null @@ -1,2331 +0,0 @@ -#line 2 "src/spell-convert/lexer.cpp" - -#line 4 "src/spell-convert/lexer.cpp" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define yy_create_buffer spell_converter_create_buffer -#define yy_delete_buffer spell_converter_delete_buffer -#define yy_flex_debug spell_converter_flex_debug -#define yy_init_buffer spell_converter_init_buffer -#define yy_flush_buffer spell_converter_flush_buffer -#define yy_load_buffer_state spell_converter_load_buffer_state -#define yy_switch_to_buffer spell_converter_switch_to_buffer -#define yyin spell_converterin -#define yyleng spell_converterleng -#define yylex spell_converterlex -#define yylineno spell_converterlineno -#define yyout spell_converterout -#define yyrestart spell_converterrestart -#define yytext spell_convertertext -#define yywrap spell_converterwrap -#define yyalloc spell_converteralloc -#define yyrealloc spell_converterrealloc -#define yyfree spell_converterfree - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include <inttypes.h> -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN (yy_start) = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START (((yy_start) - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE spell_converterrestart(spell_converterin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -extern int spell_converterleng; - -extern FILE *spell_converterin, *spell_converterout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up spell_convertertext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up spell_convertertext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, (yytext_ptr) ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via spell_converterrestart()), so that the user can continue scanning by - * just pointing spell_converterin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* Stack of input buffers. */ -static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - -/* yy_hold_char holds the character lost when spell_convertertext is formed. */ -static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ -int spell_converterleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 0; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow spell_converterwrap()'s to do buffer switches - * instead of setting up a fresh spell_converterin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void spell_converterrestart (FILE *input_file ); -void spell_converter_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE spell_converter_create_buffer (FILE *file,int size ); -void spell_converter_delete_buffer (YY_BUFFER_STATE b ); -void spell_converter_flush_buffer (YY_BUFFER_STATE b ); -void spell_converterpush_buffer_state (YY_BUFFER_STATE new_buffer ); -void spell_converterpop_buffer_state (void ); - -static void spell_converterensure_buffer_stack (void ); -static void spell_converter_load_buffer_state (void ); -static void spell_converter_init_buffer (YY_BUFFER_STATE b,FILE *file ); - -#define YY_FLUSH_BUFFER spell_converter_flush_buffer(YY_CURRENT_BUFFER ) - -YY_BUFFER_STATE spell_converter_scan_buffer (char *base,yy_size_t size ); -YY_BUFFER_STATE spell_converter_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE spell_converter_scan_bytes (yyconst char *bytes,int len ); - -void *spell_converteralloc (yy_size_t ); -void *spell_converterrealloc (void *,yy_size_t ); -void spell_converterfree (void * ); - -#define yy_new_buffer spell_converter_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - spell_converterensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - spell_converter_create_buffer(spell_converterin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - spell_converterensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - spell_converter_create_buffer(spell_converterin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define spell_converterwrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -FILE *spell_converterin = (FILE *) 0, *spell_converterout = (FILE *) 0; - -typedef int yy_state_type; - -extern int spell_converterlineno; - -int spell_converterlineno = 1; - -extern char *spell_convertertext; -#define yytext_ptr spell_convertertext - -static yy_state_type yy_get_previous_state (void ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); -static int yy_get_next_buffer (void ); -static void yy_fatal_error (yyconst char msg[] ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up spell_convertertext. - */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - spell_converterleng = (size_t) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - -#define YY_NUM_RULES 86 -#define YY_END_OF_BUFFER 87 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[240] = - { 0, - 0, 0, 87, 85, 84, 84, 85, 85, 85, 23, - 33, 17, 18, 21, 19, 28, 20, 35, 22, 79, - 79, 27, 26, 14, 9, 13, 29, 81, 81, 81, - 81, 7, 81, 81, 81, 81, 81, 5, 81, 81, - 81, 1, 81, 3, 31, 32, 34, 85, 30, 12, - 0, 78, 0, 0, 82, 24, 79, 0, 0, 36, - 16, 11, 10, 51, 15, 37, 81, 81, 81, 81, - 81, 81, 75, 81, 81, 81, 81, 70, 49, 81, - 81, 81, 81, 6, 81, 81, 4, 40, 65, 81, - 81, 8, 81, 81, 81, 81, 2, 81, 81, 81, - - 41, 81, 0, 0, 77, 25, 0, 78, 0, 0, - 83, 80, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 50, 81, 74, 48, 81, 81, 67, - 81, 66, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 0, 0, 77, 81, 81, 81, 81, - 39, 81, 81, 81, 81, 81, 72, 81, 81, 81, - 56, 81, 81, 81, 81, 58, 81, 81, 81, 81, - 71, 81, 76, 59, 62, 81, 60, 81, 81, 81, - 64, 81, 81, 81, 45, 81, 81, 81, 81, 47, - 81, 81, 81, 81, 81, 81, 81, 81, 61, 68, - - 81, 81, 81, 81, 44, 52, 69, 81, 81, 81, - 81, 81, 81, 73, 81, 81, 53, 81, 42, 81, - 57, 81, 81, 46, 81, 81, 63, 54, 81, 38, - 81, 55, 81, 81, 81, 81, 81, 43, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 5, 6, 1, 7, 8, 1, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, - 22, 23, 1, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 34, 46, 34, 47, 34, - 48, 49, 50, 51, 52, 1, 53, 53, 53, 53, - - 53, 53, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 54, - 34, 34, 55, 56, 57, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[58] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, - 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, - 1, 2, 3, 2, 1, 1, 1 - } ; - -static yyconst flex_int16_t yy_base[248] = - { 0, - 0, 0, 289, 290, 290, 290, 266, 53, 284, 290, - 278, 290, 290, 290, 290, 290, 42, 290, 269, 44, - 46, 290, 290, 44, 46, 48, 290, 46, 242, 48, - 244, 44, 243, 0, 45, 47, 52, 49, 239, 52, - 251, 64, 80, 254, 290, 290, 290, 35, 222, 290, - 76, 290, 98, 274, 290, 290, 89, 273, 0, 290, - 290, 290, 290, 290, 290, 290, 0, 236, 56, 245, - 77, 77, 0, 243, 229, 83, 229, 0, 0, 226, - 242, 230, 241, 0, 228, 238, 0, 0, 0, 225, - 222, 0, 226, 228, 231, 217, 0, 216, 221, 227, - - 209, 221, 67, 93, 290, 290, 112, 113, 123, 250, - 290, 0, 210, 213, 208, 224, 212, 203, 221, 205, - 201, 214, 213, 0, 208, 211, 0, 214, 213, 0, - 200, 0, 209, 190, 205, 193, 196, 198, 199, 200, - 190, 202, 182, 73, 120, 80, 181, 196, 190, 187, - 0, 177, 184, 180, 174, 190, 0, 172, 190, 178, - 0, 188, 183, 178, 172, 0, 173, 170, 178, 166, - 0, 163, 0, 0, 0, 173, 0, 170, 155, 163, - 0, 156, 152, 171, 0, 145, 147, 132, 129, 0, - 140, 126, 129, 139, 135, 128, 121, 134, 0, 0, - - 128, 126, 113, 128, 0, 0, 0, 114, 112, 125, - 124, 108, 113, 0, 122, 106, 0, 102, 0, 103, - 0, 101, 99, 0, 112, 126, 0, 0, 96, 0, - 113, 0, 98, 108, 102, 94, 90, 0, 290, 177, - 180, 182, 185, 188, 191, 128, 194 - } ; - -static yyconst flex_int16_t yy_def[248] = - { 0, - 239, 1, 239, 239, 239, 239, 239, 240, 241, 239, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - 239, 239, 239, 239, 239, 239, 239, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 239, 239, 239, 243, 239, 239, - 240, 239, 244, 241, 239, 239, 239, 245, 246, 239, - 239, 239, 239, 239, 239, 239, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 243, 247, 239, 239, 240, 240, 244, 245, - 239, 246, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 243, 247, 243, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 0, 239, - 239, 239, 239, 239, 239, 239, 239 - } ; - -static yyconst flex_int16_t yy_nxt[348] = - { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 34, 35, 34, 34, 36, 37, 38, 39, 40, - 34, 41, 42, 43, 34, 44, 34, 45, 4, 46, - 47, 4, 34, 34, 48, 49, 4, 52, 57, 57, - 57, 57, 57, 57, 60, 61, 62, 63, 64, 65, - 66, 68, 71, 74, 78, 80, 82, 84, 89, 75, - 52, 76, 79, 104, 114, 81, 72, 85, 86, 69, - 83, 105, 92, 90, 87, 103, 93, 59, 94, 115, - - 51, 53, 108, 95, 98, 57, 57, 96, 99, 97, - 124, 100, 117, 120, 121, 104, 52, 52, 101, 118, - 119, 104, 103, 105, 53, 51, 125, 108, 104, 105, - 112, 238, 237, 236, 235, 234, 105, 233, 232, 231, - 230, 145, 229, 228, 227, 226, 109, 225, 224, 146, - 223, 222, 221, 220, 219, 218, 217, 216, 215, 214, - 53, 53, 213, 212, 211, 210, 209, 208, 145, 207, - 206, 109, 205, 204, 203, 202, 146, 51, 51, 51, - 54, 54, 54, 67, 67, 103, 103, 103, 107, 107, - 107, 110, 110, 110, 144, 144, 144, 201, 200, 199, - - 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, - 188, 187, 186, 185, 184, 183, 182, 181, 180, 179, - 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, - 168, 167, 166, 165, 164, 163, 162, 161, 160, 159, - 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, - 148, 147, 111, 143, 142, 141, 140, 139, 138, 137, - 136, 135, 134, 133, 132, 131, 130, 129, 128, 127, - 126, 123, 122, 116, 113, 111, 55, 106, 102, 91, - 88, 77, 73, 70, 58, 56, 55, 50, 239, 3, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - 239, 239, 239, 239, 239, 239, 239 - } ; - -static yyconst flex_int16_t yy_chk[348] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 8, 17, 17, - 20, 20, 21, 21, 24, 24, 24, 25, 25, 26, - 26, 28, 30, 32, 35, 36, 37, 38, 40, 32, - 51, 32, 35, 48, 69, 36, 30, 38, 38, 28, - 37, 48, 42, 40, 38, 104, 42, 20, 42, 69, - - 53, 8, 53, 42, 43, 57, 57, 42, 43, 42, - 76, 43, 71, 72, 72, 103, 107, 108, 43, 71, - 71, 144, 145, 103, 51, 109, 76, 109, 146, 144, - 246, 237, 236, 235, 234, 233, 146, 231, 229, 226, - 225, 104, 223, 222, 220, 218, 53, 216, 215, 104, - 213, 212, 211, 210, 209, 208, 204, 203, 202, 201, - 107, 108, 198, 197, 196, 195, 194, 193, 145, 192, - 191, 109, 189, 188, 187, 186, 145, 240, 240, 240, - 241, 241, 241, 242, 242, 243, 243, 243, 244, 244, - 244, 245, 245, 245, 247, 247, 247, 184, 183, 182, - - 180, 179, 178, 176, 172, 170, 169, 168, 167, 165, - 164, 163, 162, 160, 159, 158, 156, 155, 154, 153, - 152, 150, 149, 148, 147, 143, 142, 141, 140, 139, - 138, 137, 136, 135, 134, 133, 131, 129, 128, 126, - 125, 123, 122, 121, 120, 119, 118, 117, 116, 115, - 114, 113, 110, 102, 101, 100, 99, 98, 96, 95, - 94, 93, 91, 90, 86, 85, 83, 82, 81, 80, - 77, 75, 74, 70, 68, 58, 54, 49, 44, 41, - 39, 33, 31, 29, 19, 11, 9, 7, 3, 239, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - 239, 239, 239, 239, 239, 239, 239 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -extern int spell_converter_flex_debug; -int spell_converter_flex_debug = 0; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *spell_convertertext; -#line 1 "../src/spell-convert/lexer.lpp" -#line 2 "../src/spell-convert/lexer.lpp" -/* vim: set ft=lex: */ -//#include "lexer.hpp" - -#include "../strings/rstring.hpp" -#include "../strings/zstring.hpp" - -#include "../io/cxxstdio.hpp" - -#include "../sexpr/lexer.hpp" - -#include "parser.hpp" - -#define yylval spell_converterlval - -RString *str(const char *s) -{ - return new RString(ZString(strings::really_construct_from_a_pointer, s, nullptr)); -} -#define YY_NO_INPUT 1 -#line 657 "src/spell-convert/lexer.cpp" - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include <unistd.h> -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -static int yy_init_globals (void ); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int spell_converterlex_destroy (void ); - -int spell_converterget_debug (void ); - -void spell_converterset_debug (int debug_flag ); - -YY_EXTRA_TYPE spell_converterget_extra (void ); - -void spell_converterset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *spell_converterget_in (void ); - -void spell_converterset_in (FILE * in_str ); - -FILE *spell_converterget_out (void ); - -void spell_converterset_out (FILE * out_str ); - -int spell_converterget_leng (void ); - -char *spell_converterget_text (void ); - -int spell_converterget_lineno (void ); - -void spell_converterset_lineno (int line_number ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int spell_converterwrap (void ); -#else -extern int spell_converterwrap (void ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (void ); -#else -static int input (void ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( spell_convertertext, spell_converterleng, 1, spell_converterout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( spell_converterin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( spell_converterin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, spell_converterin))==0 && ferror(spell_converterin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(spell_converterin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int spell_converterlex (void); - -#define YY_DECL int spell_converterlex (void) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after spell_convertertext and spell_converterleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 27 "../src/spell-convert/lexer.lpp" - - -#line 845 "src/spell-convert/lexer.cpp" - - if ( !(yy_init) ) - { - (yy_init) = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ - - if ( ! spell_converterin ) - spell_converterin = stdin; - - if ( ! spell_converterout ) - spell_converterout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - spell_converterensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - spell_converter_create_buffer(spell_converterin,YY_BUF_SIZE ); - } - - spell_converter_load_buffer_state( ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - - /* Support of spell_convertertext. */ - *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = (yy_start); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 240 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 290 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = (yy_hold_char); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 29 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return DIR; } - YY_BREAK -case 2: -YY_RULE_SETUP -#line 30 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return DIR; } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 31 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return DIR; } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 32 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return DIR; } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 33 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return DIR; } - YY_BREAK -case 6: -YY_RULE_SETUP -#line 34 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return DIR; } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 35 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return DIR; } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 36 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return DIR; } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 37 "../src/spell-convert/lexer.lpp" -{ return '='; } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 38 "../src/spell-convert/lexer.lpp" -{ return EQ; } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 39 "../src/spell-convert/lexer.lpp" -{ return NEQ; } - YY_BREAK -case 12: -YY_RULE_SETUP -#line 40 "../src/spell-convert/lexer.lpp" -{ return NEQ; } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 41 "../src/spell-convert/lexer.lpp" -{ return '>'; } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 42 "../src/spell-convert/lexer.lpp" -{ return '<'; } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 43 "../src/spell-convert/lexer.lpp" -{ return GTE; } - YY_BREAK -case 16: -YY_RULE_SETUP -#line 44 "../src/spell-convert/lexer.lpp" -{ return LTE; } - YY_BREAK -case 17: -YY_RULE_SETUP -#line 45 "../src/spell-convert/lexer.lpp" -{ return '('; } - YY_BREAK -case 18: -YY_RULE_SETUP -#line 46 "../src/spell-convert/lexer.lpp" -{ return ')'; } - YY_BREAK -case 19: -YY_RULE_SETUP -#line 47 "../src/spell-convert/lexer.lpp" -{ return '+'; } - YY_BREAK -case 20: -YY_RULE_SETUP -#line 48 "../src/spell-convert/lexer.lpp" -{ return '-'; } - YY_BREAK -case 21: -YY_RULE_SETUP -#line 49 "../src/spell-convert/lexer.lpp" -{ return '*'; } - YY_BREAK -case 22: -YY_RULE_SETUP -#line 50 "../src/spell-convert/lexer.lpp" -{ return '/'; } - YY_BREAK -case 23: -YY_RULE_SETUP -#line 51 "../src/spell-convert/lexer.lpp" -{ return '%'; } - YY_BREAK -case 24: -YY_RULE_SETUP -#line 52 "../src/spell-convert/lexer.lpp" -{ return ANDAND; } - YY_BREAK -case 25: -YY_RULE_SETUP -#line 53 "../src/spell-convert/lexer.lpp" -{ return OROR; } - YY_BREAK -case 26: -YY_RULE_SETUP -#line 54 "../src/spell-convert/lexer.lpp" -{ return ';'; } - YY_BREAK -case 27: -YY_RULE_SETUP -#line 55 "../src/spell-convert/lexer.lpp" -{ return ':'; } - YY_BREAK -case 28: -YY_RULE_SETUP -#line 56 "../src/spell-convert/lexer.lpp" -{ return ','; } - YY_BREAK -case 29: -YY_RULE_SETUP -#line 57 "../src/spell-convert/lexer.lpp" -{ return '@'; } - YY_BREAK -case 30: -YY_RULE_SETUP -#line 58 "../src/spell-convert/lexer.lpp" -{ return '|'; } - YY_BREAK -case 31: -YY_RULE_SETUP -#line 59 "../src/spell-convert/lexer.lpp" -{ return '['; } - YY_BREAK -case 32: -YY_RULE_SETUP -#line 60 "../src/spell-convert/lexer.lpp" -{ return ']'; } - YY_BREAK -case 33: -YY_RULE_SETUP -#line 61 "../src/spell-convert/lexer.lpp" -{ return '&'; } - YY_BREAK -case 34: -YY_RULE_SETUP -#line 62 "../src/spell-convert/lexer.lpp" -{ return '^'; } - YY_BREAK -case 35: -YY_RULE_SETUP -#line 63 "../src/spell-convert/lexer.lpp" -{ return '.'; } - YY_BREAK -case 36: -YY_RULE_SETUP -#line 64 "../src/spell-convert/lexer.lpp" -{ return SHL; } - YY_BREAK -case 37: -YY_RULE_SETUP -#line 65 "../src/spell-convert/lexer.lpp" -{ return SHR; } - YY_BREAK -case 38: -YY_RULE_SETUP -#line 66 "../src/spell-convert/lexer.lpp" -{ return PROCEDURE; } - YY_BREAK -case 39: -YY_RULE_SETUP -#line 67 "../src/spell-convert/lexer.lpp" -{ return CALL; } - YY_BREAK -case 40: -YY_RULE_SETUP -#line 68 "../src/spell-convert/lexer.lpp" -{ return OR; } - YY_BREAK -case 41: -YY_RULE_SETUP -#line 69 "../src/spell-convert/lexer.lpp" -{ return TO; } - YY_BREAK -case 42: -YY_RULE_SETUP -#line 70 "../src/spell-convert/lexer.lpp" -{ return TOWARDS; } - YY_BREAK -case 43: -YY_RULE_SETUP -#line 71 "../src/spell-convert/lexer.lpp" -{ return TELEPORT_ANCHOR; } - YY_BREAK -case 44: -YY_RULE_SETUP -#line 72 "../src/spell-convert/lexer.lpp" -{ return SILENT; } - YY_BREAK -case 45: -YY_RULE_SETUP -#line 73 "../src/spell-convert/lexer.lpp" -{ return LOCAL; } - YY_BREAK -case 46: -YY_RULE_SETUP -#line 74 "../src/spell-convert/lexer.lpp" -{ return NONMAGIC; } - YY_BREAK -case 47: -YY_RULE_SETUP -#line 75 "../src/spell-convert/lexer.lpp" -{ return SPELL; } - YY_BREAK -case 48: -YY_RULE_SETUP -#line 76 "../src/spell-convert/lexer.lpp" -{ return LET; } - YY_BREAK -case 49: -YY_RULE_SETUP -#line 77 "../src/spell-convert/lexer.lpp" -{ return IN; } - YY_BREAK -case 50: -YY_RULE_SETUP -#line 78 "../src/spell-convert/lexer.lpp" -{ return END; } - YY_BREAK -case 51: -YY_RULE_SETUP -#line 79 "../src/spell-convert/lexer.lpp" -{ return DARROW; } - YY_BREAK -case 52: -YY_RULE_SETUP -#line 80 "../src/spell-convert/lexer.lpp" -{ return STRING_TY; } - YY_BREAK -case 53: -YY_RULE_SETUP -#line 81 "../src/spell-convert/lexer.lpp" -{ return REQUIRE; } - YY_BREAK -case 54: -YY_RULE_SETUP -#line 82 "../src/spell-convert/lexer.lpp" -{ return CATALYSTS; } - YY_BREAK -case 55: -YY_RULE_SETUP -#line 83 "../src/spell-convert/lexer.lpp" -{ return COMPONENTS; } - YY_BREAK -case 56: -YY_RULE_SETUP -#line 84 "../src/spell-convert/lexer.lpp" -{ return MANA; } - YY_BREAK -case 57: -YY_RULE_SETUP -#line 85 "../src/spell-convert/lexer.lpp" -{ return CASTTIME; } - YY_BREAK -case 58: -YY_RULE_SETUP -#line 86 "../src/spell-convert/lexer.lpp" -{ return SKIP; } - YY_BREAK -case 59: -YY_RULE_SETUP -#line 87 "../src/spell-convert/lexer.lpp" -{ return ABORT; } - YY_BREAK -case 60: -YY_RULE_SETUP -#line 88 "../src/spell-convert/lexer.lpp" -{ return BREAK; } - YY_BREAK -case 61: -YY_RULE_SETUP -#line 89 "../src/spell-convert/lexer.lpp" -{ return EFFECT_; } - YY_BREAK -case 62: -YY_RULE_SETUP -#line 90 "../src/spell-convert/lexer.lpp" -{ return ATEND; } - YY_BREAK -case 63: -YY_RULE_SETUP -#line 91 "../src/spell-convert/lexer.lpp" -{ return ATTRIGGER; } - YY_BREAK -case 64: -YY_RULE_SETUP -#line 92 "../src/spell-convert/lexer.lpp" -{ return CONST; } - YY_BREAK -case 65: -YY_RULE_SETUP -#line 93 "../src/spell-convert/lexer.lpp" -{ return PC_F; } - YY_BREAK -case 66: -YY_RULE_SETUP -#line 94 "../src/spell-convert/lexer.lpp" -{ return NPC_F; } - YY_BREAK -case 67: -YY_RULE_SETUP -#line 95 "../src/spell-convert/lexer.lpp" -{ return MOB_F; } - YY_BREAK -case 68: -YY_RULE_SETUP -#line 96 "../src/spell-convert/lexer.lpp" -{ return ENTITY_F; } - YY_BREAK -case 69: -YY_RULE_SETUP -#line 97 "../src/spell-convert/lexer.lpp" -{ return TARGET_F; } - YY_BREAK -case 70: -YY_RULE_SETUP -#line 98 "../src/spell-convert/lexer.lpp" -{ return IF; } - YY_BREAK -case 71: -YY_RULE_SETUP -#line 99 "../src/spell-convert/lexer.lpp" -{ return THEN; } - YY_BREAK -case 72: -YY_RULE_SETUP -#line 100 "../src/spell-convert/lexer.lpp" -{ return ELSE; } - YY_BREAK -case 73: -YY_RULE_SETUP -#line 101 "../src/spell-convert/lexer.lpp" -{ return FOREACH; } - YY_BREAK -case 74: -YY_RULE_SETUP -#line 102 "../src/spell-convert/lexer.lpp" -{ return FOR; } - YY_BREAK -case 75: -YY_RULE_SETUP -#line 103 "../src/spell-convert/lexer.lpp" -{ return DO; } - YY_BREAK -case 76: -YY_RULE_SETUP -#line 104 "../src/spell-convert/lexer.lpp" -{ return SLEEP; } - YY_BREAK -case 77: -/* rule 77 can match eol */ -YY_RULE_SETUP -#line 106 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return SCRIPT_DATA; } - YY_BREAK -case 78: -/* rule 78 can match eol */ -YY_RULE_SETUP -#line 107 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return STRING; } - YY_BREAK -case 79: -YY_RULE_SETUP -#line 108 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return INT; } - YY_BREAK -case 80: -YY_RULE_SETUP -#line 109 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return INT; } - YY_BREAK -case 81: -YY_RULE_SETUP -#line 110 "../src/spell-convert/lexer.lpp" -{ yylval.s = str(spell_convertertext); return ID; } - YY_BREAK -case 82: -*yy_cp = (yy_hold_char); /* undo effects of setting up spell_convertertext */ -(yy_c_buf_p) = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up spell_convertertext again */ -YY_RULE_SETUP -#line 111 "../src/spell-convert/lexer.lpp" -{ PRINTF("%s\n", sexpr::escape(*str(spell_convertertext + 1))); } - YY_BREAK -case 83: -*yy_cp = (yy_hold_char); /* undo effects of setting up spell_convertertext */ -(yy_c_buf_p) = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up spell_convertertext again */ -YY_RULE_SETUP -#line 112 "../src/spell-convert/lexer.lpp" -{ PRINTF("%s\n", sexpr::escape(*str(spell_convertertext + 2))); } - YY_BREAK -case 84: -/* rule 84 can match eol */ -YY_RULE_SETUP -#line 113 "../src/spell-convert/lexer.lpp" -/* ignore whitespace */ - YY_BREAK -case 85: -YY_RULE_SETUP -#line 114 "../src/spell-convert/lexer.lpp" -{ abort(); } - YY_BREAK -case 86: -YY_RULE_SETUP -#line 116 "../src/spell-convert/lexer.lpp" -ECHO; - YY_BREAK -#line 1367 "src/spell-convert/lexer.cpp" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed spell_converterin at a new source and called - * spell_converterlex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = spell_converterin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = (yy_c_buf_p); - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; - - if ( spell_converterwrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * spell_convertertext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of spell_converterlex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (void) -{ - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = (yytext_ptr); - register int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - spell_converterrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - spell_converterrestart(spell_converterin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) spell_converterrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (void) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = (yy_start); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 240 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -{ - register int yy_is_jam; - register char *yy_cp = (yy_c_buf_p); - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 240 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 239); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (void) -#else - static int input (void) -#endif - -{ - int c; - - *(yy_c_buf_p) = (yy_hold_char); - - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ - int offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - spell_converterrestart(spell_converterin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( spell_converterwrap( ) ) - return EOF; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve spell_convertertext */ - (yy_hold_char) = *++(yy_c_buf_p); - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ - void spell_converterrestart (FILE * input_file ) -{ - - if ( ! YY_CURRENT_BUFFER ){ - spell_converterensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - spell_converter_create_buffer(spell_converterin,YY_BUF_SIZE ); - } - - spell_converter_init_buffer(YY_CURRENT_BUFFER,input_file ); - spell_converter_load_buffer_state( ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * - */ - void spell_converter_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -{ - - /* TODO. We should be able to replace this entire function body - * with - * spell_converterpop_buffer_state(); - * spell_converterpush_buffer_state(new_buffer); - */ - spell_converterensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - spell_converter_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (spell_converterwrap()) processing, but the only time this flag - * is looked at is after spell_converterwrap() is called, so it's safe - * to go ahead and always set it. - */ - (yy_did_buffer_switch_on_eof) = 1; -} - -static void spell_converter_load_buffer_state (void) -{ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - spell_converterin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - (yy_hold_char) = *(yy_c_buf_p); -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE spell_converter_create_buffer (FILE * file, int size ) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) spell_converteralloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in spell_converter_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) spell_converteralloc(b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in spell_converter_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - spell_converter_init_buffer(b,file ); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with spell_converter_create_buffer() - * - */ - void spell_converter_delete_buffer (YY_BUFFER_STATE b ) -{ - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - spell_converterfree((void *) b->yy_ch_buf ); - - spell_converterfree((void *) b ); -} - -#ifndef __cplusplus -extern int isatty (int ); -#endif /* __cplusplus */ - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a spell_converterrestart() or at EOF. - */ - static void spell_converter_init_buffer (YY_BUFFER_STATE b, FILE * file ) - -{ - int oerrno = errno; - - spell_converter_flush_buffer(b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then spell_converter_init_buffer was _probably_ - * called from spell_converterrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * - */ - void spell_converter_flush_buffer (YY_BUFFER_STATE b ) -{ - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - spell_converter_load_buffer_state( ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * - */ -void spell_converterpush_buffer_state (YY_BUFFER_STATE new_buffer ) -{ - if (new_buffer == NULL) - return; - - spell_converterensure_buffer_stack(); - - /* This block is copied from spell_converter_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from spell_converter_switch_to_buffer. */ - spell_converter_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * - */ -void spell_converterpop_buffer_state (void) -{ - if (!YY_CURRENT_BUFFER) - return; - - spell_converter_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { - spell_converter_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void spell_converterensure_buffer_stack (void) -{ - int num_to_alloc; - - if (!(yy_buffer_stack)) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - (yy_buffer_stack) = (struct yy_buffer_state**)spell_converteralloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in spell_converterensure_buffer_stack()" ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } - - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)spell_converterrealloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in spell_converterensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE spell_converter_scan_buffer (char * base, yy_size_t size ) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) spell_converteralloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in spell_converter_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - spell_converter_switch_to_buffer(b ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to spell_converterlex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * spell_converter_scan_bytes() instead. - */ -YY_BUFFER_STATE spell_converter_scan_string (yyconst char * yystr ) -{ - - return spell_converter_scan_bytes(yystr,strlen(yystr) ); -} - -/** Setup the input buffer state to scan the given bytes. The next call to spell_converterlex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE spell_converter_scan_bytes (yyconst char * yybytes, int _yybytes_len ) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) spell_converteralloc(n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in spell_converter_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = spell_converter_scan_buffer(buf,n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in spell_converter_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg ) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up spell_convertertext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - spell_convertertext[spell_converterleng] = (yy_hold_char); \ - (yy_c_buf_p) = spell_convertertext + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - spell_converterleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the current line number. - * - */ -int spell_converterget_lineno (void) -{ - - return spell_converterlineno; -} - -/** Get the input stream. - * - */ -FILE *spell_converterget_in (void) -{ - return spell_converterin; -} - -/** Get the output stream. - * - */ -FILE *spell_converterget_out (void) -{ - return spell_converterout; -} - -/** Get the length of the current token. - * - */ -int spell_converterget_leng (void) -{ - return spell_converterleng; -} - -/** Get the current token. - * - */ - -char *spell_converterget_text (void) -{ - return spell_convertertext; -} - -/** Set the current line number. - * @param line_number - * - */ -void spell_converterset_lineno (int line_number ) -{ - - spell_converterlineno = line_number; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * - * @see spell_converter_switch_to_buffer - */ -void spell_converterset_in (FILE * in_str ) -{ - spell_converterin = in_str ; -} - -void spell_converterset_out (FILE * out_str ) -{ - spell_converterout = out_str ; -} - -int spell_converterget_debug (void) -{ - return spell_converter_flex_debug; -} - -void spell_converterset_debug (int bdebug ) -{ - spell_converter_flex_debug = bdebug ; -} - -static int yy_init_globals (void) -{ - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from spell_converterlex_destroy(), so don't allocate here. - */ - - (yy_buffer_stack) = 0; - (yy_buffer_stack_top) = 0; - (yy_buffer_stack_max) = 0; - (yy_c_buf_p) = (char *) 0; - (yy_init) = 0; - (yy_start) = 0; - -/* Defined in main.c */ -#ifdef YY_STDINIT - spell_converterin = stdin; - spell_converterout = stdout; -#else - spell_converterin = (FILE *) 0; - spell_converterout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * spell_converterlex_init() - */ - return 0; -} - -/* spell_converterlex_destroy is for both reentrant and non-reentrant scanners. */ -int spell_converterlex_destroy (void) -{ - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - spell_converter_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - spell_converterpop_buffer_state(); - } - - /* Destroy the stack itself. */ - spell_converterfree((yy_buffer_stack) ); - (yy_buffer_stack) = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * spell_converterlex() is called, initialization will occur. */ - yy_init_globals( ); - - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s ) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *spell_converteralloc (yy_size_t size ) -{ - return (void *) malloc( size ); -} - -void *spell_converterrealloc (void * ptr, yy_size_t size ) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void spell_converterfree (void * ptr ) -{ - free( (char *) ptr ); /* see spell_converterrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 116 "../src/spell-convert/lexer.lpp" - - -// nothing to see here, move along - diff --git a/src/spell-convert/lexer.hpp b/src/spell-convert/lexer.hpp deleted file mode 100644 index 82c6ba2..0000000 --- a/src/spell-convert/lexer.hpp +++ /dev/null @@ -1,335 +0,0 @@ -#ifndef spell_converterHEADER_H -#define spell_converterHEADER_H 1 -#define spell_converterIN_HEADER 1 - -#line 6 "src/spell-convert/lexer.hpp" - -#line 8 "src/spell-convert/lexer.hpp" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include <inttypes.h> -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -extern int spell_converterleng; - -extern FILE *spell_converterin, *spell_converterout; - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -void spell_converterrestart (FILE *input_file ); -void spell_converter_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE spell_converter_create_buffer (FILE *file,int size ); -void spell_converter_delete_buffer (YY_BUFFER_STATE b ); -void spell_converter_flush_buffer (YY_BUFFER_STATE b ); -void spell_converterpush_buffer_state (YY_BUFFER_STATE new_buffer ); -void spell_converterpop_buffer_state (void ); - -YY_BUFFER_STATE spell_converter_scan_buffer (char *base,yy_size_t size ); -YY_BUFFER_STATE spell_converter_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE spell_converter_scan_bytes (yyconst char *bytes,int len ); - -void *spell_converteralloc (yy_size_t ); -void *spell_converterrealloc (void *,yy_size_t ); -void spell_converterfree (void * ); - -/* Begin user sect3 */ - -#define spell_converterwrap(n) 1 -#define YY_SKIP_YYWRAP - -extern int spell_converterlineno; - -extern char *spell_convertertext; -#define yytext_ptr spell_convertertext - -#ifdef YY_HEADER_EXPORT_START_CONDITIONS -#define INITIAL 0 - -#endif - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include <unistd.h> -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int spell_converterlex_destroy (void ); - -int spell_converterget_debug (void ); - -void spell_converterset_debug (int debug_flag ); - -YY_EXTRA_TYPE spell_converterget_extra (void ); - -void spell_converterset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *spell_converterget_in (void ); - -void spell_converterset_in (FILE * in_str ); - -FILE *spell_converterget_out (void ); - -void spell_converterset_out (FILE * out_str ); - -int spell_converterget_leng (void ); - -char *spell_converterget_text (void ); - -int spell_converterget_lineno (void ); - -void spell_converterset_lineno (int line_number ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int spell_converterwrap (void ); -#else -extern int spell_converterwrap (void ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ); -#endif - -#ifndef YY_NO_INPUT - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int spell_converterlex (void); - -#define YY_DECL int spell_converterlex (void) -#endif /* !YY_DECL */ - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -#undef YY_NEW_FILE -#undef YY_FLUSH_BUFFER -#undef yy_set_bol -#undef yy_new_buffer -#undef yy_set_interactive -#undef YY_DO_BEFORE_ACTION - -#ifdef YY_DECL_IS_OURS -#undef YY_DECL_IS_OURS -#undef YY_DECL -#endif - -#line 116 "../src/spell-convert/lexer.lpp" - - -#line 334 "src/spell-convert/lexer.hpp" -#undef spell_converterIN_HEADER -#endif /* spell_converterHEADER_H */ diff --git a/src/spell-convert/lexer.lpp b/src/spell-convert/lexer.lpp deleted file mode 100644 index b6c6d76..0000000 --- a/src/spell-convert/lexer.lpp +++ /dev/null @@ -1,136 +0,0 @@ -%{ -/* vim: set ft=lex: */ -//#include "lexer.hpp" -// magic-interpreter-lexer.lpp - Old magic tokenizer -// -// Copyright © 2004-2011 The Mana World Development Team -// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include "../strings/rstring.hpp" -#include "../strings/zstring.hpp" - -#include "../io/cxxstdio.hpp" - -#include "../sexpr/lexer.hpp" - -#include "parser.hpp" - -#define yylval spell_converterlval - -RString *str(const char *s) -{ - return new RString(ZString(strings::really_construct_from_a_pointer, s, nullptr)); -} -%} - -%option noyywrap -%option prefix="spell_converter" -%option nounput -%option noinput - -%% - -"S" { yylval.s = str(yytext); return DIR; } -"SW" { yylval.s = str(yytext); return DIR; } -"W" { yylval.s = str(yytext); return DIR; } -"NW" { yylval.s = str(yytext); return DIR; } -"N" { yylval.s = str(yytext); return DIR; } -"NE" { yylval.s = str(yytext); return DIR; } -"E" { yylval.s = str(yytext); return DIR; } -"SE" { yylval.s = str(yytext); return DIR; } -"=" { return '='; } -"==" { return EQ; } -"<>" { return NEQ; } -"!=" { return NEQ; } -">" { return '>'; } -"<" { return '<'; } -">=" { return GTE; } -"<=" { return LTE; } -"(" { return '('; } -")" { return ')'; } -"+" { return '+'; } -"-" { return '-'; } -"*" { return '*'; } -"/" { return '/'; } -"%" { return '%'; } -"&&" { return ANDAND; } -"||" { return OROR; } -";" { return ';'; } -":" { return ':'; } -"," { return ','; } -"@" { return '@'; } -"|" { return '|'; } -"[" { return '['; } -"]" { return ']'; } -"&" { return '&'; } -"^" { return '^'; } -"." { return '.'; } -"<<" { return SHL; } -">>" { return SHR; } -"PROCEDURE" { return PROCEDURE; } -"CALL" { return CALL; } -"OR" { return OR; } -"TO" { return TO; } -"TOWARDS" { return TOWARDS; } -"TELEPORT-ANCHOR" { return TELEPORT_ANCHOR; } -"SILENT" { return SILENT; } -"LOCAL" { return LOCAL; } -"NONMAGIC" { return NONMAGIC; } -"SPELL" { return SPELL; } -"LET" { return LET; } -"IN" { return IN; } -"END" { return END; } -"=>" { return DARROW; } -"STRING" { return STRING_TY; } -"REQUIRE" { return REQUIRE; } -"CATALYSTS" { return CATALYSTS; } -"COMPONENTS" { return COMPONENTS; } -"MANA" { return MANA; } -"CASTTIME" { return CASTTIME; } -"SKIP" { return SKIP; } -"ABORT" { return ABORT; } -"BREAK" { return BREAK; } -"EFFECT" { return EFFECT_; } -"ATEND" { return ATEND; } -"ATTRIGGER" { return ATTRIGGER; } -"CONST" { return CONST; } -"PC" { return PC_F; } -"NPC" { return NPC_F; } -"MOB" { return MOB_F; } -"ENTITY" { return ENTITY_F; } -"TARGET" { return TARGET_F; } -"IF" { return IF; } -"THEN" { return THEN; } -"ELSE" { return ELSE; } -"FOREACH" { return FOREACH; } -"FOR" { return FOR; } -"DO" { return DO; } -"WAIT" { return SLEEP; } - -\{([^\}]|\\.)*\} { yylval.s = str(yytext); return SCRIPT_DATA; } -\"([^\"]|\\.)*\" { yylval.s = str(yytext); return STRING; } -"-"?[0-9]+ { yylval.s = str(yytext); return INT; } -"0x"[0-9a-fA-F]+ { yylval.s = str(yytext); return INT; } -[a-zA-Z][-_a-zA-Z0-9]* { yylval.s = str(yytext); return ID; } -"#".*$ { PRINTF("%s\n", sexpr::escape(*str(yytext + 1))); } -"//".*$ { PRINTF("%s\n", sexpr::escape(*str(yytext + 2))); } -[ \n\t\r] /* ignore whitespace */ -. { abort(); } - -%% -// nothing to see here, move along diff --git a/src/spell-convert/parser.cpp b/src/spell-convert/parser.cpp deleted file mode 100644 index 0744630..0000000 --- a/src/spell-convert/parser.cpp +++ /dev/null @@ -1,2732 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.0.2. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "3.0.2" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - -/* Substitute the variable and function names. */ -#define yyparse spell_converterparse -#define yylex spell_converterlex -#define yyerror spell_convertererror -#define yydebug spell_converterdebug -#define yynerrs spell_converternerrs - -#define yylval spell_converterlval -#define yychar spell_converterchar - -/* Copy the first part of user declarations. */ - -#line 75 "src/spell-convert/parser.cpp" /* yacc.c:339 */ - -# ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* In a future release of Bison, this section will be replaced - by #include "parser.hpp". */ -#ifndef YY_SPELL_CONVERTER_SRC_SPELL_CONVERT_PARSER_HPP_INCLUDED -# define YY_SPELL_CONVERTER_SRC_SPELL_CONVERT_PARSER_HPP_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int spell_converterdebug; -#endif -/* "%code requires" blocks. */ -#line 2 "../src/spell-convert/parser.ypp" /* yacc.c:355 */ - -/* vim: set ft=yacc: */ -#include "../strings/rstring.hpp" - -#include "ast.hpp" - -#undef YYERROR_VERBOSE -#define YYERROR_VERBOSE 1 - -#line 115 "src/spell-convert/parser.cpp" /* yacc.c:355 */ - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - INT = 258, - STRING = 259, - ID = 260, - DIR = 261, - CONST = 262, - PROCEDURE = 263, - CALL = 264, - SILENT = 265, - LOCAL = 266, - NONMAGIC = 267, - SHL = 268, - SHR = 269, - EQ = 270, - NEQ = 271, - GTE = 272, - LTE = 273, - ANDAND = 274, - OROR = 275, - SCRIPT_DATA = 276, - TO = 277, - TOWARDS = 278, - TELEPORT_ANCHOR = 279, - SPELL = 280, - LET = 281, - IN = 282, - END = 283, - DARROW = 284, - STRING_TY = 285, - REQUIRE = 286, - CATALYSTS = 287, - COMPONENTS = 288, - MANA = 289, - CASTTIME = 290, - SKIP = 291, - ABORT = 292, - BREAK = 293, - EFFECT_ = 294, - ATEND = 295, - ATTRIGGER = 296, - PC_F = 297, - NPC_F = 298, - MOB_F = 299, - ENTITY_F = 300, - TARGET_F = 301, - IF = 302, - THEN = 303, - ELSE = 304, - FOREACH = 305, - FOR = 306, - DO = 307, - SLEEP = 308, - OR = 309 - }; -#endif - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE YYSTYPE; -union YYSTYPE -{ -#line 27 "../src/spell-convert/parser.ypp" /* yacc.c:355 */ - - RString *s; - std::vector<RString> *vs; - Effect *e; - std::deque<Effect *> *ve; - SpellDef *spelldef; - SpellArg *spellarg; - TopLevel *top; - Expression *expr; - std::vector<Expression *> *vx; - Location *loc; - Item *it; - std::vector<Item *> *vit; - Assignment *a; - std::vector<Assignment *> *va; - SpellBod *b; - std::vector<SpellBod *> *vb; - SpellGuard *g; - std::vector<SpellGuard *> *vg; - -#line 203 "src/spell-convert/parser.cpp" /* yacc.c:355 */ -}; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - -extern YYSTYPE spell_converterlval; - -int spell_converterparse (void); - -#endif /* !YY_SPELL_CONVERTER_SRC_SPELL_CONVERT_PARSER_HPP_INCLUDED */ - -/* Copy the second part of user declarations. */ - -#line 218 "src/spell-convert/parser.cpp" /* yacc.c:358 */ -/* Unqualified %code blocks. */ -#line 13 "../src/spell-convert/parser.ypp" /* yacc.c:359 */ - -//#include "parser.hpp" -#include "lexer.hpp" - -#include "../io/cxxstdio.hpp" - -#include "../sexpr/lexer.hpp" - -void yyerror(const char *msg) { FPRINTF(stderr, "Fatal: %s\n", msg); abort(); } - -#line 231 "src/spell-convert/parser.cpp" /* yacc.c:359 */ - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -# else -# define YY_ATTRIBUTE(Spec) /* empty */ -# endif -#endif - -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -#endif - -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) -#else -# define YYUSE(E) /* empty */ -#endif - -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 2 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 990 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 75 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 32 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 111 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 248 - -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 309 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 14, 23, 2, - 73, 74, 12, 10, 16, 11, 17, 13, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 18, 19, - 8, 7, 9, 2, 15, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 21, 2, 22, 24, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 20, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72 -}; - -#if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 167, 167, 171, 179, 183, 191, 195, 205, 211, - 222, 227, 232, 237, 242, 253, 257, 263, 269, 281, - 285, 295, 300, 310, 315, 320, 330, 335, 340, 345, - 350, 355, 360, 365, 370, 375, 380, 385, 390, 395, - 400, 405, 410, 415, 420, 425, 430, 436, 441, 446, - 451, 462, 466, 476, 482, 493, 503, 508, 513, 523, - 528, 538, 543, 554, 564, 570, 581, 586, 591, 602, - 606, 617, 621, 631, 636, 641, 651, 657, 668, 673, - 678, 683, 688, 698, 708, 714, 725, 730, 740, 745, - 755, 760, 765, 770, 775, 780, 790, 795, 800, 805, - 810, 815, 820, 825, 830, 835, 840, 845, 850, 856, - 867, 871 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || 0 -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "INT", "STRING", "ID", "DIR", "'='", - "'<'", "'>'", "'+'", "'-'", "'*'", "'/'", "'%'", "'@'", "','", "'.'", - "':'", "';'", "'|'", "'['", "']'", "'&'", "'^'", "CONST", "PROCEDURE", - "CALL", "SILENT", "LOCAL", "NONMAGIC", "SHL", "SHR", "EQ", "NEQ", "GTE", - "LTE", "ANDAND", "OROR", "SCRIPT_DATA", "TO", "TOWARDS", - "TELEPORT_ANCHOR", "SPELL", "LET", "IN", "END", "DARROW", "STRING_TY", - "REQUIRE", "CATALYSTS", "COMPONENTS", "MANA", "CASTTIME", "SKIP", - "ABORT", "BREAK", "EFFECT_", "ATEND", "ATTRIGGER", "PC_F", "NPC_F", - "MOB_F", "ENTITY_F", "TARGET_F", "IF", "THEN", "ELSE", "FOREACH", "FOR", - "DO", "SLEEP", "OR", "'('", "')'", "$accept", "spellconf", "semicolons", - "proc_formals_list", "proc_formals_list_ne", "spellconf_option", - "spell_flags", "argopt", "arg_ty", "value", "expr", "arg_list", - "arg_list_ne", "location", "area", "spelldef", "defs", "def", - "spellbody_list", "spellbody", "maybe_trigger", "maybe_end", - "spellguard", "spellguard_list", "prereq", "items", "item_list", "item", - "item_name", "selection", "effect", "effect_list", YY_NULLPTR -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 61, 60, 62, - 43, 45, 42, 47, 37, 64, 44, 46, 58, 59, - 124, 91, 93, 38, 94, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 40, 41 -}; -# endif - -#define YYPACT_NINF -171 - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-171))) - -#define YYTABLE_NINF -13 - -#define yytable_value_is_error(Yytable_value) \ - 0 - - /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int16 yypact[] = -{ - -171, 19, -171, 156, 17, -171, 46, 60, 64, -171, - 104, 91, 65, 2, 80, -171, -171, -171, 73, -171, - -171, 27, -171, 28, 91, -171, 780, 39, -171, 91, - 98, 91, 35, 91, 91, 230, 91, 91, 91, 91, - 91, 91, 91, 91, 111, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 99, 91, 780, -171, - 49, 106, 812, 115, 107, 780, 50, 114, 556, -171, - -1, 937, 937, 958, 958, 184, 184, 184, -171, -1, - -1, -1, -1, -1, 937, 937, 937, 937, 907, 876, - 68, 588, 142, 145, 91, 134, 91, -171, 91, 91, - 91, 81, 163, -171, 484, 14, 844, 780, 620, 652, - 91, -2, 148, -171, 136, 138, 139, 140, 91, 123, - 160, 91, 163, -171, -171, -171, -171, 93, 6, 91, - 91, 684, 91, 91, 96, -171, -171, -171, -171, 462, - -171, -171, -171, -171, -171, -171, 166, 165, 716, 100, - 124, -171, -171, 91, 152, 152, 91, 91, 163, 87, - -171, 157, -171, -25, -171, 262, 306, 91, 748, 102, - 91, 163, 149, 91, -171, -171, -171, 177, 3, 780, - 11, -171, -171, 780, 780, 141, -13, -25, -14, 172, - 172, 62, -171, -171, 338, -171, 180, 129, 143, 91, - 522, 198, 172, -171, 194, -171, 48, -171, -171, 163, - 153, -171, 62, -171, 172, -171, -171, 62, -171, -171, - -171, 193, 163, 382, 91, 91, 157, 177, 63, 11, - -171, -171, 163, -171, 154, 154, -171, -171, 163, 422, - 780, -171, -171, -171, -171, -171, 163, -171 -}; - - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 2, 4, 1, 15, 0, 5, 0, 0, 0, 3, - 0, 0, 0, 0, 0, 18, 16, 17, 0, 24, - 25, 27, 23, 0, 0, 26, 10, 56, 28, 0, - 6, 0, 19, 51, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 11, 8, - 0, 7, 0, 0, 0, 53, 0, 52, 0, 49, - 46, 34, 35, 29, 30, 31, 33, 32, 50, 38, - 36, 37, 39, 40, 45, 47, 42, 41, 43, 44, - 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, - 0, 0, 110, 9, 46, 0, 0, 54, 0, 0, - 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, - 0, 0, 110, 4, 13, 22, 21, 0, 0, 0, - 0, 0, 0, 51, 0, 99, 97, 98, 100, 0, - 93, 90, 95, 91, 92, 94, 0, 0, 0, 0, - 110, 20, 4, 0, 0, 0, 0, 0, 110, 0, - 14, 59, 64, 0, 73, 0, 0, 0, 0, 0, - 51, 0, 0, 0, 106, 96, 111, 61, 0, 78, - 0, 79, 80, 81, 82, 69, 0, 76, 0, 0, - 0, 0, 55, 57, 0, 101, 0, 0, 105, 0, - 0, 0, 0, 4, 89, 88, 0, 84, 87, 110, - 71, 67, 0, 75, 0, 65, 66, 0, 74, 58, - 107, 0, 0, 0, 0, 0, 60, 62, 0, 0, - 83, 70, 110, 68, 77, 76, 109, 104, 0, 0, - 63, 89, 86, 85, 72, 102, 0, 103 -}; - - /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -171, -171, -119, -171, -171, -171, -171, -171, -171, -171, - -11, -84, -171, -171, -171, -171, -171, -171, -125, -108, - -171, -171, -86, -171, -171, 72, -171, -9, 5, -171, - -170, -105 -}; - - /* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 1, 3, 60, 61, 9, 10, 64, 127, 25, - 65, 66, 67, 27, 28, 160, 178, 203, 186, 162, - 210, 233, 163, 188, 164, 181, 206, 207, 208, 146, - 123, 124 -}; - - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int16 yytable[] = -{ - 26, 198, 212, 161, 150, 132, 36, 189, 201, 19, - 20, 21, 22, 35, 204, 205, 44, 149, 58, 2, - 62, 23, 190, 68, 11, 70, 71, 72, 73, 74, - 75, 76, 77, 177, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 176, 91, 191, 202, 169, - 152, 12, 237, 185, 56, 153, 154, 155, 156, 157, - 213, 211, 125, 158, 229, 13, 241, 205, 245, 14, - 230, 133, 29, 187, 126, 30, 247, 226, 32, 159, - 57, 215, 216, 104, 227, 106, 197, 107, 108, 109, - 19, 20, 21, 22, 19, 20, 21, 22, 31, 131, - 33, 34, 23, 59, 231, 218, 23, 139, 63, 90, - 148, 153, 154, 155, 156, 157, 78, 70, 165, 166, - 95, 168, 93, 92, 97, 96, 234, 244, 187, 111, - 98, 235, 15, 16, 17, 217, 153, 154, 155, 156, - 157, 100, 179, 5, 158, 183, 184, 18, 35, 102, - 103, 112, 105, 134, 110, 135, 194, 136, 137, 138, - 159, 4, 200, 113, 24, 147, 140, 151, 111, 170, - 114, 172, 173, 180, 175, 5, 196, 189, 115, 116, - 117, 6, 7, 141, 142, 143, 144, 145, 223, 118, - 112, 36, 119, 120, 199, 121, 5, 122, 8, 220, - 209, 44, 113, 221, 45, 225, 228, 46, 47, 114, - 222, 232, 236, 239, 240, 48, 49, 115, 116, 117, - 243, 153, 154, 155, 156, 157, 191, 182, 118, 158, - 0, 119, 120, 242, 121, 0, 122, 36, 37, 38, - 39, 40, 41, 42, 43, 214, 0, 44, 0, 0, - 45, 0, 0, 46, 47, 0, 0, 0, 0, 0, - 0, 48, 49, 50, 51, 52, 53, 54, 55, 36, - 37, 38, 39, 40, 41, 42, 43, 0, 0, 44, - 0, 0, 45, 0, 0, 46, 47, 0, 0, 0, - 0, 0, 0, 48, 49, 50, 51, 52, 53, 54, - 55, 0, 0, 0, 69, 0, 0, 0, 0, 0, - 0, 0, 0, 36, 37, 38, 39, 40, 41, 42, - 43, 0, 0, 44, 0, 0, 45, 0, 0, 46, - 47, 0, 0, 0, 0, 0, 192, 48, 49, 50, - 51, 52, 53, 54, 55, 36, 37, 38, 39, 40, - 41, 42, 43, 0, 0, 44, 0, 0, 45, 0, - 0, 46, 47, 0, 0, 0, 0, 0, 0, 48, - 49, 50, 51, 52, 53, 54, 55, 0, 0, 0, - 193, 0, 0, 0, 0, 0, 0, 0, 0, 36, - 37, 38, 39, 40, 41, 42, 43, 0, 0, 44, - 0, 0, 45, 0, 0, 46, 47, 0, 0, 0, - 0, 0, 219, 48, 49, 50, 51, 52, 53, 54, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 36, - 37, 38, 39, 40, 41, 42, 43, 0, 0, 44, - 0, 0, 45, 0, 0, 46, 47, 0, 0, 0, - 0, 0, 238, 48, 49, 50, 51, 52, 53, 54, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 36, - 37, 38, 39, 40, 41, 42, 43, 0, 0, 44, - 0, 0, 45, 0, -12, 46, 47, 0, 0, -12, - 0, 36, 246, 48, 49, 50, 51, 52, 53, 54, - 55, 44, 0, -12, 0, 0, 0, 0, 0, -12, - -12, 0, -12, -12, -12, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -12, -12, 171, 36, - 37, 38, 39, 40, 41, 42, 43, 0, 0, 44, - 0, 0, 45, 0, 0, 46, 47, 0, 0, 0, - 0, 0, 0, 48, 49, 50, 51, 52, 53, 54, - 55, 0, 224, 36, 37, 38, 39, 40, 41, 42, - 43, 0, 99, 44, 0, 0, 45, 0, 0, 46, - 47, 0, 0, 0, 0, 0, 0, 48, 49, 50, - 51, 52, 53, 54, 55, 36, 37, 38, 39, 40, - 41, 42, 43, 0, 0, 44, 101, 0, 45, 0, - 0, 46, 47, 0, 0, 0, 0, 0, 0, 48, - 49, 50, 51, 52, 53, 54, 55, 36, 37, 38, - 39, 40, 41, 42, 43, 0, 129, 44, 0, 0, - 45, 0, 0, 46, 47, 0, 0, 0, 0, 0, - 0, 48, 49, 50, 51, 52, 53, 54, 55, 36, - 37, 38, 39, 40, 41, 42, 43, 0, 130, 44, - 0, 0, 45, 0, 0, 46, 47, 0, 0, 0, - 0, 0, 0, 48, 49, 50, 51, 52, 53, 54, - 55, 36, 37, 38, 39, 40, 41, 42, 43, 0, - 167, 44, 0, 0, 45, 0, 0, 46, 47, 0, - 0, 0, 0, 0, 0, 48, 49, 50, 51, 52, - 53, 54, 55, 36, 37, 38, 39, 40, 41, 42, - 43, 0, 0, 44, 0, 174, 45, 0, 0, 46, - 47, 0, 0, 0, 0, 0, 0, 48, 49, 50, - 51, 52, 53, 54, 55, 36, 37, 38, 39, 40, - 41, 42, 43, 0, 0, 44, 0, 195, 45, 0, - 0, 46, 47, 0, 0, 0, 0, 0, 0, 48, - 49, 50, 51, 52, 53, 54, 55, 36, 37, 38, - 39, 40, 41, 42, 43, 0, 0, 44, 0, 0, - 45, 0, 0, 46, 47, 0, 0, 0, 0, 0, - 0, 48, 49, 50, 51, 52, 53, 54, 55, 94, - 37, 38, 39, 40, 41, 42, 43, 0, 0, 44, - 0, 0, 45, 0, 0, 46, 47, 0, 0, 0, - 0, 0, 0, 48, 49, 50, 51, 52, 53, 54, - 55, 128, 37, 38, 39, 40, 41, 42, 43, 0, - 0, 44, 0, 0, 45, 0, 0, 46, 47, 0, - 0, 0, 0, 0, 0, 48, 49, 50, 51, 52, - 53, 54, 55, 36, 37, 38, 39, 40, 41, 42, - 43, 0, 0, 44, 0, 0, 45, 0, 0, 46, - 47, 0, 0, 0, 0, 0, 0, 48, 49, 50, - 51, 52, 53, 54, 36, 37, 38, 39, 40, 41, - 42, 43, 0, 0, 44, 0, 0, 45, 0, 0, - 46, 47, 0, 0, 0, 0, 0, 0, 48, 49, - 50, 51, 52, 53, 36, 0, 0, 39, 40, 41, - 42, 43, 0, 0, 44, 0, 0, 45, 0, 0, - 46, 47, 0, 0, 0, 36, 0, 0, 48, 49, - 41, 42, 43, 0, 0, 44, 0, 0, 45, 0, - 0, 46, 47, 0, 0, 0, 0, 0, 0, 48, - 49 -}; - -static const yytype_int16 yycheck[] = -{ - 11, 171, 16, 128, 123, 7, 7, 20, 5, 3, - 4, 5, 6, 24, 3, 4, 17, 122, 29, 0, - 31, 15, 47, 34, 7, 36, 37, 38, 39, 40, - 41, 42, 43, 152, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 150, 57, 72, 45, 133, - 44, 5, 222, 158, 15, 49, 50, 51, 52, 53, - 74, 74, 48, 57, 16, 5, 3, 4, 238, 5, - 22, 73, 7, 159, 60, 73, 246, 202, 5, 73, - 41, 189, 190, 94, 203, 96, 170, 98, 99, 100, - 3, 4, 5, 6, 3, 4, 5, 6, 18, 110, - 73, 73, 15, 5, 209, 191, 15, 118, 73, 10, - 121, 49, 50, 51, 52, 53, 5, 128, 129, 130, - 5, 132, 16, 74, 74, 18, 212, 232, 214, 5, - 16, 217, 28, 29, 30, 73, 49, 50, 51, 52, - 53, 73, 153, 19, 57, 156, 157, 43, 159, 7, - 5, 27, 18, 5, 73, 19, 167, 19, 19, 19, - 73, 5, 173, 39, 73, 5, 43, 74, 5, 73, - 46, 5, 7, 21, 74, 19, 74, 20, 54, 55, - 56, 25, 26, 60, 61, 62, 63, 64, 199, 65, - 27, 7, 68, 69, 45, 71, 19, 73, 42, 19, - 59, 17, 39, 74, 20, 7, 12, 23, 24, 46, - 67, 58, 19, 224, 225, 31, 32, 54, 55, 56, - 229, 49, 50, 51, 52, 53, 72, 155, 65, 57, - -1, 68, 69, 228, 71, -1, 73, 7, 8, 9, - 10, 11, 12, 13, 14, 73, -1, 17, -1, -1, - 20, -1, -1, 23, 24, -1, -1, -1, -1, -1, - -1, 31, 32, 33, 34, 35, 36, 37, 38, 7, - 8, 9, 10, 11, 12, 13, 14, -1, -1, 17, - -1, -1, 20, -1, -1, 23, 24, -1, -1, -1, - -1, -1, -1, 31, 32, 33, 34, 35, 36, 37, - 38, -1, -1, -1, 74, -1, -1, -1, -1, -1, - -1, -1, -1, 7, 8, 9, 10, 11, 12, 13, - 14, -1, -1, 17, -1, -1, 20, -1, -1, 23, - 24, -1, -1, -1, -1, -1, 74, 31, 32, 33, - 34, 35, 36, 37, 38, 7, 8, 9, 10, 11, - 12, 13, 14, -1, -1, 17, -1, -1, 20, -1, - -1, 23, 24, -1, -1, -1, -1, -1, -1, 31, - 32, 33, 34, 35, 36, 37, 38, -1, -1, -1, - 74, -1, -1, -1, -1, -1, -1, -1, -1, 7, - 8, 9, 10, 11, 12, 13, 14, -1, -1, 17, - -1, -1, 20, -1, -1, 23, 24, -1, -1, -1, - -1, -1, 74, 31, 32, 33, 34, 35, 36, 37, - 38, -1, -1, -1, -1, -1, -1, -1, -1, 7, - 8, 9, 10, 11, 12, 13, 14, -1, -1, 17, - -1, -1, 20, -1, -1, 23, 24, -1, -1, -1, - -1, -1, 70, 31, 32, 33, 34, 35, 36, 37, - 38, -1, -1, -1, -1, -1, -1, -1, -1, 7, - 8, 9, 10, 11, 12, 13, 14, -1, -1, 17, - -1, -1, 20, -1, 0, 23, 24, -1, -1, 5, - -1, 7, 70, 31, 32, 33, 34, 35, 36, 37, - 38, 17, -1, 19, -1, -1, -1, -1, -1, 25, - 26, -1, 28, 29, 30, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 42, 43, 66, 7, - 8, 9, 10, 11, 12, 13, 14, -1, -1, 17, - -1, -1, 20, -1, -1, 23, 24, -1, -1, -1, - -1, -1, -1, 31, 32, 33, 34, 35, 36, 37, - 38, -1, 40, 7, 8, 9, 10, 11, 12, 13, - 14, -1, 16, 17, -1, -1, 20, -1, -1, 23, - 24, -1, -1, -1, -1, -1, -1, 31, 32, 33, - 34, 35, 36, 37, 38, 7, 8, 9, 10, 11, - 12, 13, 14, -1, -1, 17, 18, -1, 20, -1, - -1, 23, 24, -1, -1, -1, -1, -1, -1, 31, - 32, 33, 34, 35, 36, 37, 38, 7, 8, 9, - 10, 11, 12, 13, 14, -1, 16, 17, -1, -1, - 20, -1, -1, 23, 24, -1, -1, -1, -1, -1, - -1, 31, 32, 33, 34, 35, 36, 37, 38, 7, - 8, 9, 10, 11, 12, 13, 14, -1, 16, 17, - -1, -1, 20, -1, -1, 23, 24, -1, -1, -1, - -1, -1, -1, 31, 32, 33, 34, 35, 36, 37, - 38, 7, 8, 9, 10, 11, 12, 13, 14, -1, - 16, 17, -1, -1, 20, -1, -1, 23, 24, -1, - -1, -1, -1, -1, -1, 31, 32, 33, 34, 35, - 36, 37, 38, 7, 8, 9, 10, 11, 12, 13, - 14, -1, -1, 17, -1, 19, 20, -1, -1, 23, - 24, -1, -1, -1, -1, -1, -1, 31, 32, 33, - 34, 35, 36, 37, 38, 7, 8, 9, 10, 11, - 12, 13, 14, -1, -1, 17, -1, 19, 20, -1, - -1, 23, 24, -1, -1, -1, -1, -1, -1, 31, - 32, 33, 34, 35, 36, 37, 38, 7, 8, 9, - 10, 11, 12, 13, 14, -1, -1, 17, -1, -1, - 20, -1, -1, 23, 24, -1, -1, -1, -1, -1, - -1, 31, 32, 33, 34, 35, 36, 37, 38, 7, - 8, 9, 10, 11, 12, 13, 14, -1, -1, 17, - -1, -1, 20, -1, -1, 23, 24, -1, -1, -1, - -1, -1, -1, 31, 32, 33, 34, 35, 36, 37, - 38, 7, 8, 9, 10, 11, 12, 13, 14, -1, - -1, 17, -1, -1, 20, -1, -1, 23, 24, -1, - -1, -1, -1, -1, -1, 31, 32, 33, 34, 35, - 36, 37, 38, 7, 8, 9, 10, 11, 12, 13, - 14, -1, -1, 17, -1, -1, 20, -1, -1, 23, - 24, -1, -1, -1, -1, -1, -1, 31, 32, 33, - 34, 35, 36, 37, 7, 8, 9, 10, 11, 12, - 13, 14, -1, -1, 17, -1, -1, 20, -1, -1, - 23, 24, -1, -1, -1, -1, -1, -1, 31, 32, - 33, 34, 35, 36, 7, -1, -1, 10, 11, 12, - 13, 14, -1, -1, 17, -1, -1, 20, -1, -1, - 23, 24, -1, -1, -1, 7, -1, -1, 31, 32, - 12, 13, 14, -1, -1, 17, -1, -1, 20, -1, - -1, 23, 24, -1, -1, -1, -1, -1, -1, 31, - 32 -}; - - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 76, 0, 77, 5, 19, 25, 26, 42, 80, - 81, 7, 5, 5, 5, 28, 29, 30, 43, 3, - 4, 5, 6, 15, 73, 84, 85, 88, 89, 7, - 73, 18, 5, 73, 73, 85, 7, 8, 9, 10, - 11, 12, 13, 14, 17, 20, 23, 24, 31, 32, - 33, 34, 35, 36, 37, 38, 15, 41, 85, 5, - 78, 79, 85, 73, 82, 85, 86, 87, 85, 74, - 85, 85, 85, 85, 85, 85, 85, 85, 5, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 10, 85, 74, 16, 7, 5, 18, 74, 16, 16, - 73, 18, 7, 5, 85, 18, 85, 85, 85, 85, - 73, 5, 27, 39, 46, 54, 55, 56, 65, 68, - 69, 71, 73, 105, 106, 48, 60, 83, 7, 16, - 16, 85, 7, 73, 5, 19, 19, 19, 19, 85, - 43, 60, 61, 62, 63, 64, 104, 5, 85, 106, - 77, 74, 44, 49, 50, 51, 52, 53, 57, 73, - 90, 93, 94, 97, 99, 85, 85, 16, 85, 86, - 73, 66, 5, 7, 19, 74, 106, 77, 91, 85, - 21, 100, 100, 85, 85, 106, 93, 97, 98, 20, - 47, 72, 74, 74, 85, 19, 74, 86, 105, 45, - 85, 5, 45, 92, 3, 4, 101, 102, 103, 59, - 95, 74, 16, 74, 73, 94, 94, 73, 97, 74, - 19, 74, 67, 85, 40, 7, 93, 77, 12, 16, - 22, 106, 58, 96, 97, 97, 19, 105, 70, 85, - 85, 3, 103, 102, 106, 105, 70, 105 -}; - - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 75, 76, 76, 77, 77, 78, 78, 79, 79, - 80, 80, 80, 80, 80, 81, 81, 81, 81, 82, - 82, 83, 83, 84, 84, 84, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 86, 86, 87, 87, 88, 89, 89, 89, 90, - 90, 91, 91, 92, 93, 93, 94, 94, 94, 95, - 95, 96, 96, 97, 97, 97, 98, 98, 99, 99, - 99, 99, 99, 100, 101, 101, 102, 102, 103, 103, - 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 106, 106 -}; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 0, 3, 0, 2, 0, 1, 1, 3, - 3, 4, 6, 7, 8, 0, 2, 2, 2, 0, - 5, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, - 3, 0, 1, 1, 3, 8, 1, 8, 9, 1, - 4, 1, 3, 3, 1, 3, 3, 3, 4, 0, - 2, 0, 2, 1, 3, 3, 1, 3, 2, 2, - 2, 2, 2, 3, 1, 3, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 2, 2, 2, - 2, 4, 7, 8, 6, 4, 3, 5, 1, 6, - 0, 3 -}; - - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -/* This macro is provided for backward compatibility. */ -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif - - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -{ - FILE *yyo = yyoutput; - YYUSE (yyo); - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - YYUSE (yytype); -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -{ - YYFPRINTF (yyoutput, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) -{ - unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -yystrlen (const char *yystr) -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -yystpcpy (char *yydest, const char *yysrc) -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -{ - YYUSE (yyvaluep); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - - - -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (void) -{ - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = yylex (); - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 3: -#line 172 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyvsp[0].top)->dump(); -} -#line 1633 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 6: -#line 191 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vs) = new std::vector<RString>(); -} -#line 1641 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 7: -#line 196 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vs) = (yyvsp[0].vs); -} -#line 1649 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 8: -#line 206 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vs) = new std::vector<RString>(); - (yyval.vs)->push_back(*(yyvsp[0].s)); -} -#line 1658 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 9: -#line 212 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vs) = (yyvsp[-2].vs); - (yyval.vs)->push_back(*(yyvsp[0].s)); -} -#line 1667 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 10: -#line 223 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.top) = new Assignment{*(yyvsp[-2].s), (yyvsp[0].expr)}; -} -#line 1675 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 11: -#line 228 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.top) = new Constant{*(yyvsp[-2].s), (yyvsp[0].expr)}; -} -#line 1683 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 12: -#line 233 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.top) = new Teleport{*(yyvsp[-4].s), (yyvsp[-2].expr), (yyvsp[0].expr)}; -} -#line 1691 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 13: -#line 238 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.top) = new Procedure{*(yyvsp[-5].s), (yyvsp[-3].vs), (yyvsp[0].ve)}; -} -#line 1699 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 14: -#line 243 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.top) = new Spell{(yyvsp[-7].vs), *(yyvsp[-5].s), (yyvsp[-4].spellarg), (yyvsp[-2].expr), (yyvsp[0].spelldef)}; -} -#line 1707 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 15: -#line 253 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vs) = new std::vector<RString>(); -} -#line 1715 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 16: -#line 258 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vs) = (yyvsp[-1].vs); - (yyval.vs)->push_back("LOCAL"); -} -#line 1724 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 17: -#line 264 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vs) = (yyvsp[-1].vs); - (yyval.vs)->push_back("NONMAGIC"); -} -#line 1733 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 18: -#line 270 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vs) = (yyvsp[-1].vs); - (yyval.vs)->push_back("SILENT"); -} -#line 1742 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 19: -#line 281 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.spellarg) = new SpellArg{}; -} -#line 1750 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 20: -#line 286 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.spellarg) = new SpellArg{*(yyvsp[-3].s), *(yyvsp[-1].s)}; -} -#line 1758 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 21: -#line 296 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = new RString("PC"); -} -#line 1766 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 22: -#line 301 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = new RString("STRING"); -} -#line 1774 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 23: -#line 311 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = (yyvsp[0].s); -} -#line 1782 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 24: -#line 316 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = (yyvsp[0].s); -} -#line 1790 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 25: -#line 321 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = (yyvsp[0].s); -} -#line 1798 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 26: -#line 331 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new SimpleExpr{*(yyvsp[0].s)}; -} -#line 1806 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 27: -#line 336 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new SimpleExpr{*(yyvsp[0].s)}; -} -#line 1814 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 28: -#line 341 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = (yyvsp[0].expr); -} -#line 1822 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 29: -#line 346 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "+", (yyvsp[0].expr)}; -} -#line 1830 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 30: -#line 351 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "-", (yyvsp[0].expr)}; -} -#line 1838 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 31: -#line 356 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "*", (yyvsp[0].expr)}; -} -#line 1846 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 32: -#line 361 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "%", (yyvsp[0].expr)}; -} -#line 1854 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 33: -#line 366 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "/", (yyvsp[0].expr)}; -} -#line 1862 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 34: -#line 371 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "<", (yyvsp[0].expr)}; -} -#line 1870 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 35: -#line 376 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), ">", (yyvsp[0].expr)}; -} -#line 1878 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 36: -#line 381 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "&", (yyvsp[0].expr)}; -} -#line 1886 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 37: -#line 386 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "^", (yyvsp[0].expr)}; -} -#line 1894 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 38: -#line 391 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "|", (yyvsp[0].expr)}; -} -#line 1902 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 39: -#line 396 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "<<", (yyvsp[0].expr)}; -} -#line 1910 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 40: -#line 401 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), ">>", (yyvsp[0].expr)}; -} -#line 1918 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 41: -#line 406 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "<=", (yyvsp[0].expr)}; -} -#line 1926 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 42: -#line 411 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), ">=", (yyvsp[0].expr)}; -} -#line 1934 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 43: -#line 416 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "&&", (yyvsp[0].expr)}; -} -#line 1942 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 44: -#line 421 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "||", (yyvsp[0].expr)}; -} -#line 1950 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 45: -#line 426 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "==", (yyvsp[0].expr)}; -} -#line 1958 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 46: -#line 431 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - // convert to == - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "==", (yyvsp[0].expr)}; -} -#line 1967 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 47: -#line 437 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), "!=", (yyvsp[0].expr)}; -} -#line 1975 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 48: -#line 442 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new CallExpr{*(yyvsp[-3].s), (yyvsp[-1].vx)}; -} -#line 1983 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 49: -#line 447 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = (yyvsp[-1].expr); -} -#line 1991 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 50: -#line 452 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new BinExpr{(yyvsp[-2].expr), ".", new SimpleExpr(*(yyvsp[0].s))}; -} -#line 1999 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 51: -#line 462 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vx) = new std::vector<Expression *>(); -} -#line 2007 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 52: -#line 467 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vx) = (yyvsp[0].vx); -} -#line 2015 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 53: -#line 477 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vx) = new std::vector<Expression *>(); - (yyval.vx)->push_back((yyvsp[0].expr)); -} -#line 2024 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 54: -#line 483 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vx) = (yyvsp[-2].vx); - (yyval.vx)->push_back((yyvsp[0].expr)); -} -#line 2033 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 55: -#line 494 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.loc) = new Location{(yyvsp[-5].expr), (yyvsp[-3].expr), (yyvsp[-1].expr)}; -} -#line 2041 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 56: -#line 504 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new AreaLoc{(yyvsp[0].loc)}; -} -#line 2049 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 57: -#line 509 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new AreaRect{(yyvsp[-7].loc), (yyvsp[-3].expr), (yyvsp[-1].expr)}; -} -#line 2057 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 58: -#line 514 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.expr) = new AreaBar{(yyvsp[-8].loc), (yyvsp[-6].expr), (yyvsp[-3].expr), (yyvsp[-1].expr)}; -} -#line 2065 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 59: -#line 524 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.spelldef) = new SpellDef{new std::vector<Assignment *>{}, (yyvsp[0].vb)}; -} -#line 2073 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 60: -#line 529 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.spelldef) = new SpellDef{(yyvsp[-2].va), (yyvsp[0].vb)}; -} -#line 2081 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 61: -#line 539 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.va) = new std::vector<Assignment *>(); -} -#line 2089 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 62: -#line 544 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.va) = (yyvsp[-2].va); - (yyval.va)->push_back((yyvsp[-1].a)); -} -#line 2098 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 63: -#line 555 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.a) = new Assignment{*(yyvsp[-2].s), (yyvsp[0].expr)}; -} -#line 2106 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 64: -#line 565 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vb) = new std::vector<SpellBod *>(); - (yyval.vb)->push_back((yyvsp[0].b)); -} -#line 2115 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 65: -#line 571 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vb) = (yyvsp[-2].vb); - (yyval.vb)->push_back((yyvsp[0].b)); -} -#line 2124 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 66: -#line 582 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.b) = new SpellBodGuarded{(yyvsp[-2].g), (yyvsp[0].b)}; -} -#line 2132 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 67: -#line 587 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.b) = new SpellBodList{(yyvsp[-1].vb)}; -} -#line 2140 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 68: -#line 592 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.b) = new SpellBodEffect{(yyvsp[-2].ve), (yyvsp[-1].ve), (yyvsp[0].ve)}; -} -#line 2148 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 69: -#line 602 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.ve) = nullptr; -} -#line 2156 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 70: -#line 607 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.ve) = (yyvsp[0].ve); -} -#line 2164 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 71: -#line 617 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.ve) = nullptr; -} -#line 2172 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 72: -#line 622 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.ve) = (yyvsp[0].ve); -} -#line 2180 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 73: -#line 632 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.g) = (yyvsp[0].g); -} -#line 2188 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 74: -#line 637 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.g) = new SpellGuardOr((yyvsp[-2].g), (yyvsp[0].g)); -} -#line 2196 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 75: -#line 642 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.g) = new SpellGuardList{(yyvsp[-1].vg)}; -} -#line 2204 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 76: -#line 652 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vg) = new std::vector<SpellGuard *>(); - (yyval.vg)->push_back((yyvsp[0].g)); -} -#line 2213 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 77: -#line 658 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vg) = (yyvsp[-2].vg); - (yyval.vg)->push_back((yyvsp[0].g)); -} -#line 2222 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 78: -#line 669 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.g) = new SpellGuardRequire{(yyvsp[0].expr)}; -} -#line 2230 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 79: -#line 674 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.g) = new SpellGuardCatalysts{(yyvsp[0].vit)}; -} -#line 2238 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 80: -#line 679 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.g) = new SpellGuardComponents{(yyvsp[0].vit)}; -} -#line 2246 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 81: -#line 684 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.g) = new SpellGuardMana{(yyvsp[0].expr)}; -} -#line 2254 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 82: -#line 689 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.g) = new SpellGuardCasttime{(yyvsp[0].expr)}; -} -#line 2262 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 83: -#line 699 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vit) = (yyvsp[-1].vit); -} -#line 2270 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 84: -#line 709 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vit) = new std::vector<Item *>(); - (yyval.vit)->push_back((yyvsp[0].it)); -} -#line 2279 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 85: -#line 715 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.vit) = (yyvsp[-2].vit); - (yyval.vit)->push_back((yyvsp[0].it)); -} -#line 2288 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 86: -#line 726 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.it) = new Item{*(yyvsp[-2].s), *(yyvsp[0].s)}; -} -#line 2296 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 87: -#line 731 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.it) = new Item{RString(), *(yyvsp[0].s)}; -} -#line 2304 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 88: -#line 741 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = (yyvsp[0].s); -} -#line 2312 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 89: -#line 746 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = (yyvsp[0].s); -} -#line 2320 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 90: -#line 756 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = new RString{"PC"}; -} -#line 2328 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 91: -#line 761 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = new RString{"MOB"}; -} -#line 2336 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 92: -#line 766 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = new RString{"ENTITY"}; -} -#line 2344 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 93: -#line 771 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = new RString{"SPELL"}; -} -#line 2352 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 94: -#line 776 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = new RString{"TARGET"}; -} -#line 2360 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 95: -#line 781 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.s) = new RString{"NPC"}; -} -#line 2368 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 96: -#line 791 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new EffectList{(yyvsp[-1].ve)}; -} -#line 2376 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 97: -#line 796 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new SimpleEffect{"SKIP"}; -} -#line 2384 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 98: -#line 801 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new SimpleEffect{"ABORT"}; -} -#line 2392 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 99: -#line 806 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new SimpleEffect{"END"}; -} -#line 2400 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 100: -#line 811 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new SimpleEffect{"BREAK"}; -} -#line 2408 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 101: -#line 816 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new Assignment(*(yyvsp[-3].s), (yyvsp[-1].expr)); -} -#line 2416 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 102: -#line 821 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new ForeachEffect{*(yyvsp[-5].s), *(yyvsp[-4].s), (yyvsp[-2].expr), (yyvsp[0].e)}; -} -#line 2424 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 103: -#line 826 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new ForEffect{*(yyvsp[-6].s), (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].e)}; -} -#line 2432 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 104: -#line 831 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new IfEffect{(yyvsp[-4].expr), (yyvsp[-2].e), (yyvsp[0].e)}; -} -#line 2440 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 105: -#line 836 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new IfEffect{(yyvsp[-2].expr), (yyvsp[0].e)}; -} -#line 2448 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 106: -#line 841 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new SleepEffect{(yyvsp[-1].expr)}; -} -#line 2456 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 107: -#line 846 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new CallExpr{*(yyvsp[-4].s), (yyvsp[-2].vx)}; -} -#line 2464 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 108: -#line 851 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - AString tmp = sexpr::escape(*(yyvsp[0].s)); - (yyval.e) = new ScriptEffect{RString(tmp)}; -} -#line 2473 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 109: -#line 857 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.e) = new ExplicitCallEffect{*(yyvsp[-4].s), (yyvsp[-2].vx)}; -} -#line 2481 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 110: -#line 867 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - (yyval.ve) = new std::deque<Effect *>(); -} -#line 2489 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - case 111: -#line 872 "../src/spell-convert/parser.ypp" /* yacc.c:1646 */ - { - // because of grammar problems, doing this right generates reduce/reduce conflicts - (yyval.ve) = (yyvsp[0].ve); - (yyval.ve)->push_front((yyvsp[-2].e)); -} -#line 2499 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - break; - - -#line 2503 "src/spell-convert/parser.cpp" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - return yyresult; -} -#line 881 "../src/spell-convert/parser.ypp" /* yacc.c:1906 */ - -// Nothing to see here, move along diff --git a/src/spell-convert/parser.hpp b/src/spell-convert/parser.hpp deleted file mode 100644 index 889f2bb..0000000 --- a/src/spell-convert/parser.hpp +++ /dev/null @@ -1,152 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.0.2. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -#ifndef YY_SPELL_CONVERTER_SRC_SPELL_CONVERT_PARSER_HPP_INCLUDED -# define YY_SPELL_CONVERTER_SRC_SPELL_CONVERT_PARSER_HPP_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int spell_converterdebug; -#endif -/* "%code requires" blocks. */ -#line 2 "../src/spell-convert/parser.ypp" /* yacc.c:1909 */ - -/* vim: set ft=yacc: */ -#include "../strings/rstring.hpp" - -#include "ast.hpp" - -#undef YYERROR_VERBOSE -#define YYERROR_VERBOSE 1 - -#line 54 "src/spell-convert/parser.hpp" /* yacc.c:1909 */ - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - INT = 258, - STRING = 259, - ID = 260, - DIR = 261, - CONST = 262, - PROCEDURE = 263, - CALL = 264, - SILENT = 265, - LOCAL = 266, - NONMAGIC = 267, - SHL = 268, - SHR = 269, - EQ = 270, - NEQ = 271, - GTE = 272, - LTE = 273, - ANDAND = 274, - OROR = 275, - SCRIPT_DATA = 276, - TO = 277, - TOWARDS = 278, - TELEPORT_ANCHOR = 279, - SPELL = 280, - LET = 281, - IN = 282, - END = 283, - DARROW = 284, - STRING_TY = 285, - REQUIRE = 286, - CATALYSTS = 287, - COMPONENTS = 288, - MANA = 289, - CASTTIME = 290, - SKIP = 291, - ABORT = 292, - BREAK = 293, - EFFECT_ = 294, - ATEND = 295, - ATTRIGGER = 296, - PC_F = 297, - NPC_F = 298, - MOB_F = 299, - ENTITY_F = 300, - TARGET_F = 301, - IF = 302, - THEN = 303, - ELSE = 304, - FOREACH = 305, - FOR = 306, - DO = 307, - SLEEP = 308, - OR = 309 - }; -#endif - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE YYSTYPE; -union YYSTYPE -{ -#line 27 "../src/spell-convert/parser.ypp" /* yacc.c:1909 */ - - RString *s; - std::vector<RString> *vs; - Effect *e; - std::deque<Effect *> *ve; - SpellDef *spelldef; - SpellArg *spellarg; - TopLevel *top; - Expression *expr; - std::vector<Expression *> *vx; - Location *loc; - Item *it; - std::vector<Item *> *vit; - Assignment *a; - std::vector<Assignment *> *va; - SpellBod *b; - std::vector<SpellBod *> *vb; - SpellGuard *g; - std::vector<SpellGuard *> *vg; - -#line 142 "src/spell-convert/parser.hpp" /* yacc.c:1909 */ -}; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - -extern YYSTYPE spell_converterlval; - -int spell_converterparse (void); - -#endif /* !YY_SPELL_CONVERTER_SRC_SPELL_CONVERT_PARSER_HPP_INCLUDED */ diff --git a/src/spell-convert/parser.ypp b/src/spell-convert/parser.ypp deleted file mode 100644 index 8a40543..0000000 --- a/src/spell-convert/parser.ypp +++ /dev/null @@ -1,902 +0,0 @@ -%code requires -{ -/* vim: set ft=yacc: */ -// magic-interpreter-parser.ypp - Old magic tokenizer -// -// Copyright © 2004-2011 The Mana World Development Team -// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com> -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include "../strings/rstring.hpp" - -#include "ast.hpp" - -#undef YYERROR_VERBOSE -#define YYERROR_VERBOSE 1 -} // %code requires - -%code -{ -//#include "parser.hpp" -#include "lexer.hpp" - -#include "../io/cxxstdio.hpp" - -#include "../sexpr/lexer.hpp" - -void yyerror(const char *msg) { FPRINTF(stderr, "Fatal: %s\n", msg); abort(); } -} // %code - -%name-prefix "spell_converter" - -%union -{ - RString *s; - std::vector<RString> *vs; - Effect *e; - std::deque<Effect *> *ve; - SpellDef *spelldef; - SpellArg *spellarg; - TopLevel *top; - Expression *expr; - std::vector<Expression *> *vx; - Location *loc; - Item *it; - std::vector<Item *> *vit; - Assignment *a; - std::vector<Assignment *> *va; - SpellBod *b; - std::vector<SpellBod *> *vb; - SpellGuard *g; - std::vector<SpellGuard *> *vg; -} // %union - -%expect 7 - -%token <s> INT -%token <s> STRING -%token <s> ID -%token <s> DIR - -%token '=' -%token '<' -%token '>' -%token '+' -%token '-' -%token '*' -%token '/' -%token '%' -%token '@' -%token ',' -%token '.' -%token ':' -%token ';' -%token '|' -%token '[' -%token ']' -%token '&' -%token '^' - -%token CONST -%token PROCEDURE -%token CALL -%token SILENT -%token LOCAL -%token NONMAGIC -%token SHL -%token SHR -%token EQ -%token NEQ -%token GTE -%token LTE -%token ANDAND -%token OROR -%token <s> SCRIPT_DATA -%token TO -%token TOWARDS -%token TELEPORT_ANCHOR -%token SPELL -%token LET -%token IN -%token END -%token DARROW -%token STRING_TY -%token REQUIRE -%token CATALYSTS -%token COMPONENTS -%token MANA -%token CASTTIME -%token SKIP -%token ABORT -%token BREAK -%token EFFECT_ -%token ATEND -%token ATTRIGGER -%token PC_F -%token NPC_F -%token MOB_F -%token ENTITY_F -%token TARGET_F -%token IF -%token THEN -%token ELSE -%token FOREACH -%token FOR -%token DO -%token SLEEP - -%type <s> value -%type <loc> location -%type <expr> area -%type <vx> arg_list -%type <vx> arg_list_ne -%type <va> defs -%type <spelldef> spelldef -%type <spellarg> argopt -%type <a> def -%type <vb> spellbody_list -%type <b> spellbody -%type <g> spellguard -%type <vg> spellguard_list -%type <g> prereq -%type <it> item -%type <vit> items -%type <vit> item_list -%type <s> item_name -%type <s> selection; -%type <e> effect -%type <ve> effect_list -%type <ve> maybe_trigger -%type <ve> maybe_end -%type <vs> spell_flags; - -%type <expr> expr -%type <s> arg_ty -%type <vs> proc_formals_list -%type <vs> proc_formals_list_ne - -%type <top> spellconf_option - -%left OROR -%left ANDAND -%left '<' '>' GTE LTE NEQ EQ -%left '+' '-' -%left '*' '/' '%' -%left SHL SHR '&' '^' '|' -%right '=' -%left OR -%left DARROW -%left '.' - -%% - -spellconf - -: /* empty */ - -| spellconf semicolons spellconf_option -{ - $3->dump(); -} - -; - - -semicolons - -: /* empty */ - -| semicolons ';' - -; - - -proc_formals_list - -: /* empty */ -{ - $$ = new std::vector<RString>(); -} - -| proc_formals_list_ne -{ - $$ = $1; -} - -; - - -proc_formals_list_ne - -: ID -{ - $$ = new std::vector<RString>(); - $$->push_back(*$1); -} - -| proc_formals_list_ne ',' ID -{ - $$ = $1; - $$->push_back(*$3); -} - -; - - -spellconf_option - -: ID '=' expr -{ - $$ = new Assignment{*$1, $3}; -} - -| CONST ID '=' expr -{ - $$ = new Constant{*$2, $4}; -} - -| TELEPORT_ANCHOR ID ':' expr '=' expr -{ - $$ = new Teleport{*$2, $4, $6}; -} - -| PROCEDURE ID '(' proc_formals_list ')' '=' effect_list -{ - $$ = new Procedure{*$2, $4, $7}; -} - -| spell_flags SPELL ID argopt ':' expr '=' spelldef -{ - $$ = new Spell{$1, *$3, $4, $6, $8}; -} - -; - - -spell_flags - -: /* empty */ -{ - $$ = new std::vector<RString>(); -} - -| spell_flags LOCAL -{ - $$ = $1; - $$->push_back("LOCAL"); -} - -| spell_flags NONMAGIC -{ - $$ = $1; - $$->push_back("NONMAGIC"); -} - -| spell_flags SILENT -{ - $$ = $1; - $$->push_back("SILENT"); -} - -; - - -argopt - -: /* empty */ -{ - $$ = new SpellArg{}; -} - -| '(' ID ':' arg_ty ')' -{ - $$ = new SpellArg{*$2, *$4}; -} - -; - - -arg_ty - -: PC_F -{ - $$ = new RString("PC"); -} - -| STRING_TY -{ - $$ = new RString("STRING"); -} - -; - - -value - -: DIR -{ - $$ = $1; -} - -| INT -{ - $$ = $1; -} - -| STRING -{ - $$ = $1; -} - -; - - -expr - -: value -{ - $$ = new SimpleExpr{*$1}; -} - -| ID -{ - $$ = new SimpleExpr{*$1}; -} - -| area -{ - $$ = $1; -} - -| expr '+' expr -{ - $$ = new BinExpr{$1, "+", $3}; -} - -| expr '-' expr -{ - $$ = new BinExpr{$1, "-", $3}; -} - -| expr '*' expr -{ - $$ = new BinExpr{$1, "*", $3}; -} - -| expr '%' expr -{ - $$ = new BinExpr{$1, "%", $3}; -} - -| expr '/' expr -{ - $$ = new BinExpr{$1, "/", $3}; -} - -| expr '<' expr -{ - $$ = new BinExpr{$1, "<", $3}; -} - -| expr '>' expr -{ - $$ = new BinExpr{$1, ">", $3}; -} - -| expr '&' expr -{ - $$ = new BinExpr{$1, "&", $3}; -} - -| expr '^' expr -{ - $$ = new BinExpr{$1, "^", $3}; -} - -| expr '|' expr -{ - $$ = new BinExpr{$1, "|", $3}; -} - -| expr SHL expr -{ - $$ = new BinExpr{$1, "<<", $3}; -} - -| expr SHR expr -{ - $$ = new BinExpr{$1, ">>", $3}; -} - -| expr LTE expr -{ - $$ = new BinExpr{$1, "<=", $3}; -} - -| expr GTE expr -{ - $$ = new BinExpr{$1, ">=", $3}; -} - -| expr ANDAND expr -{ - $$ = new BinExpr{$1, "&&", $3}; -} - -| expr OROR expr -{ - $$ = new BinExpr{$1, "||", $3}; -} - -| expr EQ expr -{ - $$ = new BinExpr{$1, "==", $3}; -} - -| expr '=' expr -{ - // convert to == - $$ = new BinExpr{$1, "==", $3}; -} - -| expr NEQ expr -{ - $$ = new BinExpr{$1, "!=", $3}; -} - -| ID '(' arg_list ')' -{ - $$ = new CallExpr{*$1, $3}; -} - -| '(' expr ')' -{ - $$ = $2; -} - -| expr '.' ID -{ - $$ = new BinExpr{$1, ".", new SimpleExpr(*$3)}; -} - -; - - -arg_list - -: /* empty */ -{ - $$ = new std::vector<Expression *>(); -} - -| arg_list_ne -{ - $$ = $1; -} - -; - - -arg_list_ne - -: expr -{ - $$ = new std::vector<Expression *>(); - $$->push_back($1); -} - -| arg_list_ne ',' expr -{ - $$ = $1; - $$->push_back($3); -} - -; - - -location - -: '@' '(' expr ',' expr ',' expr ')' -{ - $$ = new Location{$3, $5, $7}; -} - -; - - -area - -: location -{ - $$ = new AreaLoc{$1}; -} - -| location '@' '+' '(' expr ',' expr ')' -{ - $$ = new AreaRect{$1, $5, $7}; -} - -| location TOWARDS expr ':' '(' expr ',' expr ')' -{ - $$ = new AreaBar{$1, $3, $6, $8}; -} - -; - - -spelldef - -: spellbody_list -{ - $$ = new SpellDef{new std::vector<Assignment *>{}, $1}; -} - -| LET defs IN spellbody_list -{ - $$ = new SpellDef{$2, $4}; -} - -; - - -defs - -: semicolons -{ - $$ = new std::vector<Assignment *>(); -} - -| defs def semicolons -{ - $$ = $1; - $$->push_back($2); -} - -; - - -def - -: ID '=' expr -{ - $$ = new Assignment{*$1, $3}; -} - -; - - -spellbody_list - -: spellbody -{ - $$ = new std::vector<SpellBod *>(); - $$->push_back($1); -} - -| spellbody_list '|' spellbody -{ - $$ = $1; - $$->push_back($3); -} - -; - - -spellbody - -: spellguard DARROW spellbody -{ - $$ = new SpellBodGuarded{$1, $3}; -} - -| '(' spellbody_list ')' -{ - $$ = new SpellBodList{$2}; -} - -| EFFECT_ effect_list maybe_trigger maybe_end -{ - $$ = new SpellBodEffect{$2, $3, $4}; -} - -; - - -maybe_trigger - -: /* empty */ -{ - $$ = nullptr; -} - -| ATTRIGGER effect_list -{ - $$ = $2; -} - -; - - -maybe_end - -: /* empty */ -{ - $$ = nullptr; -} - -| ATEND effect_list -{ - $$ = $2; -} - -; - - -spellguard - -: prereq -{ - $$ = $1; -} - -| spellguard OR spellguard -{ - $$ = new SpellGuardOr($1, $3); -} - -| '(' spellguard_list ')' -{ - $$ = new SpellGuardList{$2}; -} - -; - - -spellguard_list - -: spellguard -{ - $$ = new std::vector<SpellGuard *>(); - $$->push_back($1); -} - -| spellguard_list ',' spellguard -{ - $$ = $1; - $$->push_back($3); -} - -; - - -prereq - -: REQUIRE expr -{ - $$ = new SpellGuardRequire{$2}; -} - -| CATALYSTS items -{ - $$ = new SpellGuardCatalysts{$2}; -} - -| COMPONENTS items -{ - $$ = new SpellGuardComponents{$2}; -} - -| MANA expr -{ - $$ = new SpellGuardMana{$2}; -} - -| CASTTIME expr -{ - $$ = new SpellGuardCasttime{$2}; -} - -; - - -items - -: '[' item_list ']' -{ - $$ = $2; -} - -; - - -item_list - -: item -{ - $$ = new std::vector<Item *>(); - $$->push_back($1); -} - -| item_list ',' item -{ - $$ = $1; - $$->push_back($3); -} - -; - - -item - -: INT '*' item_name -{ - $$ = new Item{*$1, *$3}; -} - -| item_name -{ - $$ = new Item{RString(), *$1}; -} - -; - - -item_name - -: STRING -{ - $$ = $1; -} - -| INT -{ - $$ = $1; -} - -; - - -selection - -: PC_F -{ - $$ = new RString{"PC"}; -} - -| MOB_F -{ - $$ = new RString{"MOB"}; -} - -| ENTITY_F -{ - $$ = new RString{"ENTITY"}; -} - -| SPELL -{ - $$ = new RString{"SPELL"}; -} - -| TARGET_F -{ - $$ = new RString{"TARGET"}; -} - -| NPC_F -{ - $$ = new RString{"NPC"}; -} - -; - - -effect - -: '(' effect_list ')' -{ - $$ = new EffectList{$2}; -} - -| SKIP ';' -{ - $$ = new SimpleEffect{"SKIP"}; -} - -| ABORT ';' -{ - $$ = new SimpleEffect{"ABORT"}; -} - -| END ';' -{ - $$ = new SimpleEffect{"END"}; -} - -| BREAK ';' -{ - $$ = new SimpleEffect{"BREAK"}; -} - -| ID '=' expr ';' -{ - $$ = new Assignment(*$1, $3); -} - -| FOREACH selection ID IN expr DO effect -{ - $$ = new ForeachEffect{*$2, *$3, $5, $7}; -} - -| FOR ID '=' expr TO expr DO effect -{ - $$ = new ForEffect{*$2, $4, $6, $8}; -} - -| IF expr THEN effect ELSE effect -{ - $$ = new IfEffect{$2, $4, $6}; -} - -| IF expr THEN effect -{ - $$ = new IfEffect{$2, $4}; -} - -| SLEEP expr ';' -{ - $$ = new SleepEffect{$2}; -} - -| ID '(' arg_list ')' ';' -{ - $$ = new CallExpr{*$1, $3}; -} - -| SCRIPT_DATA -{ - AString tmp = sexpr::escape(*$1); - $$ = new ScriptEffect{RString(tmp)}; -} - -| CALL ID '(' arg_list ')' ';' -{ - $$ = new ExplicitCallEffect{*$2, $4}; -} - -; - - -effect_list - -: /* empty */ -{ - $$ = new std::deque<Effect *>(); -} - -| effect semicolons effect_list -{ - // because of grammar problems, doing this right generates reduce/reduce conflicts - $$ = $3; - $$->push_front($1); -} - -; - - -%% -// Nothing to see here, move along diff --git a/src/strings/all.hpp b/src/strings/all.hpp index 26079ed..8e13b92 100644 --- a/src/strings/all.hpp +++ b/src/strings/all.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_STRINGS_ALL_HPP -#define TMWA_STRINGS_ALL_HPP +#pragma once // strings/all.hpp - All the string classes you'll ever need. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,16 +18,20 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "base.hpp" -# include "mstring.hpp" -# include "rstring.hpp" -# include "astring.hpp" -# include "tstring.hpp" -# include "sstring.hpp" -# include "zstring.hpp" -# include "xstring.hpp" -# include "vstring.hpp" +#include "base.hpp" +#include "mstring.hpp" +#include "rstring.hpp" +#include "astring.hpp" +#include "tstring.hpp" +#include "sstring.hpp" +#include "zstring.hpp" +#include "xstring.hpp" +#include "literal.hpp" +#include "vstring.hpp" -#endif // TMWA_STRINGS_ALL_HPP + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/strings/astring.cpp b/src/strings/astring.cpp index f1e9030..f1f12c3 100644 --- a/src/strings/astring.cpp +++ b/src/strings/astring.cpp @@ -18,15 +18,25 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include <cstdarg> +#include <cstdio> +#include <cstdlib> + +#include <algorithm> + #include "mstring.hpp" #include "tstring.hpp" #include "sstring.hpp" #include "zstring.hpp" #include "xstring.hpp" -#include "vstring.hpp" +#include "literal.hpp" +// doing sneaky tricks here //#include "../poison.hpp" + +namespace tmwa +{ namespace strings { static_assert(sizeof(AString) == 256, "AString"); @@ -156,6 +166,13 @@ namespace strings special = 255 - x.size(); } } + AString::AString(LString l) + : data{}, special() + { + new(r_ptr()) RString(); + special = 255; + *this = XString(l); + } AString::iterator AString::begin() const { @@ -205,27 +222,5 @@ namespace strings out = AString(buffer, buffer + len); return len; } - - AStringConverter::AStringConverter(AString& s) - : out(s), mid(nullptr) - {} - - AStringConverter::~AStringConverter() - { - if (mid) - { - out = ZString(really_construct_from_a_pointer, mid, nullptr); - free(mid); - } - } - - char **AStringConverter::operator &() - { - return ∣ - } - - AStringConverter convert_for_scanf(AString& s) - { - return AStringConverter(s); - } } // namespace strings +} // namespace tmwa diff --git a/src/strings/astring.hpp b/src/strings/astring.hpp index aab14cf..83399f0 100644 --- a/src/strings/astring.hpp +++ b/src/strings/astring.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_STRINGS_ASTRING_HPP -#define TMWA_STRINGS_ASTRING_HPP +#pragma once // strings/astring.hpp - An owned, reference-counted immutable string. // // Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,20 +18,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdarg> -# include <cstring> +#include "base.hpp" +#include "rstring.hpp" -# include "base.hpp" -# include "rstring.hpp" +namespace tmwa +{ namespace strings { /// An owning string that has reached its final contents. /// The storage is NUL-terminated class AString : public _crtp_string<AString, AString, ZPair> { +#ifdef __clang__ + __attribute__((unused)) +#endif RString *align[0]; char data[255]; unsigned char special; @@ -49,12 +51,6 @@ namespace strings explicit AString(const MString& s); - template<size_t n> - AString(char (&s)[n]) = delete; - - template<size_t n> - AString(const char (&s)[n]); - template<class It> AString(It b, It e); @@ -66,6 +62,7 @@ namespace strings AString(XString); template<uint8_t n> AString(const VString<n>& v); + AString(LString s); iterator begin() const; iterator end() const; @@ -81,20 +78,7 @@ namespace strings __attribute__((format(printf, 2, 0))) int do_vprint(AString& out, const char *fmt, va_list ap); - - class AStringConverter - { - AString& out; - char *mid; - public: - AStringConverter(AString& s); - ~AStringConverter(); - char **operator &(); - }; - - AStringConverter convert_for_scanf(AString& s); } // namespace strings +} // namespace tmwa -# include "astring.tcc" - -#endif // TMWA_STRINGS_ASTRING_HPP +#include "astring.tcc" diff --git a/src/strings/astring.py b/src/strings/astring.py index ec1dafe..063e721 100644 --- a/src/strings/astring.py +++ b/src/strings/astring.py @@ -2,7 +2,7 @@ class AString(object): ''' print an AString ''' __slots__ = ('_value') - name = 'strings::AString' + name = 'tmwa::strings::AString' enabled = True def __init__(self, value): diff --git a/src/strings/astring.tcc b/src/strings/astring.tcc index ed07bd9..f2d0dc9 100644 --- a/src/strings/astring.tcc +++ b/src/strings/astring.tcc @@ -19,25 +19,11 @@ #include "mstring.hpp" + +namespace tmwa +{ namespace strings { - template<size_t n> - AString::AString(const char (&s)[n]) - : data{}, special() - { - XPair x = s; - if (x.size() > 255 || x.size() == 0) - { - new(r_ptr()) RString(x); - special = 255; - } - else - { - *std::copy(x.begin(), x.end(), data) = '\0'; - special = 255 - x.size(); - } - } - template<class It> AString::AString(It b, It e) : data{}, special() @@ -74,3 +60,4 @@ namespace strings new(r_ptr()) RString(); } } // namespace strings +} // namespace tmwa diff --git a/src/strings/base.hpp b/src/strings/base.hpp index ee7480b..b6b3df0 100644 --- a/src/strings/base.hpp +++ b/src/strings/base.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_STRINGS_BASE_HPP -#define TMWA_STRINGS_BASE_HPP +#pragma once // strings/base.hpp - CRTP base for string implementations. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,15 +18,16 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" +#include "pair.hpp" -# include "fwd.hpp" -# include "pair.hpp" +#include <cstddef> -# include <cstddef> +#include <iterator> -# include <iterator> +namespace tmwa +{ // It is a common mistake to assume that one string class for everything. // Because C++ and TMWA have a C legacy, there are a few more here // than would probably be necessary in an ideal language. @@ -197,7 +197,6 @@ namespace strings template<class L, class R, typename=typename std::enable_if<string_comparison_allowed<L, R>::value>::type> auto operator >= (const L& l, const R& r) -> decltype((pair_compare(l, r), true)); } // namespace strings +} // namespace tmwa -# include "base.tcc" - -#endif // TMWA_STRINGS_BASE_HPP +#include "base.tcc" diff --git a/src/strings/base.tcc b/src/strings/base.tcc index a5a57d0..83dff70 100644 --- a/src/strings/base.tcc +++ b/src/strings/base.tcc @@ -17,10 +17,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include <cstddef> + #include <algorithm> #include "pair.hpp" + +namespace tmwa +{ namespace strings { namespace detail @@ -440,3 +445,4 @@ namespace strings return pair_compare(l, r) >= 0; } } // namespace strings +} // namespace tmwa diff --git a/src/strings/base_test.cpp b/src/strings/base_test.cpp index 52c44dc..f9b9ca6 100644 --- a/src/strings/base_test.cpp +++ b/src/strings/base_test.cpp @@ -23,9 +23,13 @@ #include "vstring.hpp" #include "xstring.hpp" #include "rstring.hpp" +#include "literal.hpp" #include "../poison.hpp" + +namespace tmwa +{ using namespace strings; struct _test : VString<1> {}; @@ -42,7 +46,8 @@ static_assert(string_comparison_allowed<XString, RString>::value, "xf"); TEST(strings, contains) { - XString hi = "Hello"; - EXPECT_TRUE(hi.contains_any("Hi")); - EXPECT_FALSE(hi.contains_any("hi")); + XString hi = "Hello"_s; + EXPECT_TRUE(hi.contains_any("Hi"_s)); + EXPECT_FALSE(hi.contains_any("hi"_s)); } +} // namespace tmwa diff --git a/src/strings/fwd.hpp b/src/strings/fwd.hpp index 4c58e03..b1b8266 100644 --- a/src/strings/fwd.hpp +++ b/src/strings/fwd.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_STRINGS_FWD_HPP -#define TMWA_STRINGS_FWD_HPP +#pragma once // strings/fwd.hpp - Forward declarations for all the string classes. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,10 +18,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "../sanity.hpp" -# include <cstdint> +#include <cstddef> +#include <cstdint> + +namespace tmwa +{ // It is a common mistake to assume that one string class for everything. // Because C++ and TMWA have a C legacy, there are a few more here // than would probably be necessary in an ideal language. @@ -40,12 +43,18 @@ namespace strings class XString; // semi-owning + class LString; + class FormatString; template<uint8_t len> class VString; - // refactor this into a function? + // TODO refactor this into a function? enum _type_that_just_has_a_name_to_fix_linkage { really_construct_from_a_pointer }; + + LString operator "" _s(const char *, size_t); + constexpr + FormatString operator "" _fmt(const char *, size_t); } // namespace strings using strings::MString; @@ -57,6 +66,10 @@ using strings::SString; using strings::ZString; using strings::XString; +using strings::LString; +using strings::FormatString; using strings::VString; -#endif // TMWA_STRINGS_FWD_HPP +using strings::operator "" _s; +using strings::operator "" _fmt; +} // namespace tmwa diff --git a/src/strings/literal.cpp b/src/strings/literal.cpp new file mode 100644 index 0000000..252bfcb --- /dev/null +++ b/src/strings/literal.cpp @@ -0,0 +1,56 @@ +#include "literal.hpp" +// strings/literal.cpp - A string stored in the readonly data segment. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include <cstdio> + +#include "../poison.hpp" + + +namespace tmwa +{ +namespace strings +{ + LString::LString(const char *b, const char *e) + : _b(b), _e(e) + {} + + LString::iterator LString::begin() const + { + return _b; + } + LString::iterator LString::end() const + { + return _e; + } + const RString *LString::base() const + { + return nullptr; + } + const char *LString::c_str() const + { + return &*begin(); + } + + const char *decay_for_printf(const LString& zs) + { + return zs.c_str(); + } +} // namespace strings +} // namespace tmwa diff --git a/src/strings/literal.hpp b/src/strings/literal.hpp new file mode 100644 index 0000000..67bd317 --- /dev/null +++ b/src/strings/literal.hpp @@ -0,0 +1,79 @@ +#pragma once +// strings/literal.hpp - A string stored in the readonly data segment. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include "base.hpp" + + +namespace tmwa +{ +namespace strings +{ + /// A statically owned string that is guaranteed to be NUL-terminated. + /// This is a more permissive lifetime than anybody else has. + class LString : public _crtp_string<LString, AString, LPair> + { + iterator _b, _e; + private: + LString(const char *b, const char *e); + friend LString operator "" _s(const char *, size_t); + // for tail slicing + LString(const char *b, const char *e, const RString *) : LString(b, e) {} + friend class _crtp_string<LString, AString, LPair>; + public: + + iterator begin() const; + iterator end() const; + const RString *base() const; + const char *c_str() const; + }; + + class FormatString + { + const char *_format; + + friend constexpr FormatString operator "" _fmt(const char *, size_t); + constexpr explicit + FormatString(const char *f) : _format(f) {} + public: + constexpr + const char *format_string() const { return _format; } + }; + + + // cxxstdio helpers + // I think the conversion will happen automatically. TODO test this. + // Nope, it doesn't, since there's a template + // Actually, it might now. + const char *decay_for_printf(const LString& zs); + + inline + LString operator "" _s(const char *s, size_t) + { + return LString(s, s + __builtin_strlen(s)); + } + constexpr + FormatString operator "" _fmt(const char *s, size_t) + { + return FormatString(s); + } +} // namespace strings +} // namespace tmwa diff --git a/src/strings/mstring.cpp b/src/strings/mstring.cpp index 2a1ca62..d48bff2 100644 --- a/src/strings/mstring.cpp +++ b/src/strings/mstring.cpp @@ -22,6 +22,9 @@ #include "../poison.hpp" + +namespace tmwa +{ namespace strings { MString::iterator MString::begin() @@ -100,3 +103,4 @@ namespace strings return _hack.back(); } } // namespace strings +} // namespace tmwa diff --git a/src/strings/mstring.hpp b/src/strings/mstring.hpp index 8225d9e..4f40919 100644 --- a/src/strings/mstring.hpp +++ b/src/strings/mstring.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_STRINGS_MSTRING_HPP -#define TMWA_STRINGS_MSTRING_HPP +#pragma once // strings/mstring.hpp - A mutable string. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,12 +18,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <deque> +#include <deque> -# include "base.hpp" +namespace tmwa +{ namespace strings { /// An owning string that is still expected to change. @@ -64,5 +64,4 @@ namespace strings char& back(); }; } // namespace strings - -#endif // TMWA_STRINGS_MSTRING_HPP +} // namespace tmwa diff --git a/src/strings/pair.hpp b/src/strings/pair.hpp index a592a91..9c1cd9f 100644 --- a/src/strings/pair.hpp +++ b/src/strings/pair.hpp @@ -1,8 +1,7 @@ -#ifndef TMWA_STRINGS_PAIR_HPP -#define TMWA_STRINGS_PAIR_HPP +#pragma once // strings/pair.hpp - Internal contiguous range. // -// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> +// Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com> // // This file is part of The Mana World (Athena server) // @@ -19,12 +18,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstring> - -# include "fwd.hpp" +namespace tmwa +{ namespace strings { // TODO instead typedef ranges::Contiguous<const char> @@ -40,12 +38,6 @@ namespace strings XPair(const char *b, const char *e) : _begin(b), _end(e) {} - template<size_t n> - XPair(char (&arr)[n]) = delete; - template<size_t n> - XPair(const char (&arr)[n]) - : _begin(arr), _end(arr + strlen(arr)) - {} const char *begin() const { return _begin; } const char *end() const { return _end; } @@ -59,13 +51,15 @@ namespace strings ZPair(const char *b, const char *e) : XPair(b, e) {} - template<size_t n> - ZPair(char (&arr)[n]) = delete; - template<size_t n> - ZPair(const char (&arr)[n]) - : XPair(arr) + }; + struct LPair : ZPair + { + typedef LString TailSlice; + typedef XString FullSlice; + + LPair(const char *b, const char *e) + : ZPair(b, e) {} }; } // namespace strings - -#endif // TMWA_STRINGS_PAIR_HPP +} // namespace tmwa diff --git a/src/strings/rstring.cpp b/src/strings/rstring.cpp index c0e231e..3e5a46d 100644 --- a/src/strings/rstring.cpp +++ b/src/strings/rstring.cpp @@ -18,15 +18,22 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include <cstdio> + #include "mstring.hpp" +#include "astring.hpp" #include "tstring.hpp" #include "sstring.hpp" #include "zstring.hpp" #include "xstring.hpp" -#include "vstring.hpp" +#include "literal.hpp" +// doing sneaky tricks here //#include "../poison.hpp" + +namespace tmwa +{ namespace strings { static_assert(sizeof(RString) == sizeof(const char *), "RString"); @@ -54,7 +61,7 @@ namespace strings { // order important for self-assign r.owned->count++; - // owned can be NULL from ctors + // owned can be nullptr from ctors // TODO do ctors *properly* (requires gcc 4.7 to stay sane) if (owned && !owned->count--) ::operator delete(owned); @@ -125,6 +132,11 @@ namespace strings else _assign(x.begin(), x.end()); } + RString::RString(LString l) + : owned(nullptr) + { + *this = XString(l); + } RString::iterator RString::begin() const { @@ -164,3 +176,4 @@ namespace strings return len; } } // namespace strings +} // namespace tmwa diff --git a/src/strings/rstring.hpp b/src/strings/rstring.hpp index 7cb19d6..fd3ee65 100644 --- a/src/strings/rstring.hpp +++ b/src/strings/rstring.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_STRINGS_RSTRING_HPP -#define TMWA_STRINGS_RSTRING_HPP +#pragma once // strings/rstring.hpp - An owned, reference-counted immutable string. // // Copyright © 2013-2014 Ben Longbons <b.r.longbons@gmail.com> @@ -19,13 +18,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstdarg> -# include <cstring> +#include <cstdarg> -# include "base.hpp" +#include "base.hpp" + +namespace tmwa +{ namespace strings { /// An owning string that has reached its final contents. @@ -56,12 +57,6 @@ namespace strings explicit RString(const MString& s); - template<size_t n> - RString(char (&s)[n]) = delete; - - template<size_t n> - RString(const char (&s)[n]); - template<class It> RString(It b, It e); @@ -73,6 +68,7 @@ namespace strings RString(XString); template<uint8_t n> RString(const VString<n>& v); + RString(LString s); iterator begin() const; iterator end() const; @@ -89,7 +85,6 @@ namespace strings __attribute__((format(printf, 2, 0))) int do_vprint(RString& out, const char *fmt, va_list ap); } // namespace strings +} // namespace tmwa -# include "rstring.tcc" - -#endif // TMWA_STRINGS_RSTRING_HPP +#include "rstring.tcc" diff --git a/src/strings/rstring.py b/src/strings/rstring.py index f0618d6..8021ec2 100644 --- a/src/strings/rstring.py +++ b/src/strings/rstring.py @@ -2,7 +2,7 @@ class RString(object): ''' print a RString ''' __slots__ = ('_value') - name = 'strings::RString' + name = 'tmwa::strings::RString' enabled = True def __init__(self, value): diff --git a/src/strings/rstring.tcc b/src/strings/rstring.tcc index 8b4c0c0..c247b8f 100644 --- a/src/strings/rstring.tcc +++ b/src/strings/rstring.tcc @@ -19,6 +19,9 @@ #include "mstring.hpp" + +namespace tmwa +{ namespace strings { template<class It> @@ -47,12 +50,6 @@ namespace strings owned->body[diff] = '\0'; } - template<size_t n> - RString::RString(const char (&s)[n]) - { - _assign(s, s + strlen(s)); - } - template<class It> RString::RString(It b, It e) { @@ -65,3 +62,4 @@ namespace strings _assign(v.begin(), v.end()); } } // namespace strings +} // namespace tmwa diff --git a/src/strings/sstring.cpp b/src/strings/sstring.cpp index 76f0994..0500129 100644 --- a/src/strings/sstring.cpp +++ b/src/strings/sstring.cpp @@ -18,12 +18,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include "rstring.hpp" +#include "astring.hpp" #include "tstring.hpp" #include "zstring.hpp" #include "xstring.hpp" +#include "literal.hpp" #include "../poison.hpp" + +namespace tmwa +{ namespace strings { SString::SString() @@ -54,6 +60,10 @@ namespace strings else *this = RString(x); } + SString::SString(const LString& l) + { + *this = XString(l); + } SString::SString(RString r, size_t b, size_t e) : _s(std::move(r)), _b(b), _e(e) @@ -95,3 +105,4 @@ namespace strings return &_s; } } // namespace strings +} // namespace tmwa diff --git a/src/strings/sstring.hpp b/src/strings/sstring.hpp index 7166e94..a65616d 100644 --- a/src/strings/sstring.hpp +++ b/src/strings/sstring.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_STRINGS_SSTRING_HPP -#define TMWA_STRINGS_SSTRING_HPP +#pragma once // strings/sstring.hpp - A full slice of an RString. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,11 +18,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "base.hpp" -# include "rstring.hpp" +#include "base.hpp" +#include "rstring.hpp" + +namespace tmwa +{ namespace strings { /// An owning string that represents a arbitrary slice of an RString. @@ -42,10 +44,7 @@ namespace strings SString(const XString&); template<uint8_t n> SString(const VString<n>& v); - template<size_t n> - SString(char (&s)[n]) = delete; - template<size_t n> - SString(const char (&s)[n]); + SString(const LString&); //template<class It> //SString(It b, It e) : _s(b, e), _b(0), _e(_s.size()) {} SString(RString f, size_t b, size_t e); @@ -57,7 +56,6 @@ namespace strings const RString *base() const; }; } // namespace strings +} // namespace tmwa -# include "sstring.tcc" - -#endif // TMWA_STRINGS_SSTRING_HPP +#include "sstring.tcc" diff --git a/src/strings/sstring.tcc b/src/strings/sstring.tcc index 4be33dd..315e19a 100644 --- a/src/strings/sstring.tcc +++ b/src/strings/sstring.tcc @@ -19,15 +19,14 @@ #include "vstring.hpp" + +namespace tmwa +{ namespace strings { template<uint8_t n> SString::SString(const VString<n>& v) : _s(v), _b(0), _e(_s.size()) {} - - template<size_t n> - SString::SString(const char (&s)[n]) - : _s(s), _b(0), _e(_s.size()) - {} } // namespace strings +} // namespace tmwa diff --git a/src/strings/strings2_test.cpp b/src/strings/strings2_test.cpp index e5d5281..18c7db4 100644 --- a/src/strings/strings2_test.cpp +++ b/src/strings/strings2_test.cpp @@ -1,4 +1,3 @@ -#include "all.hpp" // strings2_test.cpp - Testsuite part 2 for strings. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -18,30 +17,34 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. - #include <gtest/gtest.h> +#include "all.hpp" + #include "../poison.hpp" + +namespace tmwa +{ TEST(StringTests, traits2) { - ZString print_non = "\t\e"; - ZString print_mix = "n\t"; - RString print_all = "n "; + ZString print_non = "\t\e"_s; + ZString print_mix = "n\t"_s; + RString print_all = "n "_s; EXPECT_FALSE(print_non.has_print()); EXPECT_TRUE(print_mix.has_print()); EXPECT_TRUE(print_all.has_print()); EXPECT_FALSE(print_non.is_print()); EXPECT_FALSE(print_mix.is_print()); EXPECT_TRUE(print_all.is_print()); - EXPECT_EQ("__", print_non.to_print()); - EXPECT_EQ("n_", print_mix.to_print()); - EXPECT_EQ("n ", print_all.to_print()); + EXPECT_EQ("__"_s, print_non.to_print()); + EXPECT_EQ("n_"_s, print_mix.to_print()); + EXPECT_EQ("n "_s, print_all.to_print()); EXPECT_EQ(print_all.begin(), print_all.to_print().begin()); - ZString graph_non = " \e"; - ZString graph_mix = "n "; - RString graph_all = "n."; + ZString graph_non = " \e"_s; + ZString graph_mix = "n "_s; + RString graph_all = "n."_s; EXPECT_FALSE(graph_non.has_graph()); EXPECT_TRUE(graph_mix.has_graph()); EXPECT_TRUE(graph_all.has_graph()); @@ -49,37 +52,37 @@ TEST(StringTests, traits2) EXPECT_FALSE(graph_mix.is_graph()); EXPECT_TRUE(graph_all.is_graph()); - ZString lower_non = "0A"; - ZString lower_mix = "Oa"; - RString lower_all = "oa"; + ZString lower_non = "0A"_s; + ZString lower_mix = "Oa"_s; + RString lower_all = "oa"_s; EXPECT_FALSE(lower_non.has_lower()); EXPECT_TRUE(lower_mix.has_lower()); EXPECT_TRUE(lower_all.has_lower()); EXPECT_FALSE(lower_non.is_lower()); EXPECT_FALSE(lower_mix.is_lower()); EXPECT_TRUE(lower_all.is_lower()); - EXPECT_EQ("0a", lower_non.to_lower()); - EXPECT_EQ("oa", lower_mix.to_lower()); - EXPECT_EQ("oa", lower_all.to_lower()); + EXPECT_EQ("0a"_s, lower_non.to_lower()); + EXPECT_EQ("oa"_s, lower_mix.to_lower()); + EXPECT_EQ("oa"_s, lower_all.to_lower()); EXPECT_EQ(lower_all.begin(), lower_all.to_lower().begin()); - ZString upper_non = "0a"; - ZString upper_mix = "oA"; - RString upper_all = "OA"; + ZString upper_non = "0a"_s; + ZString upper_mix = "oA"_s; + RString upper_all = "OA"_s; EXPECT_FALSE(upper_non.has_upper()); EXPECT_TRUE(upper_mix.has_upper()); EXPECT_TRUE(upper_all.has_upper()); EXPECT_FALSE(upper_non.is_upper()); EXPECT_FALSE(upper_mix.is_upper()); EXPECT_TRUE(upper_all.is_upper()); - EXPECT_EQ("0A", upper_non.to_upper()); - EXPECT_EQ("OA", upper_mix.to_upper()); - EXPECT_EQ("OA", upper_all.to_upper()); + EXPECT_EQ("0A"_s, upper_non.to_upper()); + EXPECT_EQ("OA"_s, upper_mix.to_upper()); + EXPECT_EQ("OA"_s, upper_all.to_upper()); EXPECT_EQ(upper_all.begin(), upper_all.to_upper().begin()); - ZString alpha_non = " 0"; - ZString alpha_mix = "n "; - RString alpha_all = "nA"; + ZString alpha_non = " 0"_s; + ZString alpha_mix = "n "_s; + RString alpha_all = "nA"_s; EXPECT_FALSE(alpha_non.has_alpha()); EXPECT_TRUE(alpha_mix.has_alpha()); EXPECT_TRUE(alpha_all.has_alpha()); @@ -87,9 +90,9 @@ TEST(StringTests, traits2) EXPECT_FALSE(alpha_mix.is_alpha()); EXPECT_TRUE(alpha_all.is_alpha()); - ZString digit2_non = "a9"; - ZString digit2_mix = "20"; - RString digit2_all = "01"; + ZString digit2_non = "a9"_s; + ZString digit2_mix = "20"_s; + RString digit2_all = "01"_s; EXPECT_FALSE(digit2_non.has_digit2()); EXPECT_TRUE(digit2_mix.has_digit2()); EXPECT_TRUE(digit2_all.has_digit2()); @@ -97,9 +100,9 @@ TEST(StringTests, traits2) EXPECT_FALSE(digit2_mix.is_digit2()); EXPECT_TRUE(digit2_all.is_digit2()); - ZString digit8_non = "a9"; - ZString digit8_mix = "80"; - RString digit8_all = "37"; + ZString digit8_non = "a9"_s; + ZString digit8_mix = "80"_s; + RString digit8_all = "37"_s; EXPECT_FALSE(digit8_non.has_digit8()); EXPECT_TRUE(digit8_mix.has_digit8()); EXPECT_TRUE(digit8_all.has_digit8()); @@ -107,9 +110,9 @@ TEST(StringTests, traits2) EXPECT_FALSE(digit8_mix.is_digit8()); EXPECT_TRUE(digit8_all.is_digit8()); - ZString digit10_non = "az"; - ZString digit10_mix = "a9"; - RString digit10_all = "42"; + ZString digit10_non = "az"_s; + ZString digit10_mix = "a9"_s; + RString digit10_all = "42"_s; EXPECT_FALSE(digit10_non.has_digit10()); EXPECT_TRUE(digit10_mix.has_digit10()); EXPECT_TRUE(digit10_all.has_digit10()); @@ -117,9 +120,9 @@ TEST(StringTests, traits2) EXPECT_FALSE(digit10_mix.is_digit10()); EXPECT_TRUE(digit10_all.is_digit10()); - ZString digit16_non = "gz"; - ZString digit16_mix = "ao"; - RString digit16_all = "be"; + ZString digit16_non = "gz"_s; + ZString digit16_mix = "ao"_s; + RString digit16_all = "be"_s; EXPECT_FALSE(digit16_non.has_digit16()); EXPECT_TRUE(digit16_mix.has_digit16()); EXPECT_TRUE(digit16_all.has_digit16()); @@ -127,9 +130,9 @@ TEST(StringTests, traits2) EXPECT_FALSE(digit16_mix.is_digit16()); EXPECT_TRUE(digit16_all.is_digit16()); - ZString alnum_non = " ."; - ZString alnum_mix = "n "; - RString alnum_all = "n0"; + ZString alnum_non = " ."_s; + ZString alnum_mix = "n "_s; + RString alnum_all = "n0"_s; EXPECT_FALSE(alnum_non.has_alnum()); EXPECT_TRUE(alnum_mix.has_alnum()); EXPECT_TRUE(alnum_all.has_alnum()); @@ -140,7 +143,7 @@ TEST(StringTests, traits2) TEST(StringTests, rempty) { - const char empty_text[] = ""; + LString empty_text = ""_s; RString r = empty_text; EXPECT_EQ(r.size(), 0); AString a = empty_text; @@ -166,7 +169,7 @@ TEST(StringTests, rempty) } TEST(StringTests, rshort) { - const char short_text[] = "0123456789"; + LString short_text = "0123456789"_s; RString r = short_text; EXPECT_EQ(r.size(), 10); AString a = short_text; @@ -193,13 +196,13 @@ TEST(StringTests, rshort) TEST(StringTests, rlong) { - const char long_text[] = + LString long_text = "01234567890123456789012345678901234567890123456789" "0123456789012345678901234567890123456789012345 100" "01234567890123456789012345678901234567890123456789" "0123456789012345678901234567890123456789012345 200" "01234567890123456789012345678901234567890123456789" - "0123456789012345678901234567890123456789012345 300"; + "0123456789012345678901234567890123456789012345 300"_s; RString r = long_text; EXPECT_EQ(r.size(), 300); AString a = long_text; @@ -223,3 +226,4 @@ TEST(StringTests, rlong) EXPECT_EQ(&*r.begin(), &*r3.begin()); EXPECT_EQ(&*a.begin(), &*a3.begin()); } +} // namespace tmwa diff --git a/src/strings/strings_test.cpp b/src/strings/strings_test.cpp index dca463d..a95499d 100644 --- a/src/strings/strings_test.cpp +++ b/src/strings/strings_test.cpp @@ -1,4 +1,3 @@ -#include "all.hpp" // strings_test.cpp - Testsuite part 1 for strings. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -22,8 +21,13 @@ #include <gtest/gtest.h> +#include "all.hpp" + #include "../poison.hpp" + +namespace tmwa +{ template<typename T> class StringTest : public ::testing::Test { @@ -32,10 +36,10 @@ TYPED_TEST_CASE_P(StringTest); TYPED_TEST_P(StringTest, basic) { - TypeParam hi("Hello"); + TypeParam hi("Hello"_s); EXPECT_EQ(5, hi.size()); EXPECT_EQ(hi, hi); - const char hi2[] = "Hello\0random garbage"; + LString hi2 = "Hello\0random garbage"_s; EXPECT_EQ(hi, hi2); TypeParam hi0; EXPECT_EQ(0, hi0.size()); @@ -47,9 +51,9 @@ TYPED_TEST_P(StringTest, basic) TYPED_TEST_P(StringTest, order) { TypeParam a; - TypeParam b("Hello"); - TypeParam c("Hello,"); - TypeParam d("World!"); + TypeParam b("Hello"_s); + TypeParam c("Hello,"_s); + TypeParam d("World!"_s); // not using EXPECT_LT, etc. for better visibility @@ -158,7 +162,7 @@ TYPED_TEST_P(StringTest, order) TYPED_TEST_P(StringTest, iterators) { - TypeParam hi("Hello"); + TypeParam hi("Hello"_s); EXPECT_EQ(hi.begin(), hi.begin()); EXPECT_NE(hi.begin(), hi.end()); EXPECT_EQ(5, std::distance(hi.begin(), hi.end())); @@ -168,19 +172,19 @@ TYPED_TEST_P(StringTest, iterators) TYPED_TEST_P(StringTest, xslice) { - TypeParam hi("Hello, World!"); - EXPECT_EQ(" World!", hi.xslice_t(6)); - EXPECT_EQ("Hello,", hi.xslice_h(6)); - EXPECT_EQ("World!", hi.xrslice_t(6)); - EXPECT_EQ("Hello, ", hi.xrslice_h(6)); + TypeParam hi("Hello, World!"_s); + EXPECT_EQ(" World!"_s, hi.xslice_t(6)); + EXPECT_EQ("Hello,"_s, hi.xslice_h(6)); + EXPECT_EQ("World!"_s, hi.xrslice_t(6)); + EXPECT_EQ("Hello, "_s, hi.xrslice_h(6)); typename TypeParam::iterator it = std::find(hi.begin(), hi.end(), ' '); - EXPECT_EQ(" World!", hi.xislice_t(it)); - EXPECT_EQ("Hello,", hi.xislice_h(it)); - EXPECT_EQ("World", hi.xlslice(7, 5)); - EXPECT_EQ("World", hi.xpslice(7, 12)); - EXPECT_EQ("World", hi.xislice(hi.begin() + 7, hi.begin() + 12)); - EXPECT_TRUE(hi.startswith("Hello")); - EXPECT_TRUE(hi.endswith("World!")); + EXPECT_EQ(" World!"_s, hi.xislice_t(it)); + EXPECT_EQ("Hello,"_s, hi.xislice_h(it)); + EXPECT_EQ("World"_s, hi.xlslice(7, 5)); + EXPECT_EQ("World"_s, hi.xpslice(7, 12)); + EXPECT_EQ("World"_s, hi.xislice(hi.begin() + 7, hi.begin() + 12)); + EXPECT_TRUE(hi.startswith("Hello"_s)); + EXPECT_TRUE(hi.endswith("World!"_s)); } TYPED_TEST_P(StringTest, convert) @@ -188,15 +192,15 @@ TYPED_TEST_P(StringTest, convert) constexpr bool is_zstring = std::is_same<TypeParam, ZString>::value; typedef typename std::conditional<is_zstring, TString, SString>::type Sstring; typedef typename std::conditional<is_zstring, ZString, XString>::type Xstring; - RString r = "r"; - AString a = "a"; - TString t = "t"; - Sstring s = "s"; - ZString z = "z"; - Xstring x = "x"; - VString<255> v = "v"; - const char l[] = "l"; - VString<5> hi = "hello"; + RString r = "r"_s; + AString a = "a"_s; + TString t = "t"_s; + Sstring s = "s"_s; + ZString z = "z"_s; + Xstring x = "x"_s; + VString<255> v = "v"_s; + LString l = "l"_s; + VString<5> hi = "hello"_s; TypeParam r2 = r; TypeParam a2 = a; @@ -270,7 +274,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(StringStuff, StringTest, MostStringTypes); TEST(VStringTest, basic) { - VString<5> hi = "Hello"; + VString<5> hi = "Hello"_s; EXPECT_EQ(5, hi.size()); EXPECT_EQ(hi, hi); // truncation @@ -278,7 +282,7 @@ TEST(VStringTest, basic) EXPECT_EQ(5, hi2.size()); EXPECT_EQ(hi, hi2); // short - hi = "hi"; + hi = "hi"_s; EXPECT_EQ(2, hi.size()); VString<5> hi0; EXPECT_EQ(0, hi0.size()); @@ -292,7 +296,7 @@ TYPED_TEST_CASE_P(NulStringTest); TYPED_TEST_P(NulStringTest, basic) { - TypeParam hi("hello"); + TypeParam hi("hello"_s); EXPECT_EQ(hi.size(), strlen(hi.c_str())); EXPECT_STREQ("hello", hi.c_str()); } @@ -304,3 +308,4 @@ typedef ::testing::Types< RString, AString, TString, ZString, VString<255> > NulStringTypes; INSTANTIATE_TYPED_TEST_CASE_P(NulStringStuff, NulStringTest, NulStringTypes); +} // namespace tmwa diff --git a/src/strings/tstring.cpp b/src/strings/tstring.cpp index 5f463ca..b0bd74a 100644 --- a/src/strings/tstring.cpp +++ b/src/strings/tstring.cpp @@ -18,12 +18,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include "rstring.hpp" +#include "astring.hpp" #include "sstring.hpp" #include "zstring.hpp" #include "xstring.hpp" +#include "literal.hpp" #include "../poison.hpp" + +namespace tmwa +{ namespace strings { TString::TString() @@ -67,6 +73,10 @@ namespace strings else *this = RString(x); } + TString::TString(const LString& l) + { + *this = XString(l); + } TString::TString(XPair p) : _s(p), _o(0) @@ -94,3 +104,4 @@ namespace strings return ts.c_str(); } } // namespace strings +} // namespace tmwa diff --git a/src/strings/tstring.hpp b/src/strings/tstring.hpp index 7003d37..b0da566 100644 --- a/src/strings/tstring.hpp +++ b/src/strings/tstring.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_STRINGS_TSTRING_HPP -#define TMWA_STRINGS_TSTRING_HPP +#pragma once // strings/tstring.hpp - A tail slice of a string. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,11 +18,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "base.hpp" -# include "rstring.hpp" +#include "base.hpp" +#include "rstring.hpp" + +namespace tmwa +{ namespace strings { /// An owning string that represents a tail slice of an RString. @@ -43,10 +45,7 @@ namespace strings TString(const XString&); template<uint8_t n> TString(const VString<n>& v); - template<size_t n> - TString(char (&s)[n]) = delete; - template<size_t n> - TString(const char (&s)[n]); + TString(const LString&); //template<class It> //TString(It b, It e) : _s(b, e), _o(0) {} TString(XPair p); @@ -63,7 +62,6 @@ namespace strings // Actually, it might now. const char *decay_for_printf(const TString& ts); } // namespace strings +} // namespace tmwa -# include "tstring.tcc" - -#endif // TMWA_STRINGS_TSTRING_HPP +#include "tstring.tcc" diff --git a/src/strings/tstring.tcc b/src/strings/tstring.tcc index 4eba13f..2641fb7 100644 --- a/src/strings/tstring.tcc +++ b/src/strings/tstring.tcc @@ -19,14 +19,14 @@ #include "vstring.hpp" + +namespace tmwa +{ namespace strings { template<uint8_t n> TString::TString(const VString<n>& v) : _s(v), _o(0) {} - template<size_t n> - TString::TString(const char (&s)[n]) - : _s(s), _o(0) - {} } // namespace strings +} // namespace tmwa diff --git a/src/strings/vstring.cpp b/src/strings/vstring.cpp index 0ef8f3d..1cb313a 100644 --- a/src/strings/vstring.cpp +++ b/src/strings/vstring.cpp @@ -20,6 +20,10 @@ #include "../poison.hpp" + +namespace tmwa +{ namespace strings { } // namespace strings +} // namespace tmwa diff --git a/src/strings/vstring.hpp b/src/strings/vstring.hpp index 9952ff9..f3437a5 100644 --- a/src/strings/vstring.hpp +++ b/src/strings/vstring.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_STRINGS_VSTRING_HPP -#define TMWA_STRINGS_VSTRING_HPP +#pragma once // strings/vstring.hpp - A small string that stores its own value. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,10 +18,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "base.hpp" +#include <cstdio> +#include "base.hpp" + + +namespace tmwa +{ namespace strings { template<uint8_t n> @@ -40,10 +44,7 @@ namespace strings VString(ZString z); template<uint8_t m> VString(VString<m> v); - template<size_t m> - VString(char (&s)[m]) = delete; - template<size_t m> - VString(const char (&s)[m]); + VString(LString l); VString(decltype(really_construct_from_a_pointer) e, const char *s); VString(char c); VString(); @@ -74,7 +75,6 @@ T stringish(VString<sizeof(T) - 1> iv) static_cast<VString<sizeof(T) - 1>&>(rv) = iv; return rv; } +} // namespace tmwa -# include "vstring.tcc" - -#endif // TMWA_STRINGS_VSTRING_HPP +#include "vstring.tcc" diff --git a/src/strings/vstring.py b/src/strings/vstring.py index 39e657b..fa975b2 100644 --- a/src/strings/vstring.py +++ b/src/strings/vstring.py @@ -2,7 +2,7 @@ class VString(object): ''' print a VString ''' __slots__ = ('_value') - name = 'strings::VString' + name = 'tmwa::strings::VString' enabled = True def __init__(self, value): diff --git a/src/strings/vstring.tcc b/src/strings/vstring.tcc index 1aa163d..4f24a20 100644 --- a/src/strings/vstring.tcc +++ b/src/strings/vstring.tcc @@ -18,8 +18,8 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. #include <cassert> - -#include "../compat/cast.hpp" +#include <cstdarg> +#include <cstdio> #include "rstring.hpp" #include "astring.hpp" @@ -27,7 +27,11 @@ #include "sstring.hpp" #include "zstring.hpp" #include "xstring.hpp" +#include "literal.hpp" + +namespace tmwa +{ namespace strings { template<uint8_t n> @@ -76,11 +80,9 @@ namespace strings *this = XString(v); } template<uint8_t n> - template<size_t m> - VString<n>::VString(const char (&s)[m]) + VString<n>::VString(LString l) { - static_assert(m <= n + 1, "string would truncate"); - *this = XString(s); + *this = XString(l); } template<uint8_t n> VString<n>::VString(decltype(really_construct_from_a_pointer) e, const char *s) @@ -143,7 +145,8 @@ namespace strings char buffer[len + 1]; vsnprintf(buffer, len + 1, fmt, ap); - out = const_(buffer); + out = VString<len>(strings::really_construct_from_a_pointer, buffer); return len; } } // namespace strings +} // namespace tmwa diff --git a/src/strings/xstring.cpp b/src/strings/xstring.cpp index 0808104..4635a90 100644 --- a/src/strings/xstring.cpp +++ b/src/strings/xstring.cpp @@ -18,8 +18,18 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include "rstring.hpp" +#include "astring.hpp" +#include "tstring.hpp" +#include "sstring.hpp" +#include "zstring.hpp" +#include "literal.hpp" + #include "../poison.hpp" + +namespace tmwa +{ namespace strings { XString::XString() @@ -40,6 +50,9 @@ namespace strings XString::XString(const ZString& s) : _b(&*s.begin()), _e(&*s.end()), _base(s.base()) {} + XString::XString(const LString& s) + : _b(&*s.begin()), _e(&*s.end()), _base(s.base()) + {} XString::XString(const char *b, const char *e, const RString *base_) : _b(b), _e(e), _base(base_) @@ -65,3 +78,4 @@ namespace strings return _base; } } // namespace strings +} // namespace tmwa diff --git a/src/strings/xstring.hpp b/src/strings/xstring.hpp index 8f6eac5..2b000c4 100644 --- a/src/strings/xstring.hpp +++ b/src/strings/xstring.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_STRINGS_XSTRING_HPP -#define TMWA_STRINGS_XSTRING_HPP +#pragma once // strings/xstring.hpp - A full borrowed slice. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,10 +18,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include "base.hpp" +#include "base.hpp" + +namespace tmwa +{ namespace strings { /// A non-owning string that is not guaranteed to be NUL-terminated. @@ -44,10 +46,7 @@ namespace strings XString(const ZString& s); template<uint8_t n> XString(const VString<n>& s); - template<size_t n> - XString(char (&s)[n]) = delete; - template<size_t n> - XString(const char (&s)[n]); + XString(const LString& s); // mostly internal XString(const char *b, const char *e, const RString *base_); XString(decltype(really_construct_from_a_pointer) e, const char *s, const RString *base_); @@ -58,7 +57,6 @@ namespace strings const RString *base() const; }; } // namespace strings +} // namespace tmwa -# include "xstring.tcc" - -#endif // TMWA_STRINGS_XSTRING_HPP +#include "xstring.tcc" diff --git a/src/strings/xstring.py b/src/strings/xstring.py index 92cb78b..fa0abcb 100644 --- a/src/strings/xstring.py +++ b/src/strings/xstring.py @@ -2,7 +2,7 @@ class XString(object): ''' print a XString ''' __slots__ = ('_value') - name = 'strings::XString' + name = 'tmwa::strings::XString' enabled = True def __init__(self, value): diff --git a/src/strings/xstring.tcc b/src/strings/xstring.tcc index aee87f8..e9f0f1e 100644 --- a/src/strings/xstring.tcc +++ b/src/strings/xstring.tcc @@ -19,14 +19,14 @@ #include "vstring.hpp" + +namespace tmwa +{ namespace strings { template<uint8_t n> XString::XString(const VString<n>& s) : _b(&*s.begin()), _e(&*s.end()), _base(nullptr) {} - template<size_t n> - XString::XString(const char (&s)[n]) - : _b(s), _e(s + strlen(s)), _base(nullptr) - {} } // namespace strings +} // namespace tmwa diff --git a/src/strings/zstring.cpp b/src/strings/zstring.cpp index e2a763f..01e9c2b 100644 --- a/src/strings/zstring.cpp +++ b/src/strings/zstring.cpp @@ -18,15 +18,24 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include "xstring.hpp" +#include <cstdio> +#include <cstring> + +#include "rstring.hpp" +#include "astring.hpp" +#include "tstring.hpp" +#include "literal.hpp" #include "../poison.hpp" + +namespace tmwa +{ namespace strings { ZString::ZString() { - *this = ZString(""); + *this = ZString(""_s); } ZString::ZString(const RString& s) : _b(&*s.begin()), _e(&*s.end()), _base(s.base()) @@ -37,6 +46,9 @@ namespace strings ZString::ZString(const TString& s) : _b(&*s.begin()), _e(&*s.end()), _base(s.base()) {} + ZString::ZString(const LString& s) + : _b(&*s.begin()), _e(&*s.end()), _base(s.base()) + {} ZString::ZString(const char *b, const char *e, const RString *base_) : _b(b), _e(e), _base(base_) {} @@ -65,10 +77,5 @@ namespace strings { return zs.c_str(); } - - __attribute__((format(scanf, 2, 0))) - int do_vscan(ZString in, const char *fmt, va_list ap) - { - return vsscanf(in.c_str(), fmt, ap); - } } // namespace strings +} // namespace tmwa diff --git a/src/strings/zstring.hpp b/src/strings/zstring.hpp index 717da88..1e38662 100644 --- a/src/strings/zstring.hpp +++ b/src/strings/zstring.hpp @@ -1,5 +1,4 @@ -#ifndef TMWA_STRINGS_ZSTRING_HPP -#define TMWA_STRINGS_ZSTRING_HPP +#pragma once // strings/zstring.hpp - A borrowed tail slice of a string. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -19,12 +18,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -# include "../sanity.hpp" +#include "fwd.hpp" -# include <cstring> +#include "base.hpp" -# include "base.hpp" +namespace tmwa +{ namespace strings { /// A non-owning string that is guaranteed to be NUL-terminated. @@ -45,13 +45,10 @@ namespace strings ZString(const XString&) = delete; template<uint8_t n> ZString(const VString<n>& s); + ZString(const LString& s); // dangerous ZString(const char *b, const char *e, const RString *base_); ZString(decltype(really_construct_from_a_pointer), const char *s, const RString *base_); - template<size_t n> - ZString(char (&s)[n]) = delete; - template<size_t n> - ZString(const char (&s)[n], const RString *base_=nullptr); iterator begin() const; iterator end() const; @@ -64,11 +61,7 @@ namespace strings // Nope, it doesn't, since there's a template // Actually, it might now. const char *decay_for_printf(const ZString& zs); - - __attribute__((format(scanf, 2, 0))) - int do_vscan(ZString in, const char *fmt, va_list ap); } // namespace strings +} // namespace tmwa -# include "zstring.tcc" - -#endif // TMWA_STRINGS_ZSTRING_HPP +#include "zstring.tcc" diff --git a/src/strings/zstring.py b/src/strings/zstring.py index 5021e1c..dca5f4e 100644 --- a/src/strings/zstring.py +++ b/src/strings/zstring.py @@ -2,7 +2,7 @@ class ZString(object): ''' print a ZString ''' __slots__ = ('_value') - name = 'strings::ZString' + name = 'tmwa::strings::ZString' enabled = True def __init__(self, value): diff --git a/src/strings/zstring.tcc b/src/strings/zstring.tcc index fe0e9f3..2eaa8c0 100644 --- a/src/strings/zstring.tcc +++ b/src/strings/zstring.tcc @@ -17,19 +17,16 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include <cstring> - #include "vstring.hpp" + +namespace tmwa +{ namespace strings { template<uint8_t n> ZString::ZString(const VString<n>& s) : _b(&*s.begin()), _e(&*s.end()), _base(nullptr) {} - - template<size_t n> - ZString::ZString(const char (&s)[n], const RString *base_) - : _b(s), _e(s + strlen(s)), _base(base_) - {} } // namespace strings +} // namespace tmwa diff --git a/src/tests/fdhack.cpp b/src/tests/fdhack.cpp new file mode 100644 index 0000000..7a95431 --- /dev/null +++ b/src/tests/fdhack.cpp @@ -0,0 +1,26 @@ +#include "fdhack.hpp" +// fdhack.cpp - Move file descriptors around. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../poison.hpp" + + +namespace tmwa +{ +} // namespace tmwa diff --git a/src/tests/fdhack.hpp b/src/tests/fdhack.hpp new file mode 100644 index 0000000..c75bfea --- /dev/null +++ b/src/tests/fdhack.hpp @@ -0,0 +1,58 @@ +#pragma once +// fdhack.hpp - Move file descriptors around. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "fwd.hpp" + +#include <cstddef> +#include <fcntl.h> + +#include <stdexcept> + +#include "../strings/literal.hpp" +#include "../strings/zstring.hpp" + +#include "../io/fd.hpp" + +namespace tmwa +{ +class ReplaceFd +{ + io::FD number, backup; +public: + ReplaceFd(io::FD num, io::FD handle, bool owned) + : number(handle.dup2(num)), backup(num.dup()) + { + if (owned) + handle.close(); + } + ~ReplaceFd() + { + backup.dup2(number); + backup.close(); + } +}; +class QuietFd : ReplaceFd +{ +public: + QuietFd(io::FD num=io::FD::stderr()) + : ReplaceFd(num, io::FD::open("/dev/null"_s, O_RDONLY), true) + {} +}; +} // namespace tmwa diff --git a/src/tests/fwd.hpp b/src/tests/fwd.hpp new file mode 100644 index 0000000..48627da --- /dev/null +++ b/src/tests/fwd.hpp @@ -0,0 +1,27 @@ +#pragma once +// tests/fwd.hpp - list of type names for test libs +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "../sanity.hpp" + + +namespace tmwa +{ +// meh, add more when I feel like it +} // namespace tmwa diff --git a/src/tests/test.cpp b/src/tests/test.cpp index d9cba5e..d731d7c 100644 --- a/src/tests/test.cpp +++ b/src/tests/test.cpp @@ -1,4 +1,3 @@ -#include <gtest/gtest.h> // test.cpp - Driver for testwuite // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -18,8 +17,15 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. +#include <gtest/gtest.h> + #include "../poison.hpp" + +namespace tmwa +{ +} // namespace tmwa + int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/src/warnings.hpp b/src/warnings.hpp index 1ea0074..9389766 100644 --- a/src/warnings.hpp +++ b/src/warnings.hpp @@ -1,7 +1,7 @@ -// no include guards +#pragma once // This is the first file in every compilation, passed by the makefile. // This file contains only preprocessor directions. - +// The preceding sentence is a lie. // warnings.hpp - Make the compiler do the hard work. // // Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com> @@ -21,700 +21,170 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#if 0 -# include "../sanity.hpp" +// just mention "fwd.hpp" to make formatter happy + +#include "diagnostics.hpp" + + +namespace tmwa +{ +PRAGMA(GCC diagnostic warning "-Wall"); +PRAGMA(GCC diagnostic warning "-Wextra"); +PRAGMA(GCC diagnostic warning "-Wunused"); +PRAGMA(GCC diagnostic warning "-Wformat"); + +DIAG_E(abi); +DIAG_W(abi_tag); +DIAG_E(address); +DIAG_I(aggregate_return); +DIAG_E(array_bounds); +DIAG_E(attributes); +DIAG_E(builtin_macro_redefined); +DIAG_I(cxx0x_compat); +DIAG_I(cxx1y_extensions); +DIAG_E(cast_align); +DIAG_E(cast_qual); +DIAG_E(char_subscripts); +DIAG_E(clobbered); +DIAG_E(comment); +DIAG_E(conditionally_supported); +DIAG_E(constexpr_not_const); +DIAG_X(conversion); +DIAG_E(conversion_null); +DIAG_W(coverage_mismatch); +DIAG_X(covered_switch_default); +DIAG_W(cpp); +DIAG_E(ctor_dtor_privacy); +DIAG_E(date_time); +DIAG_E(delete_incomplete); +DIAG_E(delete_non_virtual_dtor); +DIAG_W(deprecated); +#ifdef QUIET +DIAG_I(deprecated_declarations); +#else +DIAG_W(deprecated_declarations); #endif - -// This file is currently targeted at: -// GCC 4.6 (incomplete due to bugs) -// GCC 4.7 (for few minor workarounds) -// GCC 4.8 (zarro boogs found) -// clang 3.1 (may ICE later) -// clang 3.2 (with a few major workarounds) - -// List of warnings that require arguments, -// and thus cannot reliably be activated: -// gcc 4.6: -// -Wlarger-than=<1024> -// -Wnormalized=<id|nfc|nfd> -// -Wsuggest-attribute=<noreturn,const,pure,format> -// gcc 4.7: -// -Wstack-usage=<8192> -// ??? -// -Wstrict-aliasing=<1> -// -Wstrict-overflow=<1> - -// options that enable other options -// only warnings so I can catch the errors -#pragma GCC diagnostic warning "-Wall" -#pragma GCC diagnostic warning "-Wextra" -#pragma GCC diagnostic warning "-Wunused" -#pragma GCC diagnostic warning "-Wformat" - -#ifdef __clang__ -# if __clang_major__ < 3 -# error "your clang is way too old" -# elif __clang_major__ == 3 -# if __clang_minor__ < 1 -# error "your clang is too old" -# endif // __clang_minor__ -# endif // __clang_major__ -#else // __clang__ -# if __GNUC__ < 4 -# error "your gcc is way too old" -# if __GNUC_MINOR__ < 6 -# error "your gcc is too old" -# elif __GNUC_MINOR__ == 6 -# if __GNUC_PATCHLEVEL__ < 3 -# error "TODO: test this patchlevel" -# endif // __GNUC_PATCHLEVEL__ -# elif __GNUC_MINOR__ == 7 -# if __GNUC_PATCHLEVEL__ < 2 -# error "your gcc has a known bad patchlevel" -# endif // __GNUC_PATCHLEVEL__ -# endif // __GNUC_MINOR__ -# endif // __GNUC__ -#endif // __clang__ - -// BEGIN Macros to make my life easier - -// stringification requirement - #sw within #ar -// this is a lie ^ -#define P(ar) _Pragma(#ar) - -// Use "GCC diagnostic" for warnings applicable to all versions. -#define I(sw) P(GCC diagnostic ignored sw) -#define W(sw) P(GCC diagnostic warning sw) -#define E(sw) P(GCC diagnostic error sw) -// configurable thing (also change in clang below!) -#define X(sw) I(sw) - - -#ifdef __clang__ - -// Use "clang diagnostic" for warnings specific to clang -# define IC(sw) P(clang diagnostic ignored sw) -# define WC(sw) P(clang diagnostic warning sw) -# define EC(sw) P(clang diagnostic error sw) -# define XC(sw) IC(sw) // this is below - -// warning specific to gcc -# define IG(sw) static_assert('I', sw "skipped for clang"); -# define WG(sw) static_assert('W', sw "skipped for clang"); -# define EG(sw) static_assert('E', sw "skipped for clang"); -# define XG(sw) static_assert('X', sw "skipped for clang"); - -# define IG47(sw) static_assert('I', sw "only for gcc 4.7+"); -# define WG47(sw) static_assert('W', sw "only for gcc 4.7+"); -# define EG47(sw) static_assert('E', sw "only for gcc 4.7+"); -# define XG47(sw) static_assert('X', sw "only for gcc 4.7+"); - -# define IG48(sw) static_assert('I', sw "only for gcc 4.8+"); -# define WG48(sw) static_assert('W', sw "only for gcc 4.8+"); -# define EG48(sw) static_assert('E', sw "only for gcc 4.8+"); -# define XG48(sw) static_assert('X', sw "only for gcc 4.8+"); - -# define I47(sw) I(sw) -# define W47(sw) W(sw) -# define E47(sw) E(sw) -# define X47(sw) X(sw) - -# define I48(sw) I(sw) -# define W48(sw) W(sw) -# define E48(sw) E(sw) -# define X48(sw) X(sw) - +DIAG_W(disabled_optimization); +DIAG_E(div_by_zero); +DIAG_W(documentation); +DIAG_I(double_promotion); +DIAG_I(effcxx); +DIAG_E(empty_body); +DIAG_E(endif_labels); +DIAG_E(enum_compare); +DIAG_E(extra_semi); +DIAG_E(float_equal); +DIAG_E(format); +DIAG_E(format_contains_nul); +DIAG_E(format_extra_args); +#if CLANG +DIAG_I(format_nonliteral); +DIAG_I(format_security); #else - -// warnings specific to clang -# define IC(sw) static_assert('I', sw "skipped for gcc"); -# define WC(sw) static_assert('W', sw "skipped for gcc"); -# define EC(sw) static_assert('E', sw "skipped for gcc"); -# define XC(sw) static_assert('X', sw "skipped for gcc"); - -// warnings specific to gcc -# define IG(sw) I(sw) -# define WG(sw) W(sw) -# define EG(sw) E(sw) -# define XG(sw) X(sw) - -// used both for warnings not implemented in a version -// and for warnings that falsely trigger -# if __GNUC__ == 4 -# if __GNUC_MINOR__ >= 7 -# define IG47(sw) IG(sw) -# define WG47(sw) WG(sw) -# define EG47(sw) EG(sw) -# define XG47(sw) XG(sw) - -# define I47(sw) I(sw) -# define W47(sw) W(sw) -# define E47(sw) E(sw) -# define X47(sw) X(sw) -# else -# define IG47(sw) static_assert('I', sw "only for gcc 4.7+"); -# define WG47(sw) static_assert('W', sw "only for gcc 4.7+"); -# define EG47(sw) static_assert('E', sw "only for gcc 4.7+"); -# define XG47(sw) static_assert('X', sw "only for gcc 4.7+"); - -# define I47(sw) static_assert('I', sw "only for gcc 4.7+ or clang"); -# define W47(sw) static_assert('W', sw "only for gcc 4.7+ or clang"); -# define E47(sw) static_assert('E', sw "only for gcc 4.7+ or clang"); -# define X47(sw) static_assert('X', sw "only for gcc 4.7+ or clang"); -# endif // __GNUC_MINOR__ -# if __GNUC_MINOR__ >= 8 -# define IG48(sw) IG(sw) -# define WG48(sw) WG(sw) -# define EG48(sw) EG(sw) -# define XG48(sw) XG(sw) - -# define I48(sw) IG(sw) -# define W48(sw) WG(sw) -# define E48(sw) EG(sw) -# define X48(sw) XG(sw) -# else -# define IG48(sw) static_assert('I', sw "only for gcc 4.8+"); -# define WG48(sw) static_assert('W', sw "only for gcc 4.8+"); -# define EG48(sw) static_assert('E', sw "only for gcc 4.8+"); -# define XG48(sw) static_assert('X', sw "only for gcc 4.8+"); - -# define I48(sw) static_assert('I', sw "only for gcc 4.8+ or clang"); -# define W48(sw) static_assert('W', sw "only for gcc 4.8+ or clang"); -# define E48(sw) static_assert('E', sw "only for gcc 4.8+ or clang"); -# define X48(sw) static_assert('X', sw "only for gcc 4.8+ or clang"); -# endif // __GNUC_MINOR__ -# endif // __GNUC__ -#endif // __clang__ - -// END macros to make my life easier - - -/// Warn about things that will change when compiling -/// with an ABI-compliant compiler -// see note about -fabi-version=6 in the makefile -E("-Wabi") - -/// Warn if a subobject has an abi_tag attribute that -/// the complete object type does not have -WG48("-Wabi-tag") - -/// Warn about suspicious uses of memory addresses -E("-Waddress") - -/// Warn about returning structures, unions or arrays -I("-Waggregate-return") - -/// Warn if an array is accessed out of bounds -E("-Warray-bounds") - -/// Warn about inappropriate attribute usage -E("-Wattributes") - -/// Warn when a built-in preprocessor macro is -// undefined or redefined -E("-Wbuiltin-macro-redefined") - -/// Warn about C++ constructs whose meaning differs -/// between ISO C++ 1998 and ISO C++ 2011 -// This has gone funky lately. It probably doesn't do anything useful anyway. -//E("-Wc++0x-compat") -//W("-Wc++11-compat") -I("-Wc++0x-compat") - -/// Warn about pointer casts which increase alignment -X("-Wcast-align") - -/// Warn about casts which discard qualifiers -E("-Wcast-qual") - -/// Warn about subscripts whose type is "char" -E("-Wchar-subscripts") - -/// Warn about variables that might be changed by -/// "longjmp" or "vfork" -EG("-Wclobbered") - -/// Warn about possibly nested block comments, and -/// C++ comments spanning more than one physical line -E("-Wcomment") - -// A fixable difference between c++11 and c++14 -#ifdef __clang__ -# if __has_warning("-Wconstexpr-not-const") -EC("-Wconstexpr-not-const") -# else -static_assert('E', "-Wconstexpr-not-const not in this clang version"); -# endif +DIAG_E(format_nonliteral); +DIAG_E(format_security); +#endif +DIAG_E(format_y2k); +DIAG_I(format_zero_length); +DIAG_E(free_nonheap_object); +DIAG_E(gnu_designator); +DIAG_E(ignored_qualifiers); +DIAG_E(implicit_fallthrough); +DIAG_W(inherited_variadic_ctor); +DIAG_E(init_self); +DIAG_X(inline); +DIAG_E(int_to_pointer_cast); +DIAG_W(invalid_memory_model); +DIAG_E(invalid_offsetof); +DIAG_E(invalid_pch); +DIAG_W(literal_suffix); +DIAG_W(logical_op); +DIAG_I(long_long); +DIAG_E(main); +DIAG_E(maybe_uninitialized); +DIAG_I(mismatched_tags); +DIAG_E(missing_braces); +DIAG_E(missing_declarations); +#if GCC +DIAG_I(missing_field_initializers); #else -static_assert('E', "-Wconstexpr-not-const not in GCC"); +DIAG_E(missing_field_initializers); #endif - -/// Warn for implicit type conversions that may -/// change a value -X("-Wconversion") - -/// Warn for converting NULL from/to a non-pointer -/// type -E("-Wconversion-null") - -/// Warn in case profiles in -fprofile-use do not -/// match -WG("-Wcoverage-mismatch") - -/// -XC("-Wcovered-switch-default") - -/// Warn when a #warning directive is encountered -WG("-Wcpp") - -/// Warn when all constructors and destructors are -/// private -E("-Wctor-dtor-privacy") - -/// Warn about deleting polymorphic objects with non- -/// virtual destructors -E47("-Wdelete-non-virtual-dtor") - -/// Warn if a deprecated compiler feature, class, -/// method, or field is used -W("-Wdeprecated") - -/// Warn about uses of __attribute__((deprecated)") -/// declarations -W("-Wdeprecated-declarations") -#ifdef QUIET -I("-Wdeprecated-declarations") +DIAG_E(missing_format_attribute); +DIAG_E(missing_include_dirs); +DIAG_W(missing_noreturn); +DIAG_E(missing_prototypes); +#ifndef GTEST_HAS_PTHREAD // this is a hack +DIAG_E(missing_variable_declarations); +#else +DIAG_I(missing_variable_declarations); #endif - -/// Warn when an optimization pass is disabled -W("-Wdisabled-optimization") - -/// Warn about compile-time integer division by zero -E("-Wdiv-by-zero") - -/// -WC("-Wdocumentation") - -/// Warn about implicit conversions from "float" to -/// "double" -IG("-Wdouble-promotion") - -/// Warn about violations of Effective C++ style rules -I("-Weffc++") - -/// Warn about an empty body in an if or else -/// statement -E("-Wempty-body") - -/// Warn about stray tokens after #elif and #endif -E("-Wendif-labels") - -/// Warn about comparison of different enum types -E("-Wenum-compare") - -/// -EC("-Wextra-semi") - -/// Warn if testing floating point numbers for -/// equality -E("-Wfloat-equal") - -/// Warn about printf/scanf/strftime/strfmon format -/// string anomalies -// see below -EG("-Wformat") -// but gcc 4.8 warns on %ms, since we enabled -Wpedantic. -//WG48("-Wformat") - -/// Warn about format strings that contain NUL bytes -EG("-Wformat-contains-nul") - -/// Warn if passing too many arguments to a function -/// for its format string -E("-Wformat-extra-args") - -/// Warn about format strings that are not literals -EG("-Wformat-nonliteral") -// Available in clang, but not smart enough to handle constexpr. -IC("-Wformat-nonliteral") - -/// Warn about possible security problems with format -/// functions -EG("-Wformat-security") -// Same. -IC("-Wformat-security") - -/// Warn about strftime formats yielding 2-digit years -E("-Wformat-y2k") - -/// Warn about zero-length formats -I("-Wformat-zero-length") - -/// Warn when attempting to free a non-heap object -EG47("-Wfree-nonheap-object") - -// -Wgnu is a clang alias for -Wpedantic - -/// Warn whenever type qualifiers are ignored. -E("-Wignored-qualifiers") - -/// -EC("-Wimplicit-fallthrough") - -/// Warn about C++11 inheriting constructors when the -/// base has a variadic constructor -WG48("-Winherited-variadic-ctor") - -/// Warn about variables which are initialized to -/// themselves -E("-Winit-self") - -/// Warn when an inlined function cannot be inlined -X("-Winline") - -/// Warn when there is a cast to a pointer from an -/// integer of a different size -E("-Wint-to-pointer-cast") - -/// Warn when an atomic memory model parameter is -/// known to be outside the valid range. -WG47("-Winvalid-memory-model") - -/// Warn about invalid uses of the "offsetof" macro -E("-Winvalid-offsetof") - -/// Warn about PCH files that are found but not used -E("-Winvalid-pch") - -/// Warn when a string or character literal is -/// followed by a ud-suffix which does not begin with -/// an underscore. -WG48("-Wliteral-suffix") - -/// Warn when a logical operator is suspiciously -/// always evaluating to true or false -WG("-Wlogical-op") - -/// Do not warn about using "long long" when -pedantic -I("-Wlong-long") - -/// Warn about suspicious declarations of "main" -E("-Wmain") - -/// Warn about maybe uninitialized automatic variables -EG47("-Wmaybe-uninitialized") - -/// Warn about possibly missing braces around -/// initializers -// beware of things like std::array! -E("-Wmissing-braces") - -/// Warn about global functions without previous -/// declarations -// This doesn't work for clang, it wants -Wmissing-prototypes instead. -E("-Wmissing-declarations") - -/// Warn about missing fields in struct initializers -// Actually supported by GCC, but gives warnings when I don't want, e.g.: -// Foo foo = {}; -EC("-Wmissing-field-initializers") -IG("-Wmissing-field-initializers") - -/// Warn about functions which might be candidates -/// for format attributes -E("-Wmissing-format-attribute") - -/// Warn about user-specified include directories -/// that do not exist -E("-Wmissing-include-dirs") - -/// Warn about functions which might be candidates -/// for __attribute__((noreturn)") -W("-Wmissing-noreturn") - -// clang uses this instead of -Wmissing-declarations -EC("-Wmissing-prototypes") - -/// -// like -Wmissing-declarations but for variables instead of functions +DIAG_E(mudflap); +DIAG_E(multichar); +DIAG_E(narrowing); +DIAG_W(noexcept); +DIAG_E(non_template_friend); +DIAG_E(non_virtual_dtor); +DIAG_E(nonnull); +DIAG_E(null_conversion); +DIAG_E(old_style_cast); +DIAG_W(overflow); +DIAG_E(openmp_simd); +DIAG_E(overloaded_virtual); +DIAG_E(packed); +DIAG_W(packed_bitfield_compat); +DIAG_I(padded); +DIAG_E(parentheses); +DIAG_I(pedantic); +DIAG_E(pmf_conversions); +DIAG_E(pointer_arith); +DIAG_E(pragmas); +DIAG_W(redundant_decls); +DIAG_E(reorder); +DIAG_W(return_local_addr); +DIAG_E(return_type); +DIAG_E(sequence_point); +DIAG_E(shadow); +DIAG_X(sign_compare); +DIAG_E(sign_promo); +DIAG_W(sizeof_pointer_memaccess); +DIAG_X(stack_protector); +DIAG_E(strict_aliasing); +DIAG_W(strict_null_sentinel); +DIAG_X(strict_overflow); +DIAG_I(switch); +DIAG_I(switch_default); +DIAG_I(switch_enum); +DIAG_W(sync_nand); +DIAG_E(trampolines); +DIAG_E(trigraphs); +DIAG_E(type_limits); +DIAG_E(undef); +DIAG_E(uninitialized); +DIAG_E(unknown_pragmas); +DIAG_W(unreachable_code); +DIAG_X(unsafe_loop_optimizations); +DIAG_E(unused_but_set_parameter); +DIAG_E(unused_but_set_variable); +DIAG_E(unused_function); +DIAG_E(unused_label); +DIAG_E(unused_local_typedefs); +DIAG_W(unused_macros); +DIAG_E(unused_parameter); +DIAG_E(unused_result); +DIAG_E(unused_value); +DIAG_E(unused_variable); +DIAG_E(useless_cast); +DIAG_E(varargs); +DIAG_W(variadic_macros); +DIAG_W(vector_operation_performance); +DIAG_E(virtual_move_assign); +DIAG_I(vla); +DIAG_E(volatile_register_var); +DIAG_E(write_strings); #ifndef GTEST_HAS_PTHREAD // this is a hack -EC("-Wmissing-variable-declarations") +DIAG_E(zero_as_null_pointer_constant); +#else +DIAG_I(zero_as_null_pointer_constant); #endif - -/// Warn about constructs not instrumented by -/// -fmudflap -EG("-Wmudflap") - -/// Warn about use of multi-character character -/// constants -E("-Wmultichar") - -/// Warn about narrowing conversions within { } that -/// are ill-formed in C++11 -EG47("-Wnarrowing") - -/// Warn when a noexcept expression evaluates to -/// false even though the expression can't actually -/// throw -WG("-Wnoexcept") - -/// Warn when non-templatized friend functions are -/// declared within a template -EG("-Wnon-template-friend") - -/// Warn about non-virtual destructors -E("-Wnon-virtual-dtor") - -/// Warn about NULL being passed to argument slots -/// marked as requiring non-NULL -E("-Wnonnull") - -/// -XC("-Wnull-conversion") - -/// Warn if a C-style cast is used in a program -E("-Wold-style-cast") - -/// Warn about overflow in arithmetic expressions -W("-Woverflow") - -/// Warn if a string is longer than the maximum -/// portable length specified by the standard -//X("-Woverlength-strings") - -/// Warn about overloaded virtual function names -E("-Woverloaded-virtual") - -/// Warn when the packed attribute has no effect on -/// struct layout -E("-Wpacked") - -/// Warn about packed bit-fields whose offset changed -/// in GCC 4.4 -WG("-Wpacked-bitfield-compat") - -/// Warn when padding is required to align structure -/// members -I("-Wpadded") - -/// Warn about possibly missing parentheses -E("-Wparentheses") - -/// Issue warnings needed for strict compliance to -/// the standard -//EG48("-Wpedantic") -// lots of minor extensions are used -IG48("-Wpedantic") -// a bit too noisy -XC("-Wpedantic") - -/// Warn when converting the type of pointers to -/// member functions -EG("-Wpmf-conversions") - -/// Warn about function pointer arithmetic -E("-Wpointer-arith") - -/// Warn about misuses of pragmas -EG("-Wpragmas") - -/// Warn about multiple declarations of the same -/// object -W("-Wredundant-decls") - -/// Warn when the compiler reorders code -E("-Wreorder") - -/// Warn about returning a pointer/reference to a -/// local or temporary variable. -WG48("-Wreturn-local-addr") - -/// Warn whenever a function's return type defaults -/// to "int" (C), or about inconsistent return types -/// (C++") -E("-Wreturn-type") - -/// Warn about possible violations of sequence point -/// rules -E("-Wsequence-point") - -/// Warn when one local variable shadows another -E("-Wshadow") - -/// Warn about signed-unsigned comparisons -X("-Wsign-compare") - -/// Warn when overload promotes from unsigned to -/// signed -X("-Wsign-promo") - -/// This switch lacks documentation -WG48("-Wsizeof-pointer-memaccess") - -/// Warn when not issuing stack smashing protection -/// for some reason -X("-Wstack-protector") - -/// Warn about code which might break strict aliasing -/// rules -E("-Wstrict-aliasing") - -/// Warn about uncasted NULL used as sentinel -WG("-Wstrict-null-sentinel") - -/// Warn about optimizations that assume that signed -/// overflow is undefined -X("-Wstrict-overflow") - -/// Warn about enumerated switches, with no default, -/// missing a case -X("-Wswitch") - -/// Warn about enumerated switches missing a -/// "default:" statement -X("-Wswitch-default") - -/// Warn about all enumerated switches missing a -/// specific case -X("-Wswitch-enum") - -/// Warn when __sync_fetch_and_nand and -/// __sync_nand_and_fetch built-in functions are used -WG("-Wsync-nand") - -/// Warn whenever a trampoline is generated -EG("-Wtrampolines") - -/// Warn if trigraphs are encountered that might -/// affect the meaning of the program -E("-Wtrigraphs") - -/// Warn if a comparison is always true or always -/// false due to the limited range of the data type -E("-Wtype-limits") - -/// Warn if an undefined macro is used in an #if -/// directive -E("-Wundef") - -/// Warn about uninitialized automatic variables -E("-Wuninitialized") - -/// Warn about unrecognized pragmas -E("-Wunknown-pragmas") - -/// -// Not an error because of some remaining enum+default -WC("-Wunreachable-code") - -/// Warn if the loop cannot be optimized due to -/// nontrivial assumptions. -XG("-Wunsafe-loop-optimizations") - -/// Warn when a function parameter is only set, -/// otherwise unused -EG("-Wunused-but-set-parameter") - -/// Warn when a variable is only set, otherwise unused -EG("-Wunused-but-set-variable") - -/// Warn when a function is unused -E("-Wunused-function") - -/// Warn when a label is unused -E("-Wunused-label") - -/// Warn when typedefs locally defined in a function -/// are not used -EG47("-Wunused-local-typedefs") - -/// Warn about macros defined in the main file that -/// are not used -W("-Wunused-macros") - -/// Warn when a function parameter is unused -E("-Wunused-parameter") - -/// Warn if a caller of a function, marked with -/// attribute warn_unused_result, does not use its -/// return value -E("-Wunused-result") - -/// Warn when an expression value is unused -E("-Wunused-value") - -/// Warn when a variable is unused -E("-Wunused-variable") - -/// Warn about useless casts -EG48("-Wuseless-cast") - -/// Warn about questionable usage of the macros used -/// to retrieve variable arguments -EG48("-Wvarargs") - -/// Warn about using variadic macros -W("-Wvariadic-macros") - -/// Warn when a vector operation is compiled -/// outside the SIMD -WG47("-Wvector-operation-performance") - -/// Warn if a virtual base has a non-trivial move -/// assignment operator -EG48("-Wvirtual-move-assign") - -/// Warn if a variable length array is used -I("-Wvla") - -/// Warn when a register variable is declared volatile -E("-Wvolatile-register-var") - -/// In C++, nonzero means warn about deprecated -/// conversion from string literals to 'char *'. In -/// C, similar warning, except that the conversion is -/// of course not deprecated by the ISO C standard. -E("-Wwrite-strings") - -/// Warn when a literal '0' is used as null -/// pointer -XG47("-Wzero-as-null-pointer-constant") - - -// clean up after myself -#undef P - -#undef I -#undef W -#undef E -#undef X - -#undef IC -#undef WC -#undef EC -#undef XC - -#undef IG -#undef WG -#undef EG -#undef XG - -#undef IG47 -#undef WG47 -#undef EG47 -#undef XG47 - -#undef IG48 -#undef WG48 -#undef EG48 -#undef XG48 - -#undef I47 -#undef W47 -#undef E47 -#undef X47 - -#undef I48 -#undef W48 -#undef E48 -#undef X48 +} // namespace tmwa |