summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/admin/fwd.hpp27
-rw-r--r--src/admin/ladmin.cpp2119
-rw-r--r--src/admin/ladmin.hpp10
-rw-r--r--src/admin/main.cpp8
-rw-r--r--src/char/char.cpp2138
-rw-r--r--src/char/char.hpp28
-rw-r--r--src/char/fwd.hpp27
-rw-r--r--src/char/int_party.cpp530
-rw-r--r--src/char/int_party.hpp21
-rw-r--r--src/char/int_storage.cpp133
-rw-r--r--src/char/int_storage.hpp23
-rw-r--r--src/char/inter.cpp348
-rw-r--r--src/char/inter.hpp19
-rw-r--r--src/char/main.cpp8
-rw-r--r--src/compat/attr.hpp20
-rw-r--r--src/compat/cast.cpp5
-rw-r--r--src/compat/cast.hpp14
-rw-r--r--src/compat/fun.hpp14
-rw-r--r--src/compat/fwd.hpp27
-rw-r--r--src/compat/iter.cpp5
-rw-r--r--src/compat/iter.hpp66
-rw-r--r--src/compat/iter_test.cpp65
-rw-r--r--src/compat/memory.cpp5
-rw-r--r--src/compat/memory.hpp13
-rw-r--r--src/compat/nullpo.cpp4
-rw-r--r--src/compat/nullpo.hpp29
-rw-r--r--src/compat/rawmem.cpp5
-rw-r--r--src/compat/rawmem.hpp17
-rw-r--r--src/compat/time_t.cpp26
-rw-r--r--src/compat/time_t.hpp29
-rw-r--r--src/conf/install.hpp30
-rw-r--r--src/conf/version.hpp30
-rw-r--r--src/diagnostics.hpp1251
-rw-r--r--src/generic/array.cpp (renamed from src/spell-convert/main.cpp)12
-rw-r--r--src/generic/array.hpp118
-rw-r--r--src/generic/array_test.cpp162
-rw-r--r--src/generic/db.cpp5
-rw-r--r--src/generic/db.hpp15
-rw-r--r--src/generic/dumb_ptr.cpp (renamed from src/mmo/dumb_ptr.cpp)5
-rw-r--r--src/generic/dumb_ptr.hpp (renamed from src/mmo/dumb_ptr.hpp)34
-rw-r--r--src/generic/enum.cpp5
-rw-r--r--src/generic/enum.hpp82
-rw-r--r--src/generic/fwd.hpp30
-rw-r--r--src/generic/intern-pool.cpp5
-rw-r--r--src/generic/intern-pool.hpp24
-rw-r--r--src/generic/intern-pool_test.cpp22
-rw-r--r--src/generic/matrix.cpp5
-rw-r--r--src/generic/matrix.hpp15
-rw-r--r--src/generic/md5.cpp9
-rw-r--r--src/generic/md5.hpp21
-rw-r--r--src/generic/md5_test.cpp18
-rw-r--r--src/generic/oops.cpp48
-rw-r--r--src/generic/oops.hpp40
-rw-r--r--src/generic/oops_test.cpp54
-rw-r--r--src/generic/operators.cpp5
-rw-r--r--src/generic/operators.hpp11
-rw-r--r--src/generic/random.cpp4
-rw-r--r--src/generic/random.hpp15
-rw-r--r--src/generic/random.t.hpp11
-rw-r--r--src/generic/random2.hpp17
-rw-r--r--src/ints/cmp.cpp26
-rw-r--r--src/ints/cmp.hpp71
-rw-r--r--src/ints/cmp_test.cpp1465
-rw-r--r--src/ints/fwd.hpp27
-rw-r--r--src/ints/little.cpp26
-rw-r--r--src/ints/little.hpp210
-rw-r--r--src/ints/udl.cpp26
-rw-r--r--src/ints/udl.hpp227
-rw-r--r--src/ints/udl_test.cpp788
-rw-r--r--src/ints/wrap.cpp26
-rw-r--r--src/ints/wrap.hpp110
-rw-r--r--src/io/cxxstdio.cpp7
-rw-r--r--src/io/cxxstdio.hpp133
-rw-r--r--src/io/dir.cpp54
-rw-r--r--src/io/dir.hpp50
-rw-r--r--src/io/fd.cpp8
-rw-r--r--src/io/fd.hpp44
-rw-r--r--src/io/fwd.hpp10
-rw-r--r--src/io/line.cpp43
-rw-r--r--src/io/line.hpp31
-rw-r--r--src/io/line_test.cpp207
-rw-r--r--src/io/lock.cpp23
-rw-r--r--src/io/lock.hpp14
-rw-r--r--src/io/read.cpp15
-rw-r--r--src/io/read.hpp17
-rw-r--r--src/io/read_test.cpp26
-rw-r--r--src/io/tty.cpp4
-rw-r--r--src/io/tty.hpp30
-rw-r--r--src/io/write.cpp15
-rw-r--r--src/io/write.hpp21
-rw-r--r--src/io/write_test.cpp23
-rw-r--r--src/login/fwd.hpp27
-rw-r--r--src/login/login.cpp2899
-rw-r--r--src/login/login.hpp12
-rw-r--r--src/login/login.t.hpp (renamed from src/map/magic-interpreter-aux.hpp)31
-rw-r--r--src/login/main.cpp8
-rw-r--r--src/main-gdb-head.py8
-rw-r--r--src/map/atcommand.cpp1894
-rw-r--r--src/map/atcommand.hpp21
-rw-r--r--src/map/battle.cpp270
-rw-r--r--src/map/battle.hpp33
-rw-r--r--src/map/battle.t.hpp31
-rw-r--r--src/map/chrif.cpp773
-rw-r--r--src/map/chrif.hpp29
-rw-r--r--src/map/clif.cpp4498
-rw-r--r--src/map/clif.hpp97
-rw-r--r--src/map/clif.t.hpp684
-rw-r--r--src/map/fwd.hpp57
-rw-r--r--src/map/grfio.cpp18
-rw-r--r--src/map/grfio.hpp19
-rw-r--r--src/map/intif.cpp650
-rw-r--r--src/map/intif.hpp39
-rw-r--r--src/map/itemdb.cpp50
-rw-r--r--src/map/itemdb.hpp41
-rw-r--r--src/map/magic-expr-eval.cpp5
-rw-r--r--src/map/magic-expr-eval.hpp68
-rw-r--r--src/map/magic-expr.cpp312
-rw-r--r--src/map/magic-expr.hpp53
-rw-r--r--src/map/magic-interpreter-base.cpp92
-rw-r--r--src/map/magic-interpreter-base.hpp75
-rw-r--r--src/map/magic-interpreter.cpp7
-rw-r--r--src/map/magic-interpreter.hpp122
-rw-r--r--src/map/magic-interpreter.py14
-rw-r--r--src/map/magic-interpreter.t.hpp45
-rw-r--r--src/map/magic-stmt.cpp270
-rw-r--r--src/map/magic-stmt.hpp79
-rw-r--r--src/map/magic-v2.cpp367
-rw-r--r--src/map/magic-v2.hpp13
-rw-r--r--src/map/magic.cpp28
-rw-r--r--src/map/magic.hpp76
-rw-r--r--src/map/main.cpp8
-rw-r--r--src/map/map.cpp324
-rw-r--r--src/map/map.hpp186
-rw-r--r--src/map/map.t.hpp415
-rw-r--r--src/map/mapflag.cpp68
-rw-r--r--src/map/mapflag.hpp15
-rw-r--r--src/map/mapflag.py2
-rw-r--r--src/map/mob.cpp788
-rw-r--r--src/map/mob.hpp79
-rw-r--r--src/map/mob.t.hpp13
-rw-r--r--src/map/npc.cpp338
-rw-r--r--src/map/npc.hpp58
-rw-r--r--src/map/party.cpp285
-rw-r--r--src/map/party.hpp57
-rw-r--r--src/map/path.cpp29
-rw-r--r--src/map/path.hpp11
-rw-r--r--src/map/pc.cpp828
-rw-r--r--src/map/pc.hpp67
-rw-r--r--src/map/pc.t.hpp26
-rw-r--r--src/map/script.cpp912
-rw-r--r--src/map/script.hpp38
-rw-r--r--src/map/script.py4
-rw-r--r--src/map/skill-pools.cpp13
-rw-r--r--src/map/skill-pools.hpp10
-rw-r--r--src/map/skill.cpp214
-rw-r--r--src/map/skill.hpp34
-rw-r--r--src/map/skill.t.hpp15
-rw-r--r--src/map/storage.cpp120
-rw-r--r--src/map/storage.hpp29
-rw-r--r--src/map/tmw.cpp27
-rw-r--r--src/map/tmw.hpp15
-rw-r--r--src/map/trade.cpp120
-rw-r--r--src/map/trade.hpp19
-rw-r--r--src/mmo/config_parse.cpp24
-rw-r--r--src/mmo/config_parse.hpp13
-rw-r--r--src/mmo/consts.cpp26
-rw-r--r--src/mmo/consts.hpp66
-rw-r--r--src/mmo/core.cpp54
-rw-r--r--src/mmo/core.hpp15
-rw-r--r--src/mmo/enums.cpp26
-rw-r--r--src/mmo/enums.hpp162
-rw-r--r--src/mmo/extract.cpp48
-rw-r--r--src/mmo/extract.hpp68
-rw-r--r--src/mmo/extract_test.cpp384
-rw-r--r--src/mmo/fwd.hpp68
-rw-r--r--src/mmo/human_time_diff.cpp5
-rw-r--r--src/mmo/human_time_diff.hpp31
-rw-r--r--src/mmo/human_time_diff_test.cpp38
-rw-r--r--src/mmo/ids.cpp26
-rw-r--r--src/mmo/ids.hpp168
-rw-r--r--src/mmo/ip_test.cpp352
-rw-r--r--src/mmo/md5more.cpp15
-rw-r--r--src/mmo/md5more.hpp18
-rw-r--r--src/mmo/mmo.cpp5
-rw-r--r--src/mmo/mmo.hpp380
-rw-r--r--src/mmo/socket.hpp424
-rw-r--r--src/mmo/strs.cpp (renamed from src/map/magic-interpreter-aux.cpp)9
-rw-r--r--src/mmo/strs.hpp126
-rw-r--r--src/mmo/utils.cpp28
-rw-r--r--src/mmo/utils.hpp68
-rw-r--r--src/mmo/version.cpp6
-rw-r--r--src/mmo/version.hpp86
-rw-r--r--src/monitor/main.cpp71
-rw-r--r--src/net/fwd.hpp33
-rw-r--r--src/net/ip.cpp (renamed from src/mmo/ip.cpp)10
-rw-r--r--src/net/ip.hpp (renamed from src/mmo/ip.hpp)18
-rw-r--r--src/net/ip.py (renamed from src/mmo/ip.py)2
-rw-r--r--src/net/ip_test.cpp359
-rw-r--r--src/net/packets.cpp106
-rw-r--r--src/net/packets.hpp585
-rw-r--r--src/net/socket.cpp (renamed from src/mmo/socket.cpp)91
-rw-r--r--src/net/socket.hpp177
-rw-r--r--src/net/timer.cpp (renamed from src/mmo/timer.cpp)20
-rw-r--r--src/net/timer.hpp (renamed from src/mmo/timer.hpp)15
-rw-r--r--src/net/timer.t.hpp (renamed from src/mmo/timer.t.hpp)92
-rw-r--r--src/poison.hpp25
-rw-r--r--src/proto2/any-user.hpp214
-rw-r--r--src/proto2/any-user_test.cpp27
-rw-r--r--src/proto2/char-map.hpp3498
-rw-r--r--src/proto2/char-map_test.cpp27
-rw-r--r--src/proto2/char-user.hpp622
-rw-r--r--src/proto2/char-user_test.cpp27
-rw-r--r--src/proto2/fwd.hpp1713
-rw-r--r--src/proto2/include_clif_t_test.cpp41
-rw-r--r--src/proto2/include_consts_test.cpp26
-rw-r--r--src/proto2/include_cstdint_test.cpp33
-rw-r--r--src/proto2/include_enums_test.cpp29
-rw-r--r--src/proto2/include_human_time_diff_test.cpp26
-rw-r--r--src/proto2/include_ids_test.cpp32
-rw-r--r--src/proto2/include_ip_test.cpp26
-rw-r--r--src/proto2/include_little_test.cpp29
-rw-r--r--src/proto2/include_login_t_test.cpp26
-rw-r--r--src/proto2/include_skill_t_test.cpp28
-rw-r--r--src/proto2/include_strs_test.cpp33
-rw-r--r--src/proto2/include_timer_t_test.cpp27
-rw-r--r--src/proto2/include_utils_test.cpp28
-rw-r--r--src/proto2/include_version_test.cpp26
-rw-r--r--src/proto2/include_vstring_test.cpp30
-rw-r--r--src/proto2/login-admin.hpp2218
-rw-r--r--src/proto2/login-admin_test.cpp27
-rw-r--r--src/proto2/login-char.hpp1192
-rw-r--r--src/proto2/login-char_test.cpp27
-rw-r--r--src/proto2/login-user.hpp325
-rw-r--r--src/proto2/login-user_test.cpp27
-rw-r--r--src/proto2/map-user.hpp7931
-rw-r--r--src/proto2/map-user_test.cpp27
-rw-r--r--src/proto2/types.hpp1421
-rw-r--r--src/range/fwd.hpp29
-rw-r--r--src/range/slice.cpp5
-rw-r--r--src/range/slice.hpp18
-rw-r--r--src/range/slice.tcc6
-rw-r--r--src/range/slice_test.cpp4
-rw-r--r--src/sanity.hpp44
-rw-r--r--src/sexpr/bind.cpp (renamed from src/compat/alg.cpp)12
-rw-r--r--src/sexpr/bind.hpp48
-rw-r--r--src/sexpr/fwd.hpp27
-rw-r--r--src/sexpr/lexer.cpp66
-rw-r--r--src/sexpr/lexer.hpp26
-rw-r--r--src/sexpr/lexer_test.cpp93
-rw-r--r--src/sexpr/main.cpp148
-rw-r--r--src/sexpr/parser.cpp9
-rw-r--r--src/sexpr/parser.hpp21
-rw-r--r--src/sexpr/parser.py2
-rw-r--r--src/sexpr/parser_test.cpp40
-rw-r--r--src/sexpr/union.cpp44
-rw-r--r--src/sexpr/union.hpp105
-rw-r--r--src/sexpr/variant.cpp (renamed from src/compat/alg.hpp)35
-rw-r--r--src/sexpr/variant.hpp116
-rw-r--r--src/sexpr/variant.tcc293
-rw-r--r--src/sexpr/variant_test.cpp123
-rw-r--r--src/sexpr/void.cpp29
-rw-r--r--src/sexpr/void.hpp40
-rw-r--r--src/shared/lib.cpp80
-rw-r--r--src/spell-convert/ast.cpp280
-rw-r--r--src/spell-convert/ast.hpp465
-rw-r--r--src/spell-convert/lexer.cpp2331
-rw-r--r--src/spell-convert/lexer.hpp335
-rw-r--r--src/spell-convert/lexer.lpp136
-rw-r--r--src/spell-convert/parser.cpp2732
-rw-r--r--src/spell-convert/parser.hpp152
-rw-r--r--src/spell-convert/parser.ypp902
-rw-r--r--src/strings/all.hpp29
-rw-r--r--src/strings/astring.cpp43
-rw-r--r--src/strings/astring.hpp40
-rw-r--r--src/strings/astring.py2
-rw-r--r--src/strings/astring.tcc21
-rw-r--r--src/strings/base.hpp19
-rw-r--r--src/strings/base.tcc6
-rw-r--r--src/strings/base_test.cpp11
-rw-r--r--src/strings/fwd.hpp25
-rw-r--r--src/strings/literal.cpp56
-rw-r--r--src/strings/literal.hpp79
-rw-r--r--src/strings/mstring.cpp4
-rw-r--r--src/strings/mstring.hpp13
-rw-r--r--src/strings/pair.hpp34
-rw-r--r--src/strings/rstring.cpp17
-rw-r--r--src/strings/rstring.hpp25
-rw-r--r--src/strings/rstring.py2
-rw-r--r--src/strings/rstring.tcc10
-rw-r--r--src/strings/sstring.cpp11
-rw-r--r--src/strings/sstring.hpp22
-rw-r--r--src/strings/sstring.tcc9
-rw-r--r--src/strings/strings2_test.cpp94
-rw-r--r--src/strings/strings_test.cpp67
-rw-r--r--src/strings/tstring.cpp11
-rw-r--r--src/strings/tstring.hpp22
-rw-r--r--src/strings/tstring.tcc8
-rw-r--r--src/strings/vstring.cpp4
-rw-r--r--src/strings/vstring.hpp22
-rw-r--r--src/strings/vstring.py2
-rw-r--r--src/strings/vstring.tcc17
-rw-r--r--src/strings/xstring.cpp14
-rw-r--r--src/strings/xstring.hpp20
-rw-r--r--src/strings/xstring.py2
-rw-r--r--src/strings/xstring.tcc8
-rw-r--r--src/strings/zstring.cpp23
-rw-r--r--src/strings/zstring.hpp23
-rw-r--r--src/strings/zstring.py2
-rw-r--r--src/strings/zstring.tcc11
-rw-r--r--src/tests/fdhack.cpp26
-rw-r--r--src/tests/fdhack.hpp58
-rw-r--r--src/tests/fwd.hpp27
-rw-r--r--src/tests/test.cpp8
-rw-r--r--src/warnings.hpp854
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, &timestamp);
- 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, &timestamp);
- 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, &timestamp);
- 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, &timestamp);
- 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, "&amp;");
+ FPRINTF(fp2, "&amp;"_fmt);
break;
case '<':
- FPRINTF(fp2, "&lt;");
+ FPRINTF(fp2, "&lt;"_fmt);
break;
case '>':
- FPRINTF(fp2, "&gt;");
+ FPRINTF(fp2, "&gt;"_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 = &pm;
+ 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'>(
&reg->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, &timestamp);
- 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, &timestamp);
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, &timestamp);
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, &timestamp);
- 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, &timestamp);
- 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, &timestamp);
+ 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 = &pm;
+ 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 &mid;
- }
-
- 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