summaryrefslogtreecommitdiff
path: root/src/login/login.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/login/login.cpp')
-rw-r--r--src/login/login.cpp1188
1 files changed, 220 insertions, 968 deletions
diff --git a/src/login/login.cpp b/src/login/login.cpp
index ccb68fc..92f8cc0 100644
--- a/src/login/login.cpp
+++ b/src/login/login.cpp
@@ -45,23 +45,19 @@
#include "../generic/random.hpp"
#include "../io/cxxstdio.hpp"
+#include "../io/extract.hpp"
#include "../io/lock.hpp"
#include "../io/read.hpp"
+#include "../io/span.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/utils.hpp"
#include "../mmo/version.hpp"
#include "../proto2/any-user.hpp"
@@ -69,115 +65,23 @@
#include "../proto2/login-char.hpp"
#include "../proto2/login-user.hpp"
-#include "../poison.hpp"
-
+#include "../high/core.hpp"
+#include "../high/extract_mmo.hpp"
+#include "../high/md5more.hpp"
+#include "../high/mmo.hpp"
+#include "../high/utils.hpp"
-namespace tmwa
-{
-constexpr int MAX_SERVERS = 30;
+#include "../wire/packets.hpp"
-constexpr AccountId START_ACCOUNT_NUM = wrap<AccountId>(2000000);
-constexpr AccountId END_ACCOUNT_NUM = wrap<AccountId>(100000000);
-
-struct mmo_account
-{
- AccountName userid;
- AccountPass passwd;
- int passwdenc;
+#include "globals.hpp"
+#include "login_conf.hpp"
+#include "login_lan_conf.hpp"
- AccountId account_id;
- int login_id1;
- int login_id2;
- AccountId char_id;
- timestamp_milliseconds_buffer lastlogin;
- SEX sex;
-};
-
-struct mmo_char_server
-{
- ServerName name;
- IP4Address ip;
- uint16_t port;
- uint16_t users;
-};
-
-static
-AccountId account_id_count = START_ACCOUNT_NUM;
-static
-int new_account = 0;
-static
-int login_port = 6900;
-static
-IP4Address lan_char_ip = IP4_LOCALHOST;
-static
-IP4Mask lan_subnet = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST);
-static
-AString update_host;
-static
-AccountName userid;
-static
-AccountPass passwd;
-static
-ServerName main_server;
-
-static
-AString account_filename = "save/account.txt"_s;
-static
-AString gm_account_filename = "save/gm_account.txt"_s;
-static
-AString login_log_filename = "log/login.log"_s;
-static
-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 = 15_s;
-
-static
-int display_parse_login = 0; // 0: no, 1: yes
-static
-int display_parse_admin = 0; // 0: no, 1: yes
-static
-int display_parse_fromchar = 0; // 0: no, 1: yes (without packet 0x2714), 2: all packets
-
-static
-Array<struct mmo_char_server, MAX_SERVERS> server;
-static
-Array<Session *, MAX_SERVERS> server_session;
-static
-Array<int, MAX_SERVERS> server_freezeflag; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
-static
-int anti_freeze_enable = 0;
-static
-std::chrono::seconds anti_freeze_interval = 15_s;
+#include "../poison.hpp"
-static
-Session *login_session;
-enum class ACO
+namespace tmwa
{
- DENY_ALLOW,
- ALLOW_DENY,
- MUTUAL_FAILURE,
-};
-
-static
-ACO access_order = ACO::DENY_ALLOW;
-static
-std::vector<IP4Mask>
-access_allow, access_deny, access_ladmin;
-
-static
-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
-int start_limited_time = -1; // Starting additional sec from now for the limited time at creation of accounts (-1: unlimited time, 0 or more: additional sec from now)
-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)
-
DIAG_PUSH();
DIAG_I(missing_noreturn);
void SessionDeleter::operator()(SessionData *)
@@ -186,67 +90,54 @@ void SessionDeleter::operator()(SessionData *)
}
DIAG_POP();
-constexpr int AUTH_FIFO_SIZE = 256;
-struct AuthFifo
+// out of namespace because ADL is dumb
+bool extract(XString str, login::ACO *aco)
{
- 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
+ using login::ACO;
+ if (str == "deny,allow"_s || str == "deny, allow"_s)
+ {
+ *aco = ACO::DENY_ALLOW;
+ return true;
+ }
+ if (str == "allow,deny"_s || str == "allow, deny"_s)
+ {
+ *aco = ACO::ALLOW_DENY;
+ return true;
+ }
+ // typo from old config files
+ if (str == "mutual-failture"_s || str == "mutual-failure"_s)
+ {
+ *aco = ACO::MUTUAL_FAILURE;
+ return true;
+ }
+ return false;
+}
+namespace login
+{
+struct mmo_account
{
- AccountId account_id;
- SEX sex;
AccountName userid;
- AccountCrypt pass;
+ AccountPass passwd;
+ int passwdenc;
+
+ AccountId account_id;
+ int login_id1;
+ int login_id2;
+ AccountId char_id;
timestamp_milliseconds_buffer lastlogin;
- int logincount;
- int state; // packet 0x006a value + 1 (0: compte OK)
- AccountEmail email; // e-mail (by default: a@a.com)
- timestamp_seconds_buffer error_message; // Message of error code #6 = Your are Prohibited to log in until %s (packet 0x006a)
- TimeT ban_until_time; // # of seconds 1/1/1970 (timestamp): ban time limit of the account (0 = no ban)
- TimeT connect_until_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
- IP4Address last_ip; // save of last IP of connection
- VString<254> memo; // a memo field
- int account_reg2_num;
- Array<GlobalReg, ACCOUNT_REG2_NUM> account_reg2;
+ SEX sex;
};
-static
-std::vector<AuthData> auth_data;
-
-static
-int admin_state = 0;
-static
-AccountPass admin_pass;
-static
-AString gm_pass;
-static
-GmLevel level_new_gm = GmLevel::from(60u);
-
-static
-Map<AccountId, GM_Account> gm_account_db;
-
-static
-pid_t pid = 0; // For forked DB writes
//------------------------------
// Writing function of logs file
//------------------------------
#define LOGIN_LOG(fmt, ...) \
- login_log(STRPRINTF(fmt, ## __VA_ARGS__))
+ tmwa::login::login_log(STRPRINTF(fmt, ## __VA_ARGS__))
static
void login_log(XString line)
{
- io::AppendFile logfp(login_log_filename);
+ io::AppendFile logfp(login_conf.login_log_filename);
if (!logfp.is_open())
return;
log_with_timestamp(logfp, line);
@@ -287,10 +178,8 @@ void delete_admin(Session *s)
static
GmLevel isGM(AccountId account_id)
{
- GM_Account *p = gm_account_db.search(account_id);
- if (p == nullptr)
- return GmLevel();
- return p->level;
+ Option<P<GM_Account>> p = gm_account_db.search(account_id);
+ return TRY_UNWRAP(p, return GmLevel())->level;
}
//-------------------------------------------------------
@@ -303,16 +192,16 @@ int read_gm_account(void)
gm_account_db.clear();
- creation_time_GM_account_file = file_modified(gm_account_filename);
+ creation_time_GM_account_file = file_modified(login_conf.gm_account_filename);
- io::ReadFile fp(gm_account_filename);
+ io::ReadFile fp(login_conf.gm_account_filename);
if (!fp.is_open())
{
PRINTF("read_gm_account: GM accounts file [%s] not found.\n"_fmt,
- gm_account_filename);
+ login_conf.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);
+ login_conf.gm_account_filename);
LOGIN_LOG(" Actually, there is no GM accounts on the server.\n"_fmt);
return 1;
}
@@ -326,7 +215,7 @@ int read_gm_account(void)
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"_fmt,
- gm_account_filename, line);
+ login_conf.gm_account_filename, line);
else
{
GmLevel GM_level = isGM(p.account_id);
@@ -356,9 +245,9 @@ int read_gm_account(void)
}
PRINTF("read_gm_account: file '%s' readed (%d GM accounts found).\n"_fmt,
- gm_account_filename, c);
+ login_conf.gm_account_filename, c);
LOGIN_LOG("read_gm_account: file '%s' readed (%d GM accounts found).\n"_fmt,
- gm_account_filename, c);
+ login_conf.gm_account_filename, c);
return 0;
}
@@ -377,29 +266,29 @@ bool check_ip(IP4Address ip)
};
ACF flag = ACF::DEF;
- if (access_allow.empty() && access_deny.empty())
+ if (login_conf.allow.empty() && login_conf.deny.empty())
return 1;
// When there is no restriction, all IP are authorised.
- if (std::find_if(access_allow.begin(), access_allow.end(),
+ if (std::find_if(login_conf.allow.begin(), login_conf.allow.end(),
[&ip](IP4Mask m)
{
return m.covers(ip);
- }) != access_allow.end())
+ }) != login_conf.allow.end())
{
{
flag = ACF::ALLOW;
- if (access_order == ACO::ALLOW_DENY)
+ if (login_conf.order == ACO::ALLOW_DENY)
// With 'allow, deny' (deny if not allow), allow has priority
return 1;
}
}
- if (std::find_if(access_deny.begin(), access_deny.end(),
+ if (std::find_if(login_conf.deny.begin(), login_conf.deny.end(),
[&ip](IP4Mask m)
{
return m.covers(ip);
- }) != access_deny.end())
+ }) != login_conf.deny.end())
{
{
flag = ACF::DENY;
@@ -408,7 +297,7 @@ bool check_ip(IP4Address ip)
}
}
- return flag == ACF::ALLOW || access_order == ACO::DENY_ALLOW;
+ return flag == ACF::ALLOW || login_conf.order == ACO::DENY_ALLOW;
// With 'mutual-failture', only 'allow' and non 'deny' IP are authorised.
// A non 'allow' (even non 'deny') IP is not authorised. It's like: if allowed and not denied, it's authorised.
// So, it's disapproval if you have no description at the time of 'mutual-failture'.
@@ -421,15 +310,15 @@ bool check_ip(IP4Address ip)
static
bool check_ladminip(IP4Address ip)
{
- if (access_ladmin.empty())
+ if (login_conf.ladminallowip.empty())
// When there is no restriction, all IP are authorised.
return true;
- return std::find_if(access_ladmin.begin(), access_ladmin.end(),
+ return std::find_if(login_conf.ladminallowip.begin(), login_conf.ladminallowip.end(),
[&ip](IP4Mask m)
{
return m.covers(ip);
- }) != access_ladmin.end();
+ }) != login_conf.ladminallowip.end();
}
//-----------------------------------------------
@@ -480,7 +369,7 @@ AString mmo_auth_tostr(const AuthData *p)
p->state,
p->email,
p->error_message,
- p->connect_until_time,
+ TimeT(),
p->last_ip,
p->memo,
p->ban_until_time);
@@ -495,8 +384,9 @@ AString mmo_auth_tostr(const AuthData *p)
}
static
-bool extract(XString line, AuthData *ad)
+bool impl_extract(XString line, AuthData *ad)
{
+ TimeT unused_connect_until_time;
std::vector<GlobalReg> vars;
VString<1> sex;
VString<15> ip;
@@ -511,7 +401,7 @@ bool extract(XString line, AuthData *ad)
&ad->state,
&ad->email,
&ad->error_message,
- &ad->connect_until_time,
+ &unused_connect_until_time,
&ip,
&ad->memo,
&ad->ban_until_time,
@@ -577,13 +467,13 @@ int mmo_auth_init(void)
{
int gm_count = 0;
- io::ReadFile in(account_filename);
+ io::ReadFile in(login_conf.account_filename);
if (!in.is_open())
{
// 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"_fmt,
- account_filename);
+ login_conf.account_filename);
return 0;
}
@@ -620,7 +510,7 @@ int mmo_auth_init(void)
}
AString str = STRPRINTF("%s has %zu accounts (%d GMs)\n"_fmt,
- account_filename, auth_data.size(), gm_count);
+ login_conf.account_filename, auth_data.size(), gm_count);
PRINTF("mmo_auth_init: %s\n"_fmt, str);
LOGIN_LOG("%s\n"_fmt, line);
@@ -633,7 +523,7 @@ int mmo_auth_init(void)
static
void mmo_auth_sync(void)
{
- io::WriteLock fp(account_filename);
+ io::WriteLock fp(login_conf.account_filename);
if (!fp.is_open())
{
@@ -643,7 +533,7 @@ void mmo_auth_sync(void)
FPRINTF(fp,
"// 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"_fmt);
+ "// Structure: ID, account name, password, last login time, sex, # of logins, state, email, error message for state 7, validity time (unused), 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"_fmt);
@@ -754,11 +644,11 @@ static
void check_GM_file(TimerData *, tick_t)
{
// if we would not check
- if (gm_account_filename_check_timer == interval_t::zero())
+ if (login_conf.gm_account_filename_check_timer == interval_t::zero())
return;
// get last modify time/date
- tick_t new_time = file_modified(gm_account_filename);
+ tick_t new_time = file_modified(login_conf.gm_account_filename);
if (new_time != creation_time_GM_account_file)
{
@@ -795,17 +685,6 @@ AccountId mmo_auth_new(struct mmo_account *account, SEX sex, AccountEmail email)
ad.error_message = stringish<timestamp_seconds_buffer>("-"_s);
ad.ban_until_time = TimeT();
- if (start_limited_time < 0)
- ad.connect_until_time = TimeT(); // unlimited
- else
- {
- // limited time
- TimeT timestamp = static_cast<time_t>(TimeT::now()) + start_limited_time;
- // there used to be a silly overflow check here, but it wasn't
- // correct, and we don't support time-limited accounts.
- ad.connect_until_time = timestamp;
- }
-
ad.last_ip = IP4Address();
ad.memo = "!"_s;
ad.account_reg2_num = 0;
@@ -827,7 +706,7 @@ int mmo_auth(struct mmo_account *account, Session *s)
// Account creation with _M/_F
if (account->passwdenc == 0
&& (account->userid.endswith("_F"_s) || account->userid.endswith("_M"_s))
- && new_account == 1 && account_id_count < END_ACCOUNT_NUM
+ && login_conf.new_account && account_id_count < END_ACCOUNT_NUM
&& (account->userid.size() - 2) >= 4 && account->passwd.size() >= 4)
{
new_account_sex = account->userid.back();
@@ -899,14 +778,6 @@ 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"_fmt,
- account->userid, ip);
- return 2; // 2 = This ID is expired
- }
-
LOGIN_LOG("Authentification accepted (account: %s (id: %d), ip: %s)\n"_fmt,
account->userid, ad->account_id, ip);
}
@@ -989,28 +860,12 @@ void parse_fromchar(Session *s)
uint16_t packet_id;
while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id))
{
- if (display_parse_fromchar == 2 || (display_parse_fromchar == 1 && packet_id != 0x2714)) // 0x2714 is done very often (number of players)
+ if (login_conf.display_parse_fromchar == 2 || (login_conf.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 (packet_id)
{
- // request from map-server via char-server to reload GM accounts (by Yor).
- case 0x2709:
- {
- 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();
- break;
- }
-
case 0x2712: // request from char-server to authentify an account
{
Packet_Fixed<0x2712> fixed;
@@ -1027,8 +882,7 @@ void parse_fromchar(Session *s)
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 == fixed.ip)
+ auth_fifo[i].ip == fixed.ip
&& !auth_fifo[i].delflag)
{
auth_fifo[i].delflag = 1;
@@ -1057,7 +911,6 @@ void parse_fromchar(Session *s)
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;
@@ -1092,7 +945,7 @@ void parse_fromchar(Session *s)
break;
server[id].users = fixed.users;
- if (anti_freeze_enable)
+ if (login_conf.anti_freeze_enable)
server_freezeflag[id] = 5; // Char anti-freeze system. Counter. 5 ok, 4...0 freezed
break;
}
@@ -1116,7 +969,6 @@ void parse_fromchar(Session *s)
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)
@@ -1130,93 +982,6 @@ void parse_fromchar(Session *s)
break;
}
- case 0x2720: // To become GM request
- {
- Packet_Head<0x2720> head;
- AString repeat;
- rv = recv_vpacket<0x2720, 8, 1>(s, head, repeat);
- if (rv != RecvResult::Complete)
- break;
-
- {
- 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))
- {
- // if we autorise creation
- if (level_new_gm)
- {
- // if we can open the file to add the new GM
- io::AppendFile fp(gm_account_filename);
- if (fp.is_open())
- {
- timestamp_seconds_buffer tmpstr;
- stamp_time(tmpstr);
- FPRINTF(fp,
- "\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"_fmt);
- }
- fixed_21.gm_level = level_new_gm;
- read_gm_account();
- send_GM_accounts();
- 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"_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"_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"_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"_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);
- }
- }
- 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
{
@@ -1603,19 +1368,17 @@ void parse_fromchar(Session *s)
default:
{
- io::AppendFile logfp(login_log_unknown_packets_filename);
- if (logfp.is_open())
{
timestamp_milliseconds_buffer timestr;
stamp_time(timestr);
- FPRINTF(logfp,
+ FPRINTF(stderr,
"%s: receiving of an unknown packet -> disconnection\n"_fmt,
timestr);
- FPRINTF(logfp,
+ FPRINTF(stderr,
"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);
+ FPRINTF(stderr, "Detail (in hex):\n"_fmt);
+ packet_dump(s);
}
PRINTF("parse_fromchar: Unknown packet 0x%x (from a char-server)! -> disconnection.\n"_fmt,
packet_id);
@@ -1641,7 +1404,7 @@ void parse_admin(Session *s)
uint16_t packet_id;
while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id))
{
- if (display_parse_admin == 1)
+ if (login_conf.display_parse_admin)
PRINTF("parse_admin: connection #%d, packet: 0x%x (with being read: %zu bytes).\n"_fmt,
s, packet_id, packet_avail(s));
@@ -1718,23 +1481,6 @@ void parse_admin(Session *s)
break;
}
- case 0x7924:
- { // [Fate] Itemfrob package: change item IDs
- 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
{
Packet_Fixed<0x7930> fixed;
@@ -2096,10 +1842,10 @@ void parse_admin(Session *s)
AccountId GM_account;
GmLevel GM_level;
int modify_flag;
- io::WriteLock fp2(gm_account_filename);
+ io::WriteLock fp2(login_conf.gm_account_filename);
if (fp2.is_open())
{
- io::ReadFile fp(gm_account_filename);
+ io::ReadFile fp(login_conf.gm_account_filename);
if (fp.is_open())
{
timestamp_seconds_buffer tmpstr;
@@ -2330,48 +2076,6 @@ void parse_admin(Session *s)
break;
}
- case 0x7948: // Request to change the validity limit (timestamp) (absolute value)
- {
- Packet_Fixed<0x7948> fixed;
- rv = recv_fpacket<0x7948, 30>(s, fixed);
- if (rv != RecvResult::Complete)
- break;
-
- Packet_Fixed<0x7949> fixed_49;
- {
- 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)
- {
- 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;
- fixed_49.account_id = ad->account_id;
- }
- else
- {
- 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);
- }
- fixed_49.valid_until = timestamp;
- }
- send_fpacket<0x7949, 34>(s, fixed_49);
- break;
- }
-
case 0x794a: // Request to change the final date of a banishment (timestamp) (absolute value)
{
Packet_Fixed<0x794a> fixed;
@@ -2475,7 +2179,7 @@ void parse_admin(Session *s)
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"_fmt,
+ 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 ban: %lld (%s), ip: %s)\n"_fmt,
ad->userid,
ban_diff.year, ban_diff.month,
ban_diff.day, ban_diff.hour,
@@ -2583,99 +2287,6 @@ void parse_admin(Session *s)
break;
}
- case 0x7950: // Request to change the validity limite (timestamp) (relative change)
- {
- Packet_Fixed<0x7950> fixed;
- rv = recv_fpacket<0x7950, 38>(s, fixed);
- if (rv != RecvResult::Complete)
- break;
-
- Packet_Fixed<0x7951> fixed_51;
- {
- fixed_51.account_id = AccountId();
- AccountName account_name = stringish<AccountName>(fixed.account_name.to_print());
- AuthData *ad = search_account(account_name);
- if (ad)
- {
- 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"_fmt,
- ad->userid, ip);
- fixed_51.valid_until = TimeT();
- }
- else
- {
- TimeT now = TimeT::now();
- TimeT timestamp = ad->connect_until_time;
- if (!timestamp || timestamp < now)
- timestamp = now;
- struct tm tmtime = timestamp;
- HumanTimeDiff v_diff = fixed.valid_add;
- tmtime.tm_year += v_diff.year;
- tmtime.tm_mon += v_diff.month;
- tmtime.tm_mday += v_diff.day;
- tmtime.tm_hour += v_diff.hour;
- tmtime.tm_min += v_diff.minute;
- tmtime.tm_sec += v_diff.second;
- timestamp = tmtime;
- if (timestamp.okay())
- {
- 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"_fmt,
- ad->userid,
- ad->connect_until_time,
- tmpstr,
- v_diff.year,
- v_diff.month,
- v_diff.day,
- v_diff.hour,
- v_diff.minute,
- v_diff.second,
- timestamp,
- tmpstr2,
- ip);
- ad->connect_until_time = timestamp;
- fixed_51.valid_until = timestamp;
- }
- else
- {
- 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"_fmt,
- ad->userid,
- ad->connect_until_time,
- tmpstr,
- v_diff.year,
- v_diff.month,
- v_diff.day,
- v_diff.hour,
- v_diff.minute,
- v_diff.second,
- ip);
- fixed_51.valid_until = TimeT();
- }
- }
- }
- else
- {
- 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();
- }
- }
- send_fpacket<0x7951, 34>(s, fixed_51);
- break;
- }
-
case 0x7952: // Request about informations of an account (by account name)
{
Packet_Fixed<0x7952> fixed;
@@ -2699,7 +2310,6 @@ void parse_admin(Session *s)
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;
@@ -2745,7 +2355,6 @@ void parse_admin(Session *s)
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);
@@ -2779,19 +2388,17 @@ void parse_admin(Session *s)
default:
{
- io::AppendFile logfp(login_log_unknown_packets_filename);
- if (logfp.is_open())
{
timestamp_milliseconds_buffer timestr;
stamp_time(timestr);
- FPRINTF(logfp,
+ FPRINTF(stderr,
"%s: receiving of an unknown packet -> disconnection\n"_fmt,
timestr);
- FPRINTF(logfp,
+ FPRINTF(stderr,
"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);
+ FPRINTF(stderr, "Detail (in hex):\n"_fmt);
+ packet_dump(s);
}
LOGIN_LOG("'ladmin': End of connection, unknown packet (ip: %s)\n"_fmt,
ip);
@@ -2812,7 +2419,7 @@ void parse_admin(Session *s)
static
bool lan_ip_check(IP4Address p)
{
- bool lancheck = lan_subnet.covers(p);
+ bool lancheck = login_lan_conf.lan_subnet.covers(p);
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);
@@ -2833,7 +2440,7 @@ void parse_login(Session *s)
uint16_t packet_id;
while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id))
{
- if (display_parse_login == 1)
+ if (login_conf.display_parse_login)
{
if (packet_id == 0x64)
{
@@ -2895,10 +2502,10 @@ void parse_login(Session *s)
if (result == -1)
{
GmLevel gm_level = isGM(account.account_id);
- if (!(gm_level.satisfies(min_level_to_connect)))
+ if (!(gm_level.satisfies(login_conf.min_level_to_connect)))
{
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,
+ login_conf.min_level_to_connect, account.userid,
gm_level, ip);
Packet_Fixed<0x0081> fixed_81;
fixed_81.error_code = 1; // 01 = Server closed
@@ -2928,9 +2535,9 @@ void parse_login(Session *s)
*/
// if (version_2 & VERSION_2_UPDATEHOST)
{
- if (update_host)
+ if (login_conf.update_host)
{
- send_packet_repeatonly<0x0063, 4, 1>(s, update_host);
+ send_packet_repeatonly<0x0063, 4, 1>(s, login_conf.update_host);
}
}
@@ -2943,7 +2550,7 @@ void parse_login(Session *s)
{
Packet_Repeat<0x0069> info;
if (lan_ip_check(ip))
- info.ip = lan_char_ip;
+ info.ip = login_lan_conf.lan_char_ip;
else
info.ip = server[i].ip;
info.port = server[i].port;
@@ -3043,11 +2650,11 @@ void parse_login(Session *s)
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 (account.userid == login_conf.userid && account.passwd == login_conf.passwd)
{
// If this is the main server, and we don't already have a main server
if (!server_session[0]
- && server_name == main_server)
+ && server_name == login_conf.main_server)
{
account.account_id = wrap<AccountId>(0_u32);
goto x2710_okay;
@@ -3082,7 +2689,7 @@ void parse_login(Session *s)
//maintenance = RFIFOW(fd, 82);
//is_new = RFIFOW(fd, 84);
server_session[unwrap<AccountId>(account.account_id)] = s;
- if (anti_freeze_enable)
+ if (login_conf.anti_freeze_enable)
server_freezeflag[unwrap<AccountId>(account.account_id)] = 5; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
Packet_Fixed<0x2711> fixed_11;
@@ -3124,7 +2731,7 @@ void parse_login(Session *s)
Packet_Fixed<0x7531> fixed_31;
Version version = CURRENT_LOGIN_SERVER_VERSION;
- version.flags = new_account ? 1 : 0;
+ version.flags = login_conf.new_account ? 1 : 0;
fixed_31.version = version;
send_fpacket<0x7531, 10>(s, fixed_31);
break;
@@ -3163,8 +2770,8 @@ void parse_login(Session *s)
// non encrypted password
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))
+ if (login_conf.admin_state
+ && password == login_conf.admin_pass)
{
LOGIN_LOG("'ladmin'-login: Connection in administration mode accepted (non encrypted password: %s, ip: %s)\n"_fmt,
password, ip);
@@ -3172,7 +2779,7 @@ void parse_login(Session *s)
fixed_19.error = 0;
s->set_parsers(SessionParsers{.func_parse= parse_admin, .func_delete= delete_admin});
}
- else if (admin_state != 1)
+ else if (!login_conf.admin_state)
LOGIN_LOG("'ladmin'-login: Connection in administration mode REFUSED - remote administration is disabled (non encrypted password: %s, ip: %s)\n"_fmt,
password, ip);
else
@@ -3194,22 +2801,19 @@ void parse_login(Session *s)
default:
{
- if (save_unknown_packets)
{
- io::AppendFile logfp(login_log_unknown_packets_filename);
- if (logfp.is_open())
{
timestamp_milliseconds_buffer timestr;
stamp_time(timestr);
- FPRINTF(logfp,
+ FPRINTF(stderr,
"%s: receiving of an unknown packet -> disconnection\n"_fmt,
timestr);
- FPRINTF(logfp,
+ FPRINTF(stderr,
"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);
+ FPRINTF(stderr, "Detail (in hex):\n"_fmt);
+ packet_dump(s);
}
}
LOGIN_LOG("End of connection, unknown packet (ip: %s)\n"_fmt, ip);
@@ -3222,67 +2826,19 @@ void parse_login(Session *s)
s->set_eof();
}
-//----------------------------------
-// Reading Lan Support configuration
-//----------------------------------
-static
-bool login_lan_config(XString w1, ZString w2)
-{
- struct hostent *h = nullptr;
-
- {
- if (w1 == "lan_char_ip"_s)
- {
- // Read Char-Server Lan IP Address
- h = gethostbyname(w2.c_str());
- if (h != nullptr)
- {
- lan_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]),
- });
- }
- else
- {
- PRINTF("Bad IP value: %s\n"_fmt, w2);
- return false;
- }
- PRINTF("LAN IP of char-server: %s.\n"_fmt, lan_char_ip);
- }
- else if (w1 == "subnet"_s /*backward compatibility*/
- || w1 == "lan_subnet"_s)
- {
- if (!extract(w2, &lan_subnet))
- {
- PRINTF("Bad IP mask: %s\n"_fmt, w2);
- return false;
- }
- PRINTF("Sub-network of the char-server: %s.\n"_fmt,
- lan_subnet);
- }
- else
- {
- return false;
- }
- }
- return true;
-}
-
static
bool lan_check()
{
// log the LAN configuration
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 LAN IP of char-server: %s.\n"_fmt, login_lan_conf.lan_char_ip);
LOGIN_LOG("- with the sub-network of the char-server: %s.\n"_fmt,
- lan_subnet);
+ login_lan_conf.lan_subnet);
// sub-network check of the char-server
{
PRINTF("LAN test of LAN IP of the char-server: "_fmt);
- if (!lan_ip_check(lan_char_ip))
+ if (!lan_ip_check(login_lan_conf.lan_char_ip))
{
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);
@@ -3293,229 +2849,6 @@ bool lan_check()
return true;
}
-//-----------------------------------
-// Reading general configuration file
-//-----------------------------------
-static
-bool login_config(XString w1, ZString w2)
-{
- {
- if (w1 == "admin_state"_s)
- {
- admin_state = config_switch(w2);
- }
- else if (w1 == "admin_pass"_s)
- {
- admin_pass = stringish<AccountPass>(w2);
- }
- else if (w1 == "ladminallowip"_s)
- {
- 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"_s)
- {
- // reset all previous values
- access_ladmin.clear();
- // set to all
- access_ladmin.push_back(IP4Mask());
- }
- else if (w2
- && !(access_ladmin.size() == 1
- && access_ladmin.front().mask() == IP4Address()))
- {
- // don't add IP if already 'all'
- IP4Mask n;
- if (!extract(w2, &n))
- {
- PRINTF("Bad IP mask: %s\n"_fmt, w2);
- return false;
- }
- access_ladmin.push_back(n);
- }
- }
- }
- else if (w1 == "gm_pass"_s)
- {
- gm_pass = w2;
- }
- else if (w1 == "level_new_gm"_s)
- {
- level_new_gm = GmLevel::from(static_cast<uint32_t>(atoi(w2.c_str())));
- }
- else if (w1 == "new_account"_s)
- {
- new_account = config_switch(w2);
- }
- else if (w1 == "login_port"_s)
- {
- login_port = atoi(w2.c_str());
- }
- else if (w1 == "account_filename"_s)
- {
- account_filename = w2;
- }
- else if (w1 == "gm_account_filename"_s)
- {
- gm_account_filename = w2;
- }
- 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"_s)
- {
- login_log_filename = w2;
- }
- else if (w1 == "login_log_unknown_packets_filename"_s)
- {
- login_log_unknown_packets_filename = w2;
- }
- else if (w1 == "save_unknown_packets"_s)
- {
- save_unknown_packets = config_switch(w2);
- }
- else if (w1 == "display_parse_login"_s)
- {
- display_parse_login = config_switch(w2); // 0: no, 1: yes
- }
- else if (w1 == "display_parse_admin"_s)
- {
- display_parse_admin = config_switch(w2); // 0: no, 1: yes
- }
- 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"_s)
- {
- min_level_to_connect = GmLevel::from(static_cast<uint32_t>(atoi(w2.c_str())));
- }
- else if (w1 == "add_to_unlimited_account"_s)
- {
- add_to_unlimited_account = config_switch(w2);
- }
- else if (w1 == "start_limited_time"_s)
- {
- start_limited_time = atoi(w2.c_str());
- }
- else if (w1 == "check_ip_flag"_s)
- {
- check_ip_flag = config_switch(w2);
- }
- else if (w1 == "order"_s)
- {
- if (w2 == "deny,allow"_s || w2 == "deny, allow"_s)
- access_order = ACO::DENY_ALLOW;
- else if (w2 == "allow,deny"_s || w2 == "allow, deny"_s)
- access_order = ACO::ALLOW_DENY;
- else if (w2 == "mutual-failture"_s || w2 == "mutual-failure"_s)
- access_order = ACO::MUTUAL_FAILURE;
- else
- {
- PRINTF("Bad order: %s\n"_fmt, w2);
- return false;
- }
- }
- else if (w1 == "allow"_s)
- {
- if (w2 == "clear"_s)
- {
- access_allow.clear();
- }
- else
- {
- if (w2 == "all"_s)
- {
- // reset all previous values
- access_allow.clear();
- // set to all
- access_allow.push_back(IP4Mask());
- }
- else if (w2
- && !(access_allow.size() == 1
- && access_allow.front().mask() == IP4Address()))
- {
- // don't add IP if already 'all'
- IP4Mask n;
- if (!extract(w2, &n))
- {
- PRINTF("Bad IP mask: %s\n"_fmt, w2);
- return false;
- }
- access_allow.push_back(n);
- }
- }
- }
- else if (w1 == "deny"_s)
- {
- if (w2 == "clear"_s)
- {
- access_deny.clear();
- }
- else
- {
- if (w2 == "all"_s)
- {
- // reset all previous values
- access_deny.clear();
- // set to all
- access_deny.push_back(IP4Mask());
- }
- else if (w2
- && !(access_deny.size() == 1
- && access_deny.front().mask() == IP4Address()))
- {
- // don't add IP if already 'all'
- IP4Mask n;
- if (!extract(w2, &n))
- {
- PRINTF("Bad IP mask: %s\n"_fmt, w2);
- return false;
- }
- access_deny.push_back(n);
- }
- }
- }
- else if (w1 == "anti_freeze_enable"_s)
- {
- anti_freeze_enable = config_switch(w2);
- }
- else if (w1 == "anti_freeze_interval"_s)
- {
- anti_freeze_interval = std::max(
- std::chrono::seconds(atoi(w2.c_str())),
- 5_s);
- }
- else if (w1 == "update_host"_s)
- {
- update_host = w2;
- }
- else if (w1 == "main_server"_s)
- {
- main_server = stringish<ServerName>(w2);
- }
- else if (w1 == "userid"_s)
- {
- userid = stringish<AccountName>(w2);
- }
- else if (w1 == "passwd"_s)
- {
- passwd = stringish<AccountPass>(w2);
- }
- else
- {
- return false;
- }
- }
-
- return true;
-}
-
//-------------------------------------
// Displaying of configuration warnings
//-------------------------------------
@@ -3523,135 +2856,60 @@ static
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"_fmt);
- admin_state = 0;
- rv = false;
- }
- if (admin_state == 1)
+ if (login_conf.admin_state)
{
- if (!admin_pass)
+ if (!login_conf.admin_pass)
{
PRINTF("***WARNING: Administrator password is void (admin_pass).\n"_fmt);
rv = false;
}
- else if (admin_pass == stringish<AccountPass>("admin"_s))
+ else if (login_conf.admin_pass == stringish<AccountPass>("admin"_s))
{
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)
+ if (!login_conf.gm_pass)
{
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"_s)
+ else if (login_conf.gm_pass == "gm"_s)
{
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"_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"_fmt);
- login_port = 6900;
- rv = false;
- }
-
- if (gm_account_filename_check_timer.count() < 0)
+ if (login_conf.gm_account_filename_check_timer.count() < 0)
{
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;
+ login_conf.gm_account_filename_check_timer = 15_s;
rv = false;
}
- else if (gm_account_filename_check_timer == 1_s)
+ else if (login_conf.gm_account_filename_check_timer == 1_s)
{
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"_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"_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"_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"_fmt);
- PRINTF(" -> set to 0 (no display).\n"_fmt);
- display_parse_fromchar = 0;
- 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"_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"_fmt);
- PRINTF(" -> set to -1 (new accounts are created with unlimited time).\n"_fmt);
- start_limited_time = -1;
+ login_conf.gm_account_filename_check_timer = 2_s;
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"_fmt);
- PRINTF(" -> set to 1 (check players ip between login-server & char-server).\n"_fmt);
- check_ip_flag = 1;
- rv = false;
- }
-
- if (access_order == ACO::DENY_ALLOW)
+ if (login_conf.order == ACO::DENY_ALLOW)
{
- if (access_deny.size() == 1 && access_deny.front().mask() == IP4Address())
+ if (login_conf.deny.size() == 1 && login_conf.deny.front().mask() == IP4Address())
{
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;
}
}
- else if (access_order == ACO::ALLOW_DENY)
+ else if (login_conf.order == ACO::ALLOW_DENY)
{
- if (access_allow.empty())
+ if (login_conf.allow.empty())
{
PRINTF("***WARNING: The IP security order is 'allow,deny' (deny if not allow).\n"_fmt);
PRINTF(" But, NO IP IS AUTHORISED!\n"_fmt);
@@ -3661,14 +2919,14 @@ bool display_conf_warnings(void)
else
{
// ACO::MUTUAL_FAILURE
- if (access_allow.empty())
+ if (login_conf.allow.empty())
{
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())
+ else if (login_conf.deny.size() == 1 && login_conf.deny.front().mask() == IP4Address())
{
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);
@@ -3692,195 +2950,188 @@ void save_config_in_log(void)
// save configuration in log file
LOGIN_LOG("The configuration of the server is set:\n"_fmt);
- if (admin_state != 1)
+ if (!login_conf.admin_state)
LOGIN_LOG("- with no remote administration.\n"_fmt);
- else if (!admin_pass)
+ else if (!login_conf.admin_pass)
LOGIN_LOG("- with a remote administration with a VOID password.\n"_fmt);
- else if (admin_pass == stringish<AccountPass>("admin"_s))
+ else if (login_conf.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"_fmt,
- admin_pass.size());
- if (access_ladmin.empty()
- || (access_ladmin.size() == 1 && access_ladmin.front().mask() == IP4Address()))
+ login_conf.admin_pass.size());
+ if (login_conf.ladminallowip.empty()
+ || (login_conf.ladminallowip.size() == 1 && login_conf.ladminallowip.front().mask() == IP4Address()))
{
LOGIN_LOG("- to accept any IP for remote administration\n"_fmt);
}
else
{
LOGIN_LOG("- to accept following IP for remote administration:\n"_fmt);
- for (const IP4Mask& ae : access_ladmin)
+ for (const IP4Mask& ae : login_conf.ladminallowip)
LOGIN_LOG(" %s\n"_fmt, ae);
}
- if (!gm_pass)
+ if (!login_conf.gm_pass)
LOGIN_LOG("- with a VOID 'To GM become' password (gm_pass).\n"_fmt);
- else if (gm_pass == "gm"_s)
+ else if (login_conf.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"_fmt,
- gm_pass.size());
- if (!level_new_gm)
+ login_conf.gm_pass.size());
+ if (!login_conf.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"_fmt,
- level_new_gm);
+ login_conf.level_new_gm);
- if (new_account == 1)
+ if (login_conf.new_account)
LOGIN_LOG("- to ALLOW new users (with _F/_M).\n"_fmt);
else
LOGIN_LOG("- to NOT ALLOW new users (with _F/_M).\n"_fmt);
- LOGIN_LOG("- with port: %d.\n"_fmt, login_port);
+ LOGIN_LOG("- with port: %d.\n"_fmt, login_conf.login_port);
LOGIN_LOG("- with the accounts file name: '%s'.\n"_fmt,
- account_filename);
+ login_conf.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_conf.gm_account_filename);
+ if (login_conf.gm_account_filename_check_timer == interval_t::zero())
LOGIN_LOG("- to NOT check GM accounts file modifications.\n"_fmt);
else
LOGIN_LOG("- to check GM accounts file modifications every %lld seconds.\n"_fmt,
- maybe_cast<long long>(gm_account_filename_check_timer.count()));
+ maybe_cast<long long>(login_conf.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"_fmt,
- login_log_unknown_packets_filename);
- if (save_unknown_packets)
- 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"_fmt);
- if (display_parse_login)
+ if (login_conf.display_parse_login)
LOGIN_LOG("- to display normal parse packets on console.\n"_fmt);
else
LOGIN_LOG("- to NOT display normal parse packets on console.\n"_fmt);
- if (display_parse_admin)
+ if (login_conf.display_parse_admin)
LOGIN_LOG("- to display administration parse packets on console.\n"_fmt);
else
LOGIN_LOG("- to NOT display administration parse packets on console.\n"_fmt);
- if (display_parse_fromchar)
+ if (login_conf.display_parse_fromchar)
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"_fmt);
- if (!min_level_to_connect) // 0: all players, 1-99 at least gm level x
+ if (!login_conf.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"_fmt,
- min_level_to_connect);
-
- if (add_to_unlimited_account)
- 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"_fmt);
+ login_conf.min_level_to_connect);
- if (start_limited_time < 0)
- 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"_fmt);
- else
- 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"_fmt);
- else
- LOGIN_LOG("- to not check players IP between login-server and char-server.\n"_fmt);
-
- if (access_order == ACO::DENY_ALLOW)
+ if (login_conf.order == ACO::DENY_ALLOW)
{
- if (access_deny.empty())
+ if (login_conf.deny.empty())
{
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())
+ else if (login_conf.deny.size() == 1 && login_conf.deny.front().mask() == IP4Address())
{
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"_fmt);
- for (IP4Mask ae : access_deny)
+ for (IP4Mask ae : login_conf.deny)
LOGIN_LOG(" %s\n"_fmt, ae);
}
}
- else if (access_order == ACO::ALLOW_DENY)
+ else if (login_conf.order == ACO::ALLOW_DENY)
{
- if (access_allow.empty())
+ if (login_conf.allow.empty())
{
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())
+ else if (login_conf.allow.size() == 1 && login_conf.allow.front().mask() == IP4Address())
{
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"_fmt);
- for (IP4Mask ae : access_allow)
+ for (IP4Mask ae : login_conf.allow)
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"_fmt);
- if (access_allow.empty())
+ if (login_conf.allow.empty())
{
LOGIN_LOG(" But, NO IP IS AUTHORISED!\n"_fmt);
}
- else if (access_deny.size() == 1 && access_deny.front().mask() == IP4Address())
+ else if (login_conf.deny.size() == 1 && login_conf.deny.front().mask() == IP4Address())
{
LOGIN_LOG(" But, you refuse ALL IP!\n"_fmt);
}
else
{
- if (access_allow.size() == 1 && access_allow.front().mask() == IP4Address())
+ if (login_conf.allow.size() == 1 && login_conf.allow.front().mask() == IP4Address())
{
LOGIN_LOG(" You authorise ALL IP.\n"_fmt);
}
else
{
LOGIN_LOG(" Authorised IP are:\n"_fmt);
- for (IP4Mask ae : access_allow)
+ for (IP4Mask ae : login_conf.allow)
LOGIN_LOG(" %s\n"_fmt, ae);
}
LOGIN_LOG(" Refused IP are:\n"_fmt);
- for (IP4Mask ae : access_deny)
+ for (IP4Mask ae : login_conf.deny)
LOGIN_LOG(" %s\n"_fmt, ae);
}
}
}
+static
+bool login_config(io::Spanned<XString> key, io::Spanned<ZString> value)
+{
+ return parse_login_conf(login_conf, key, value);
+}
+
+static
+bool login_lan_config(io::Spanned<XString> key, io::Spanned<ZString> value)
+{
+ return parse_login_lan_conf(login_lan_conf, key, value);
+}
+
+static
+bool login_confs(io::Spanned<XString> key, io::Spanned<ZString> value)
+{
+ if (key.data == "login_conf"_s)
+ {
+ return load_config_file(value.data, login_config);
+ }
+ if (key.data == "login_lan_conf"_s)
+ {
+ return load_config_file(value.data, login_lan_config);
+ }
+ key.span.error("Unknown meta-key for login server"_s);
+ return false;
+}
+} // namespace login
+
//--------------------------------------
// Function called at exit of the server
//--------------------------------------
void term_func(void)
{
- mmo_auth_sync();
+ login::mmo_auth_sync();
- auth_data.clear();
- gm_account_db.clear();
- for (int i = 0; i < MAX_SERVERS; i++)
+ login::auth_data.clear();
+ login::gm_account_db.clear();
+ for (int i = 0; i < login::MAX_SERVERS; i++)
{
- Session *s = server_session[i];
+ Session *s = login::server_session[i];
if (s)
delete_session(s);
}
- delete_session(login_session);
+ delete_session(login::login_session);
LOGIN_LOG("----End of login-server (normal end with closing of all files).\n"_fmt);
}
-static
-bool login_confs(XString key, ZString value)
-{
- unsigned sum = 0;
- sum += login_config(key, value);
- sum += login_lan_config(key, value);
- if (sum >= 2)
- abort();
- return sum;
-}
-
//------------------------------
// Main function of login-server
//------------------------------
@@ -3913,59 +3164,60 @@ int do_init(Slice<ZString> argv)
else
{
loaded_config_yet = true;
- runflag &= load_config_file(argvi, login_confs);
+ runflag &= load_config_file(argvi, login::login_confs);
}
}
if (!loaded_config_yet)
- runflag &= load_config_file("conf/tmwa-login.conf"_s, login_confs);
+ runflag &= load_config_file("conf/tmwa-login.conf"_s, login::login_confs);
// not in login_config_read, because we can use 'import' option, and display same message twice or more
// (why is that bad?)
- runflag &= display_conf_warnings();
+ runflag &= login::display_conf_warnings();
// not before, because log file name can be changed
// (that doesn't stop the char-server though)
- save_config_in_log();
- runflag &= lan_check();
+ login::save_config_in_log();
+ runflag &= login::lan_check();
- for (int i = 0; i < AUTH_FIFO_SIZE; i++)
- auth_fifo[i].delflag = 1;
- for (int i = 0; i < MAX_SERVERS; i++)
- server_session[i] = nullptr;
+ for (int i = 0; i < login::AUTH_FIFO_SIZE; i++)
+ login::auth_fifo[i].delflag = 1;
+ for (int i = 0; i < login::MAX_SERVERS; i++)
+ login::server_session[i] = nullptr;
- read_gm_account();
- mmo_auth_init();
+ login::read_gm_account();
+ login::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::login_session = make_listen_port(login::login_conf.login_port, SessionParsers{.func_parse= login::parse_login, .func_delete= login::delete_login});
Timer(gettick() + 5_min,
- check_auth_sync,
+ login::check_auth_sync,
5_min
).detach();
- if (anti_freeze_enable > 0)
+ if (login::login_conf.anti_freeze_enable > 0)
{
Timer(gettick() + 1_s,
- char_anti_freeze_system,
- anti_freeze_interval
+ login::char_anti_freeze_system,
+ login::login_conf.anti_freeze_interval
).detach();
}
// add timer to check GM accounts file modification
- std::chrono::seconds j = gm_account_filename_check_timer;
+ std::chrono::seconds j = login::login_conf.gm_account_filename_check_timer;
if (j == interval_t::zero())
j = 1_min;
Timer(gettick() + j,
- check_GM_file,
+ login::check_GM_file,
j).detach();
LOGIN_LOG("The login-server is ready (Server is listening on the port %d).\n"_fmt,
- login_port);
+ login::login_conf.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);
+ login::login_conf.login_port);
return 0;
}
+// namespace login ends before term_func and do_init
} // namespace tmwa