summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/char/char.cpp437
-rw-r--r--src/char/char.hpp20
-rw-r--r--src/char/consts.hpp31
-rw-r--r--src/char/fwd.hpp14
-rw-r--r--src/char/globals.cpp68
-rw-r--r--src/char/globals.hpp59
-rw-r--r--src/char/int_party.cpp25
-rw-r--r--src/char/int_party.hpp5
-rw-r--r--src/char/int_storage.cpp26
-rw-r--r--src/char/int_storage.hpp5
-rw-r--r--src/char/inter.cpp55
-rw-r--r--src/char/inter.hpp20
-rw-r--r--src/high/extract_mmo.cpp5
-rw-r--r--src/high/extract_mmo.hpp1
14 files changed, 350 insertions, 421 deletions
diff --git a/src/char/char.cpp b/src/char/char.cpp
index ff9905f..a9b6834 100644
--- a/src/char/char.cpp
+++ b/src/char/char.cpp
@@ -78,7 +78,11 @@
#include "../wire/packets.hpp"
+#include "char_conf.hpp"
+#include "char_lan_conf.hpp"
+#include "globals.hpp"
#include "inter.hpp"
+#include "inter_conf.hpp"
#include "int_party.hpp"
#include "int_storage.hpp"
@@ -87,52 +91,8 @@
namespace tmwa
{
-static
-Array<struct mmo_map_server, MAX_MAP_SERVERS> server;
-static
-Array<Session *, MAX_MAP_SERVERS> server_session;
-static
-Array<int, MAX_MAP_SERVERS> server_freezeflag; // Map-server anti-freeze system. Counter. 5 ok, 4...0 freezed
-static
-int anti_freeze_enable = 0;
-static
-std::chrono::seconds anti_freeze_interval = 6_s;
-
-static
-Session *login_session, *char_session;
-static
-AccountName userid;
-static
-AccountPass passwd;
-static
-ServerName server_name;
-static
-const CharName WISP_SERVER_NAME = stringish<CharName>("Server"_s);
-static
-IP4Address login_ip;
-static
-int login_port = 6900;
-static
-IP4Address char_ip;
-static
-int char_port = 6121;
-static
-AString char_txt;
-static
-CharName unknown_char_name = stringish<CharName>("Unknown"_s);
-static
-AString char_log_filename = "log/char.log"_s;
-//Added for lan support
-static
-IP4Address lan_map_ip = IP4_LOCALHOST;
-static
-IP4Mask lan_subnet = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST);
-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);
-
-
+namespace char_
+{
struct char_session_data : SessionData
{
AccountId account_id;
@@ -141,61 +101,15 @@ struct char_session_data : SessionData
unsigned short packet_tmw_version;
AccountEmail email;
};
+} // namespace char_
void SessionDeleter::operator()(SessionData *sd)
{
- really_delete1 static_cast<char_session_data *>(sd);
+ really_delete1 static_cast<char_::char_session_data *>(sd);
}
-struct AuthFifoEntry
+namespace char_
{
- AccountId account_id;
- CharId char_id;
- int login_id1, login_id2;
- IP4Address ip;
- int delflag;
- SEX sex;
- unsigned short packet_tmw_version;
-};
-static
-std::array<AuthFifoEntry, 256> auth_fifo;
-static
-auto auth_fifo_iter = auth_fifo.begin();
-
-static
-CharId char_id_count = wrap<CharId>(150000);
-static
-std::vector<CharPair> char_keys;
-static
-int max_connect_user = 0;
-static
-std::chrono::milliseconds autosave_time = DEFAULT_AUTOSAVE_INTERVAL;
-
-// Initial position (it's possible to set it in conf file)
-static
-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"_s;
-static
-AString online_html_filename = "online.html"_s;
-static
-int online_refresh_html = 20; // refresh time (in sec) of the html file in the explorer
-static
-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)
-static
-TimeT update_online; // to update online files when we receiving information from a server (not less than 8 seconds)
-
-static
-pid_t pid = 0; // For forked DB writes
-
auto iter_map_sessions() -> decltype(filter_iterator<Session *>(std::declval<Array<Session *, MAX_MAP_SERVERS> *>()))
{
@@ -241,7 +155,7 @@ void delete_frommap(Session *sess)
//------------------------------
void char_log(XString line)
{
- io::AppendFile logfp(char_log_filename, true);
+ io::AppendFile logfp(char_conf.char_log_filename, true);
if (!logfp.is_open())
return;
log_with_timestamp(logfp, line);
@@ -318,7 +232,7 @@ AString mmo_char_tostr(struct CharPair *cp)
// on multi-map server, sometimes it's posssible that last_point become void. (reason???) We check that to not lost character at restart.
if (!p->last_point.map_)
{
- p->last_point = start_point;
+ p->last_point = char_conf.start_point;
}
MString str_p;
@@ -405,12 +319,6 @@ AString mmo_char_tostr(struct CharPair *cp)
return AString(str_p);
}
-static
-bool impl_extract(XString str, Point *p)
-{
- return extract(str, record<','>(&p->map_, &p->x, &p->y));
-}
-
struct skill_loader
{
SkillID id;
@@ -429,6 +337,7 @@ bool impl_extract(XString str, struct skill_loader *s)
s->flags = SkillFlags(flags_and_level >> 16);
return true;
}
+} // namespace char
//-------------------------------------------------------------------------
// Function to set the character from the line (at read of characters file)
@@ -436,6 +345,8 @@ bool impl_extract(XString str, struct skill_loader *s)
static
bool impl_extract(XString str, CharPair *cp)
{
+ using namespace tmwa::char_;
+
CharKey *k = &cp->key;
CharData *p = cp->data.get();
@@ -523,6 +434,8 @@ bool impl_extract(XString str, CharPair *cp)
return true;
}
+namespace char_
+{
//---------------------------------
// Function to read characters file
//---------------------------------
@@ -532,11 +445,11 @@ int mmo_char_init(void)
char_keys.clear();
online_chars.clear();
- io::ReadFile in(char_txt);
+ io::ReadFile in(char_conf.char_txt);
if (!in.is_open())
{
- PRINTF("Characters file not found: %s.\n"_fmt, char_txt);
- CHAR_LOG("Characters file not found: %s.\n"_fmt, char_txt);
+ PRINTF("Characters file not found: %s.\n"_fmt, char_conf.char_txt);
+ CHAR_LOG("Characters file not found: %s.\n"_fmt, char_conf.char_txt);
CHAR_LOG("Id for the next created character: %d.\n"_fmt,
char_id_count);
return 0;
@@ -574,9 +487,9 @@ int mmo_char_init(void)
}
PRINTF("mmo_char_init: %zu characters read in %s.\n"_fmt,
- char_keys.size(), char_txt);
+ char_keys.size(), char_conf.char_txt);
CHAR_LOG("mmo_char_init: %zu characters read in %s.\n"_fmt,
- char_keys.size(), char_txt);
+ char_keys.size(), char_conf.char_txt);
CHAR_LOG("Id for the next created character: %d.\n"_fmt,
char_id_count);
@@ -590,7 +503,7 @@ int mmo_char_init(void)
static
void mmo_char_sync(void)
{
- io::WriteLock fp(char_txt);
+ io::WriteLock fp(char_conf.char_txt);
if (!fp.is_open())
{
PRINTF("WARNING: Server can't not save characters.\n"_fmt);
@@ -681,12 +594,14 @@ CharPair *make_new_char(Session *s, CharName name, const Stats6& stats, uint8_t
{
// only letters/symbols in char_name_letters are authorised
for (uint8_t c : name.to__actual())
- if (!char_name_letters[c])
+ {
+ if (!char_conf.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"_fmt,
s, sd->account_id, name, c);
return nullptr;
}
+ }
}
// TODO this comment is obsolete
@@ -800,8 +715,8 @@ CharPair *make_new_char(Session *s, CharName name, const Stats6& stats, uint8_t
cd.head_top = ItemNameId();
cd.head_mid = ItemNameId();
cd.head_bottom = ItemNameId();
- cd.last_point = start_point;
- cd.save_point = start_point;
+ cd.last_point = char_conf.start_point;
+ cd.save_point = char_conf.start_point;
char_keys.push_back(std::move(cp));
online_chars.push_back(nullptr);
@@ -815,10 +730,10 @@ static
void create_online_files(void)
{
// write files
- io::WriteFile fp(online_txt_filename);
+ io::WriteFile fp(char_conf.online_txt_filename);
if (fp.is_open())
{
- io::WriteFile fp2(online_html_filename);
+ io::WriteFile fp2(char_conf.online_html_filename);
if (fp2.is_open())
{
// get time
@@ -826,15 +741,15 @@ void create_online_files(void)
stamp_time(timetemp);
// write heading
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, " <META http-equiv=\"Refresh\" content=\"%d\">\n"_fmt, char_conf.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);
+ char_conf.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);
+ char_conf.server_name, timetemp);
+ FPRINTF(fp, "Online Players on %s (%s):\n"_fmt, char_conf.server_name, timetemp);
FPRINTF(fp, "\n"_fmt);
int players = 0;
@@ -870,14 +785,14 @@ void create_online_files(void)
// without/with 'GM' display
GmLevel gml = isGM(cd.key.account_id);
{
- if (gml.satisfies(online_gm_display_min_level))
+ if (gml.satisfies(char_conf.online_gm_display_min_level))
FPRINTF(fp, "%-24s (GM) "_fmt, cd.key.name);
else
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>"_fmt);
- if (gml.satisfies(online_gm_display_min_level))
+ if (gml.satisfies(char_conf.online_gm_display_min_level))
FPRINTF(fp2, "<b>"_fmt);
for (char c : cd.key.name.to__actual())
{
@@ -897,7 +812,7 @@ void create_online_files(void)
break;
};
}
- if (gml.satisfies(online_gm_display_min_level))
+ if (gml.satisfies(char_conf.online_gm_display_min_level))
FPRINTF(fp2, "</b> (GM)"_fmt);
FPRINTF(fp2, "</td>\n"_fmt);
}
@@ -1257,8 +1172,8 @@ void parse_tologin(Session *ls)
fixed_6c.code = 0x42;
send_fpacket<0x006c, 3>(s2, fixed_6c);
}
- else if (max_connect_user == 0
- || count_users() < max_connect_user)
+ else if (char_conf.max_connect_user == 0
+ || count_users() < char_conf.max_connect_user)
{
sd->email = stringish<AccountEmail>(fixed.email);
if (!e_mail_check(sd->email))
@@ -1812,7 +1727,7 @@ void parse_frommap(Session *ms)
server[id].users = head.users;
assert (head.users == repeat.size());
- if (anti_freeze_enable)
+ if (char_conf.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
for (Session *& oci : online_chars)
@@ -2234,7 +2149,7 @@ int search_mapserver(XString map)
static
int lan_ip_check(IP4Address addr)
{
- bool lancheck = lan_subnet.covers(addr);
+ bool lancheck = char_lan_conf.lan_subnet.covers(addr);
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);
@@ -2299,7 +2214,7 @@ void handle_x0066(Session *s, struct char_session_data *sd, uint8_t rfifob_2, IP
sd->account_id, ck->char_num, ip);
PRINTF("--Send IP of map-server. "_fmt);
if (lan_ip_check(ip))
- fixed_71.ip = lan_map_ip;
+ fixed_71.ip = char_lan_conf.lan_map_ip;
else
fixed_71.ip = server[i].ip;
fixed_71.port = server[i].port;
@@ -2403,8 +2318,8 @@ void parse_char(Session *s)
&& afi.delflag == 2)
{
afi.delflag = 1;
- if (max_connect_user == 0
- || count_users() < max_connect_user)
+ if (char_conf.max_connect_user == 0
+ || count_users() < char_conf.max_connect_user)
{
{
// there is always a login server
@@ -2615,8 +2530,8 @@ void parse_char(Session *s)
}
AccountName userid_ = fixed.account_name;
AccountPass passwd_ = fixed.account_pass;
- if (i == MAX_MAP_SERVERS || userid_ != userid
- || passwd_ != passwd)
+ if (i == MAX_MAP_SERVERS || userid_ != char_conf.userid
+ || passwd_ != char_conf.passwd)
{
fixed_f9.code = 3;
send_fpacket<0x2af9, 3>(s, fixed_f9);
@@ -2626,7 +2541,7 @@ void parse_char(Session *s)
fixed_f9.code = 0;
s->set_parsers(SessionParsers{.func_parse= parse_frommap, .func_delete= delete_frommap});
server_session[i] = s;
- if (anti_freeze_enable)
+ if (char_conf.anti_freeze_enable)
server_freezeflag[i] = 5; // Map anti-freeze system. Counter. 5 ok, 4...0 freezed
// ignore fixed.unknown
server[i].ip = fixed.ip;
@@ -2714,19 +2629,19 @@ void check_connect_login_server(TimerData *, tick_t)
if (!login_session)
{
PRINTF("Attempt to connect to login-server...\n"_fmt);
- login_session = make_connection(login_ip, login_port,
+ login_session = make_connection(char_conf.login_ip, char_conf.login_port,
SessionParsers{.func_parse= parse_tologin, .func_delete= delete_tologin});
if (!login_session)
return;
realloc_fifo(login_session, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
Packet_Fixed<0x2710> fixed_10;
- fixed_10.account_name = userid;
- fixed_10.account_pass = passwd;
+ fixed_10.account_name = char_conf.userid;
+ fixed_10.account_pass = char_conf.passwd;
fixed_10.unknown = 0;
- fixed_10.ip = char_ip;
- fixed_10.port = char_port;
- fixed_10.server_name = server_name;
+ fixed_10.ip = char_conf.char_ip;
+ fixed_10.port = char_conf.char_port;
+ fixed_10.server_name = char_conf.server_name;
fixed_10.unknown2 = 0;
fixed_10.maintenance = 0;
fixed_10.is_new = 0;
@@ -2734,61 +2649,13 @@ void check_connect_login_server(TimerData *, tick_t)
}
}
-//-------------------------------------------
-// Reading Lan Support configuration by [Yor]
-//-------------------------------------------
-static
-bool char_lan_config(io::Spanned<XString> w1, io::Spanned<ZString> w2)
-{
- struct hostent *h = nullptr;
-
- {
- if (w1.data == "lan_map_ip"_s)
- {
- // Read map-server Lan IP Address
- h = gethostbyname(w2.data.c_str());
- if (h != nullptr)
- {
- lan_map_ip = IP4Address({
- static_cast<uint8_t>(h->h_addr[0]),
- static_cast<uint8_t>(h->h_addr[1]),
- static_cast<uint8_t>(h->h_addr[2]),
- static_cast<uint8_t>(h->h_addr[3]),
- });
- }
- else
- {
- PRINTF("Bad IP value: %s\n"_fmt, w2.data);
- return false;
- }
- PRINTF("LAN IP of map-server: %s.\n"_fmt, lan_map_ip);
- }
- else if (w1.data == "subnet"_s /*backward compatibility*/
- || w1.data == "lan_subnet"_s)
- {
- if (!extract(w2.data, &lan_subnet))
- {
- PRINTF("Bad IP mask: %s\n"_fmt, w2.data);
- return false;
- }
- PRINTF("Sub-network of the map-server: %s.\n"_fmt,
- lan_subnet);
- }
- else
- {
- return false;
- }
- }
- return true;
-}
-
static
bool lan_check()
{
// sub-network check of the map-server
{
PRINTF("LAN test of LAN IP of the map-server: "_fmt);
- if (!lan_ip_check(lan_map_ip))
+ if (!lan_ip_check(char_lan_conf.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"_fmt);
return false;
@@ -2799,144 +2666,46 @@ bool lan_check()
}
static
-bool char_config(io::Spanned<XString> w1, io::Spanned<ZString> w2)
+bool char_config(io::Spanned<XString> key, io::Spanned<ZString> value)
+{
+ return parse_char_conf(char_conf, key, value);
+}
+
+static
+bool char_lan_config(io::Spanned<XString> key, io::Spanned<ZString> value)
+{
+ return parse_char_lan_conf(char_lan_conf, key, value);
+}
+
+static
+bool inter_config(io::Spanned<XString> key, io::Spanned<ZString> value)
{
- struct hostent *h = nullptr;
+ return parse_inter_conf(inter_conf, key, value);
+}
+static
+bool char_confs(io::Spanned<XString> key, io::Spanned<ZString> value)
+{
+ if (key.data == "char_conf"_s)
{
- if (w1.data == "userid"_s)
- userid = stringish<AccountName>(w2.data);
- else if (w1.data == "passwd"_s)
- passwd = stringish<AccountPass>(w2.data);
- else if (w1.data == "server_name"_s)
- {
- server_name = stringish<ServerName>(w2.data);
- PRINTF("%s server has been intialized\n"_fmt, w2.data);
- }
- else if (w1.data == "login_ip"_s)
- {
- h = gethostbyname(w2.data.c_str());
- if (h != nullptr)
- {
- login_ip = IP4Address({
- static_cast<uint8_t>(h->h_addr[0]),
- static_cast<uint8_t>(h->h_addr[1]),
- static_cast<uint8_t>(h->h_addr[2]),
- static_cast<uint8_t>(h->h_addr[3]),
- });
- PRINTF("Login server IP address : %s -> %s\n"_fmt,
- w2.data, login_ip);
- }
- else
- {
- PRINTF("Bad IP value: %s\n"_fmt, w2.data);
- return false;
- }
- }
- else if (w1.data == "login_port"_s)
- {
- login_port = atoi(w2.data.c_str());
- }
- else if (w1.data == "char_ip"_s)
- {
- h = gethostbyname(w2.data.c_str());
- if (h != nullptr)
- {
- char_ip = IP4Address({
- static_cast<uint8_t>(h->h_addr[0]),
- static_cast<uint8_t>(h->h_addr[1]),
- static_cast<uint8_t>(h->h_addr[2]),
- static_cast<uint8_t>(h->h_addr[3]),
- });
- PRINTF("Character server IP address : %s -> %s\n"_fmt,
- w2.data, char_ip);
- }
- else
- {
- PRINTF("Bad IP value: %s\n"_fmt, w2.data);
- return false;
- }
- }
- else if (w1.data == "char_port"_s)
- {
- char_port = atoi(w2.data.c_str());
- }
- else if (w1.data == "char_txt"_s)
- {
- char_txt = w2.data;
- }
- else if (w1.data == "max_connect_user"_s)
- {
- max_connect_user = atoi(w2.data.c_str());
- if (max_connect_user < 0)
- max_connect_user = 0; // unlimited online players
- }
- else if (w1.data == "autosave_time"_s)
- {
- autosave_time = std::chrono::seconds(atoi(w2.data.c_str()));
- if (autosave_time <= std::chrono::seconds::zero())
- autosave_time = DEFAULT_AUTOSAVE_INTERVAL;
- }
- else if (w1.data == "start_point"_s)
- {
- extract(w2.data, &start_point);
- }
- else if (w1.data == "unknown_char_name"_s)
- {
- unknown_char_name = stringish<CharName>(w2.data);
- }
- else if (w1.data == "char_log_filename"_s)
- {
- char_log_filename = w2.data;
- }
- else if (w1.data == "char_name_letters"_s)
- {
- if (!w2.data)
- char_name_letters.reset();
- else
- for (uint8_t c : w2.data)
- char_name_letters[c] = true;
- }
- else if (w1.data == "online_txt_filename"_s)
- {
- online_txt_filename = w2.data;
- }
- else if (w1.data == "online_html_filename"_s)
- {
- online_html_filename = w2.data;
- }
- else if (w1.data == "online_gm_display_min_level"_s)
- {
- // minimum GM level to display 'GM' when we want to display it
- return extract(w2.data, &online_gm_display_min_level);
- }
- else if (w1.data == "online_refresh_html"_s)
- {
- online_refresh_html = atoi(w2.data.c_str());
- if (online_refresh_html < 1)
- online_refresh_html = 1;
- }
- else if (w1.data == "anti_freeze_enable"_s)
- {
- anti_freeze_enable = config_switch(w2.data);
- }
- else if (w1.data == "anti_freeze_interval"_s)
- {
- anti_freeze_interval = std::max(
- std::chrono::seconds(atoi(w2.data.c_str())),
- 5_s);
- }
- else
- {
- return false;
- }
+ return load_config_file(value.data, char_config);
}
-
- return true;
+ if (key.data == "char_lan_conf"_s)
+ {
+ return load_config_file(value.data, char_lan_config);
+ }
+ if (key.data == "inter_conf"_s)
+ {
+ return load_config_file(value.data, inter_config);
+ }
+ key.span.error("Unknown meta-key for char server"_s);
+ return false;
}
+} // namespace char_
void term_func(void)
{
+ using namespace tmwa::char_;
// write online players files with no player
std::fill(online_chars.begin(), online_chars.end(), nullptr);
create_online_files();
@@ -2954,24 +2723,9 @@ void term_func(void)
CHAR_LOG("----End of char-server (normal end with closing of all files).\n"_fmt);
}
-static
-bool char_confs(io::Spanned<XString> key, io::Spanned<ZString> value)
-{
- bool ok;
- ok = char_config(key, value);
- if (!ok)
- return ok;
- ok = char_lan_config(key, value);
- if (!ok)
- return ok;
- ok = inter_config(key, value);
- if (!ok)
- return ok;
- return ok;
-}
-
int do_init(Slice<ZString> argv)
{
+ using namespace tmwa::char_;
ZString argv0 = argv.pop_front();
bool loaded_config_yet = false;
@@ -3000,12 +2754,12 @@ int do_init(Slice<ZString> argv)
else
{
loaded_config_yet = true;
- runflag &= load_config_file(argvi, char_confs);
+ runflag &= load_config_file(argvi, char_::char_confs);
}
}
if (!loaded_config_yet)
- runflag &= load_config_file("conf/tmwa-char.conf"_s, char_confs);
+ runflag &= load_config_file("conf/tmwa-char.conf"_s, char_::char_confs);
// a newline in the log...
CHAR_LOG(""_fmt);
@@ -3019,7 +2773,7 @@ int do_init(Slice<ZString> argv)
update_online = TimeT::now();
create_online_files(); // update online players files at start of the server
- char_session = make_listen_port(char_port, SessionParsers{parse_char, delete_char});
+ char_session = make_listen_port(char_conf.char_port, SessionParsers{parse_char, delete_char});
Timer(gettick() + 1_s,
check_connect_login_server,
@@ -3029,25 +2783,26 @@ int do_init(Slice<ZString> argv)
send_users_tologin,
5_s
).detach();
- Timer(gettick() + autosave_time,
+ Timer(gettick() + char_conf.autosave_time,
mmo_char_sync_timer,
- autosave_time
+ char_conf.autosave_time
).detach();
- if (anti_freeze_enable > 0)
+ if (char_conf.anti_freeze_enable > 0)
{
Timer(gettick() + 1_s,
map_anti_freeze_system,
- anti_freeze_interval
+ char_conf.anti_freeze_interval
).detach();
}
CHAR_LOG("The char-server is ready (Server is listening on the port %d).\n"_fmt,
- char_port);
+ char_conf.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);
+ char_conf.char_port);
return 0;
}
+// namespace char_ ends before term_func and do_init
} // namespace tmwa
diff --git a/src/char/char.hpp b/src/char/char.hpp
index bcbdeb3..4f55c04 100644
--- a/src/char/char.hpp
+++ b/src/char/char.hpp
@@ -22,19 +22,36 @@
#include "fwd.hpp"
+#include "../ints/udl.hpp"
+
#include "../generic/array.hpp"
#include "../net/ip.hpp"
#include "../high/mmo.hpp"
+#include "consts.hpp"
+
namespace tmwa
{
-constexpr int MAX_MAP_SERVERS = 30;
+namespace char_
+{
constexpr
std::chrono::seconds DEFAULT_AUTOSAVE_INTERVAL = 5_min;
+constexpr
+GmLevel default_gm_level = GmLevel::from(0_u32);
+struct AuthFifoEntry
+{
+ AccountId account_id;
+ CharId char_id;
+ int login_id1, login_id2;
+ IP4Address ip;
+ int delflag;
+ SEX sex;
+ unsigned short packet_tmw_version;
+};
struct mmo_map_server
{
@@ -54,4 +71,5 @@ void char_log(XString line);
#define CHAR_LOG(fmt, ...) \
char_log(STRPRINTF(fmt, ## __VA_ARGS__))
+} // namespace char_
} // namespace tmwa
diff --git a/src/char/consts.hpp b/src/char/consts.hpp
new file mode 100644
index 0000000..e3b6c57
--- /dev/null
+++ b/src/char/consts.hpp
@@ -0,0 +1,31 @@
+#pragma once
+// consts.hpp - Constants for tmwa-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 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 char_
+{
+constexpr
+int MAX_MAP_SERVERS = 30;
+} // namespace char_
+} // namespace tmwa
diff --git a/src/char/fwd.hpp b/src/char/fwd.hpp
index ff2bf22..8086083 100644
--- a/src/char/fwd.hpp
+++ b/src/char/fwd.hpp
@@ -22,6 +22,7 @@
#include "../ints/fwd.hpp" // rank 1
#include "../strings/fwd.hpp" // rank 1
+#include "../compat/fwd.hpp" // rank 2
#include "../generic/fwd.hpp" // rank 3
#include "../io/fwd.hpp" // rank 4
#include "../net/fwd.hpp" // rank 5
@@ -34,5 +35,16 @@
namespace tmwa
{
-// meh, add more when I feel like it
+namespace char_
+{
+ struct CharConf;
+ struct CharLanConf;
+ struct InterConf;
+
+ struct AuthFifoEntry;
+ struct mmo_map_server;
+
+ struct accreg;
+ // meh, add more when I feel like it
+} // namespace char_
} // namespace tmwa
diff --git a/src/char/globals.cpp b/src/char/globals.cpp
new file mode 100644
index 0000000..6733ad5
--- /dev/null
+++ b/src/char/globals.cpp
@@ -0,0 +1,68 @@
+#include "globals.hpp"
+// globals.cpp - Evil global variables for tmwa-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 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/time_t.hpp"
+
+#include "../generic/db.hpp"
+
+#include "../proto2/net-Storage.hpp"
+
+#include "char.hpp"
+#include "char_conf.hpp"
+#include "char_lan_conf.hpp"
+#include "inter.hpp"
+#include "inter_conf.hpp"
+
+#include "../poison.hpp"
+
+
+namespace tmwa
+{
+ namespace char_
+ {
+ CharConf char_conf;
+ CharLanConf char_lan_conf;
+ InterConf inter_conf;
+ Array<mmo_map_server, MAX_MAP_SERVERS> server;
+ Array<Session *, MAX_MAP_SERVERS> server_session;
+ // Map-server anti-freeze system. Counter. 5 ok, 4...0 freezed
+ Array<int, MAX_MAP_SERVERS> server_freezeflag;
+ Session *login_session, *char_session;
+ const CharName WISP_SERVER_NAME = stringish<CharName>("Server"_s);
+ std::array<AuthFifoEntry, 256> auth_fifo;
+ decltype(auth_fifo)::iterator auth_fifo_iter = auth_fifo.begin();
+ CharId char_id_count = wrap<CharId>(150000);
+ std::vector<CharPair> char_keys;
+ std::vector<GM_Account> gm_accounts;
+ // same size of char_keys, and id value of current server (or -1)
+ std::vector<Session *> online_chars;
+ // to update online files when we receiving information from a server (not less than 8 seconds)
+ TimeT update_online;
+ // For forked DB writes
+ pid_t pid = 0;
+
+ Map<AccountId, accreg> accreg_db;
+
+ Map<PartyId, PartyMost> party_db;
+ PartyId party_newid = wrap<PartyId>(100_u32);
+
+ Map<AccountId, Storage> storage_db;
+ } // namespace char_
+} // namespace tmwa
diff --git a/src/char/globals.hpp b/src/char/globals.hpp
new file mode 100644
index 0000000..2df3f21
--- /dev/null
+++ b/src/char/globals.hpp
@@ -0,0 +1,59 @@
+#pragma once
+// globals.hpp - Evil global variables for tmwa-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 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 <sys/types.h>
+
+#include <array>
+#include <vector>
+
+#include "consts.hpp"
+
+
+namespace tmwa
+{
+ namespace char_
+ {
+ extern CharConf char_conf;
+ extern CharLanConf char_lan_conf;
+ extern InterConf inter_conf;
+ extern Array<mmo_map_server, MAX_MAP_SERVERS> server;
+ extern Array<Session *, MAX_MAP_SERVERS> server_session;
+ extern Array<int, MAX_MAP_SERVERS> server_freezeflag;
+ extern Session *login_session, *char_session;
+ extern const CharName WISP_SERVER_NAME;
+ extern std::array<AuthFifoEntry, 256> auth_fifo;
+ extern AuthFifoEntry *auth_fifo_iter;
+ extern CharId char_id_count;
+ extern std::vector<CharPair> char_keys;
+ extern std::vector<GM_Account> gm_accounts;
+ extern std::vector<Session *> online_chars;
+ extern TimeT update_online;
+ extern pid_t pid;
+
+ extern Map<AccountId, accreg> accreg_db;
+
+ extern Map<PartyId, PartyMost> party_db;
+ extern PartyId party_newid;
+
+ extern Map<AccountId, Storage> storage_db;
+ } // namespace char_
+} // namespace tmwa
diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp
index a16bc20..5ee65ad 100644
--- a/src/char/int_party.cpp
+++ b/src/char/int_party.cpp
@@ -44,20 +44,17 @@
#include "../wire/packets.hpp"
#include "char.hpp"
+#include "globals.hpp"
#include "inter.hpp"
+#include "inter_conf.hpp"
#include "../poison.hpp"
namespace tmwa
{
-AString party_txt = "save/party.txt"_s;
-
-static
-Map<PartyId, PartyMost> party_db;
-static
-PartyId party_newid = wrap<PartyId>(100_u32);
-
+namespace char_
+{
static
void mapif_party_broken(PartyId party_id, int flag);
static
@@ -91,6 +88,7 @@ AString inter_party_tostr(PartyPair p)
return AString(str);
}
+} // namespace char_
static
bool impl_extract(XString str, PartyPair *pp)
@@ -131,6 +129,8 @@ bool impl_extract(XString str, PartyPair *pp)
return true;
}
+namespace char_
+{
static
void party_check_deleted_init(PartyPair p)
{
@@ -155,7 +155,7 @@ void party_check_deleted_init(PartyPair p)
// パーティデータのロード
void inter_party_init(void)
{
- io::ReadFile in(party_txt);
+ io::ReadFile in(inter_conf.party_txt);
if (!in.is_open())
return;
@@ -186,7 +186,7 @@ void inter_party_init(void)
}
else
{
- PRINTF("int_party: broken data [%s] line %d\n"_fmt, party_txt,
+ PRINTF("int_party: broken data [%s] line %d\n"_fmt, inter_conf.party_txt,
c + 1);
}
c++;
@@ -204,11 +204,11 @@ void inter_party_save_sub(PartyPair data, io::WriteFile& fp)
// パーティーデータのセーブ
int inter_party_save(void)
{
- io::WriteLock fp(party_txt);
+ io::WriteLock fp(inter_conf.party_txt);
if (!fp.is_open())
{
PRINTF("int_party: cant write [%s] !!! data is lost !!!\n"_fmt,
- party_txt);
+ inter_conf.party_txt);
return 1;
}
for (auto& pair : party_db)
@@ -261,7 +261,7 @@ int party_check_exp_share(PartyPair p)
}
}
- return (maxlv == 0 || maxlv - minlv <= party_share_level);
+ return (maxlv == 0 || maxlv - minlv <= inter_conf.party_share_level);
}
// パーティが空かどうかチェック
@@ -822,4 +822,5 @@ void inter_party_leave(PartyId party_id, AccountId account_id)
{
mapif_parse_PartyLeave(nullptr, party_id, account_id);
}
+} // namespace char_
} // namespace tmwa
diff --git a/src/char/int_party.hpp b/src/char/int_party.hpp
index 79b3bd4..d66afbf 100644
--- a/src/char/int_party.hpp
+++ b/src/char/int_party.hpp
@@ -25,12 +25,13 @@
namespace tmwa
{
+namespace char_
+{
void inter_party_init(void);
int inter_party_save(void);
RecvResult inter_party_parse_frommap(Session *ms, uint16_t);
void inter_party_leave(PartyId party_id, AccountId account_id);
-
-extern AString party_txt;
+} // namespace char_
} // namespace tmwa
diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp
index 0c76678..32af231 100644
--- a/src/char/int_storage.cpp
+++ b/src/char/int_storage.cpp
@@ -42,18 +42,16 @@
#include "../wire/packets.hpp"
+#include "globals.hpp"
+#include "inter_conf.hpp"
+
#include "../poison.hpp"
namespace tmwa
{
-// ファイル名のデフォルト
-// inter_config_read()で再設定される
-AString storage_txt = "save/storage.txt"_s;
-
-static
-Map<AccountId, Storage> storage_db;
-
+namespace char_
+{
// 倉庫データを文字列に変換
static
AString storage_tostr(Storage *p)
@@ -92,6 +90,7 @@ AString storage_tostr(Storage *p)
return AString();
return AString(str);
}
+} // namespace char_
// 文字列を倉庫データに変換
static
@@ -118,6 +117,8 @@ bool impl_extract(XString str, Storage *p)
return true;
}
+namespace char_
+{
// アカウントから倉庫データインデックスを得る(新規倉庫追加可能)
Borrowed<Storage> account2storage(AccountId account_id)
{
@@ -132,10 +133,10 @@ void inter_storage_init(void)
{
int c = 0;
- io::ReadFile in(storage_txt);
+ io::ReadFile in(inter_conf.storage_txt);
if (!in.is_open())
{
- PRINTF("cant't read : %s\n"_fmt, storage_txt);
+ PRINTF("cant't read : %s\n"_fmt, inter_conf.storage_txt);
return;
}
@@ -150,7 +151,7 @@ void inter_storage_init(void)
else
{
PRINTF("int_storage: broken data [%s] line %d\n"_fmt,
- storage_txt, c);
+ inter_conf.storage_txt, c);
}
c++;
}
@@ -168,12 +169,12 @@ void inter_storage_save_sub(Storage *data, io::WriteFile& fp)
// 倉庫データを書き込む
int inter_storage_save(void)
{
- io::WriteLock fp(storage_txt);
+ io::WriteLock fp(inter_conf.storage_txt);
if (!fp.is_open())
{
PRINTF("int_storage: cant write [%s] !!! data is lost !!!\n"_fmt,
- storage_txt);
+ inter_conf.storage_txt);
return 1;
}
for (auto& pair : storage_db)
@@ -270,4 +271,5 @@ RecvResult inter_storage_parse_frommap(Session *ms, uint16_t packet_id)
}
return rv;
}
+} // namespace char_
} // namespace tmwa
diff --git a/src/char/int_storage.hpp b/src/char/int_storage.hpp
index c03ebff..3741061 100644
--- a/src/char/int_storage.hpp
+++ b/src/char/int_storage.hpp
@@ -25,12 +25,13 @@
namespace tmwa
{
+namespace char_
+{
void inter_storage_init(void);
int inter_storage_save(void);
void inter_storage_delete(AccountId account_id);
Borrowed<Storage> account2storage(AccountId account_id);
RecvResult inter_storage_parse_frommap(Session *ms, uint16_t);
-
-extern AString storage_txt;
+} // namespace char_
} // namespace tmwa
diff --git a/src/char/inter.cpp b/src/char/inter.cpp
index df05434..3bf3bfc 100644
--- a/src/char/inter.cpp
+++ b/src/char/inter.cpp
@@ -50,6 +50,8 @@
#include "../wire/packets.hpp"
#include "char.hpp"
+#include "globals.hpp"
+#include "inter_conf.hpp"
#include "int_party.hpp"
#include "int_storage.hpp"
@@ -58,20 +60,8 @@
namespace tmwa
{
-static
-AString accreg_txt = "save/accreg.txt"_s;
-
-struct accreg
+namespace char_
{
- AccountId account_id;
- int reg_num;
- Array<GlobalReg, ACCOUNT_REG_NUM> reg;
-};
-static
-Map<AccountId, struct accreg> accreg_db;
-
-int party_share_level = 10;
-
//--------------------------------------------------------
// アカウント変数を文字列へ変換
@@ -112,7 +102,7 @@ void inter_accreg_init(void)
{
int c = 0;
- io::ReadFile in(accreg_txt);
+ io::ReadFile in(inter_conf.accreg_txt);
if (!in.is_open())
return;
AString line;
@@ -125,7 +115,7 @@ void inter_accreg_init(void)
}
else
{
- PRINTF("inter: accreg: broken data [%s] line %d\n"_fmt, accreg_txt,
+ PRINTF("inter: accreg: broken data [%s] line %d\n"_fmt, inter_conf.accreg_txt,
c);
}
c++;
@@ -147,11 +137,11 @@ void inter_accreg_save_sub(struct accreg *reg, io::WriteFile& fp)
static
int inter_accreg_save(void)
{
- io::WriteLock fp(accreg_txt);
+ io::WriteLock fp(inter_conf.accreg_txt);
if (!fp.is_open())
{
PRINTF("int_accreg: cant write [%s] !!! data is lost !!!\n"_fmt,
- accreg_txt);
+ inter_conf.accreg_txt);
return 1;
}
for (auto& pair : accreg_db)
@@ -160,36 +150,6 @@ int inter_accreg_save(void)
return 0;
}
-bool inter_config(io::Spanned<XString> w1, io::Spanned<ZString> w2)
-{
- {
- if (w1.data == "storage_txt"_s)
- {
- storage_txt = w2.data;
- }
- else if (w1.data == "party_txt"_s)
- {
- party_txt = w2.data;
- }
- else if (w1.data == "accreg_txt"_s)
- {
- accreg_txt = w2.data;
- }
- else if (w1.data == "party_share_level"_s)
- {
- party_share_level = atoi(w2.data.c_str());
- if (party_share_level < 0)
- party_share_level = 0;
- }
- else
- {
- return false;
- }
- }
-
- return true;
-}
-
// セーブ
void inter_save(void)
{
@@ -489,4 +449,5 @@ RecvResult inter_parse_frommap(Session *ms, uint16_t packet_id)
return rv;
}
+} // namespace char_
} // namespace tmwa
diff --git a/src/char/inter.hpp b/src/char/inter.hpp
index 741bc8d..c641254 100644
--- a/src/char/inter.hpp
+++ b/src/char/inter.hpp
@@ -22,13 +22,27 @@
#include "fwd.hpp"
+#include "../generic/array.hpp"
+
+#include "../mmo/consts.hpp"
+#include "../mmo/ids.hpp"
+
+#include "../proto2/net-GlobalReg.hpp"
+
namespace tmwa
{
-bool inter_config(io::Spanned<XString> key, io::Spanned<ZString> value);
+namespace char_
+{
+struct accreg
+{
+ AccountId account_id;
+ int reg_num;
+ Array<GlobalReg, ACCOUNT_REG_NUM> reg;
+};
+
void inter_init2();
void inter_save(void);
RecvResult inter_parse_frommap(Session *ms, uint16_t packet_id);
-
-extern int party_share_level;
+} // namespace char_
} // namespace tmwa
diff --git a/src/high/extract_mmo.cpp b/src/high/extract_mmo.cpp
index dae6a3b..ab4290d 100644
--- a/src/high/extract_mmo.cpp
+++ b/src/high/extract_mmo.cpp
@@ -92,4 +92,9 @@ bool impl_extract(XString str, NpcEvent *ev)
XString mid;
return extract(str, record<':'>(&ev->npc, &mid, &ev->label)) && !mid;
}
+
+bool impl_extract(XString str, Point *p)
+{
+ return extract(str, record<','>(&p->map_, &p->x, &p->y));
+}
} // namespace tmwa
diff --git a/src/high/extract_mmo.hpp b/src/high/extract_mmo.hpp
index 5fcd06f..f374658 100644
--- a/src/high/extract_mmo.hpp
+++ b/src/high/extract_mmo.hpp
@@ -29,4 +29,5 @@ bool impl_extract(XString str, MapName *m);
bool impl_extract(XString str, CharName *out);
bool impl_extract(XString str, NpcEvent *ev);
+bool impl_extract(XString str, Point *p);
} // namespace tmwa