add option to prevent concurrent logins; closes #511
This commit is contained in:
+14
-2
@@ -438,9 +438,21 @@ bool Client::can_use_chat_commands() const {
|
||||
|
||||
void Client::set_login(shared_ptr<Login> login) {
|
||||
this->login = login;
|
||||
|
||||
auto s = this->require_server_state();
|
||||
if (!s->allow_same_account_concurrent_logins) {
|
||||
auto it = s->client_for_account.find(login->account->account_id);
|
||||
if ((it != s->client_for_account.end()) && (it->second.get() != this)) {
|
||||
if (it->second->channel) {
|
||||
it->second->channel->disconnect();
|
||||
}
|
||||
s->client_for_account.erase(it);
|
||||
}
|
||||
s->client_for_account.emplace(this->login->account->account_id, this->shared_from_this());
|
||||
}
|
||||
|
||||
if (this->log.should_log(phosg::LogLevel::L_INFO)) {
|
||||
string login_str = this->login->str();
|
||||
this->log.info_f("Login: {}", login_str);
|
||||
this->log.info_f("Login: {}", this->login->str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -195,4 +195,11 @@ asio::awaitable<void> GameServer::destroy_client(std::shared_ptr<Client> c) {
|
||||
c->log.warning_f("Disconnect hook {} failed: {}", h_it.first, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
if (c->login) {
|
||||
auto it = this->state->client_for_account.find(c->login->account->account_id);
|
||||
if ((it != this->state->client_for_account.end()) && (it->second == c)) {
|
||||
this->state->client_for_account.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-3
@@ -15,9 +15,7 @@ struct GameServerSocket : ServerSocket {
|
||||
ServerBehavior behavior;
|
||||
};
|
||||
|
||||
class GameServer
|
||||
: public Server<Client, GameServerSocket>,
|
||||
public std::enable_shared_from_this<GameServer> {
|
||||
class GameServer : public Server<Client, GameServerSocket>, public std::enable_shared_from_this<GameServer> {
|
||||
public:
|
||||
GameServer() = delete;
|
||||
GameServer(const GameServer&) = delete;
|
||||
|
||||
@@ -865,6 +865,7 @@ void ServerState::load_config_early() {
|
||||
this->ip_stack_debug = this->config_json->get_bool("IPStackDebug", false);
|
||||
this->allow_unregistered_users = this->config_json->get_bool("AllowUnregisteredUsers", false);
|
||||
this->allow_pc_nte = this->config_json->get_bool("AllowPCNTE", false);
|
||||
this->allow_same_account_concurrent_logins = this->config_json->get_bool("AllowSameAccountConcurrentLogins", false);
|
||||
this->allow_saving_accounts = this->config_json->get_bool("AllowSavingAccounts", true);
|
||||
this->use_temp_accounts_for_prototypes = this->config_json->get_bool("UseTemporaryAccountsForPrototypes", true);
|
||||
this->notify_server_for_max_level_achieved = this->config_json->get_bool("NotifyServerForMaxLevelAchieved", false);
|
||||
|
||||
@@ -127,6 +127,7 @@ struct ServerState : public std::enable_shared_from_this<ServerState> {
|
||||
bool allow_unregistered_users = false;
|
||||
bool allow_pc_nte = false;
|
||||
bool use_temp_accounts_for_prototypes = true;
|
||||
bool allow_same_account_concurrent_logins = true;
|
||||
std::array<uint16_t, NUM_VERSIONS> compatibility_groups = {};
|
||||
bool enable_chat_commands = true;
|
||||
char chat_command_sentinel = '\0'; // 0 = default (@ on 11/2000; $ on all other versions)
|
||||
@@ -312,6 +313,8 @@ struct ServerState : public std::enable_shared_from_this<ServerState> {
|
||||
uint8_t pre_lobby_event = 0;
|
||||
int32_t ep3_menu_song = -1;
|
||||
|
||||
std::unordered_map<uint32_t, std::shared_ptr<Client>> client_for_account;
|
||||
|
||||
std::map<std::string, uint32_t> all_addresses;
|
||||
uint32_t local_address = 0;
|
||||
uint32_t external_address = 0;
|
||||
|
||||
@@ -226,6 +226,11 @@
|
||||
// Guild Card numbers every time they connect and cannot be banned by serial number or username.
|
||||
"AllowPCNTE": true,
|
||||
|
||||
// If this is enabled, players can log in multiple times on the same account at the same time. If this is disabled,
|
||||
// only one login is allowed per account at a time; when a new session is opened, any existing sessions on the same
|
||||
// account are disconnected.
|
||||
"AllowSameAccountConcurrentLogins": true,
|
||||
|
||||
// Whether to enable chat commands for all players. If this is true, all players will be able to use chat commands as
|
||||
// normal; if this is false, only players with the ALWAYS_ENABLE_CHAT_COMMANDS account flag will be able to use chat
|
||||
// commands.
|
||||
|
||||
@@ -190,6 +190,7 @@
|
||||
"AllowUnregisteredUsers": true,
|
||||
"UseTemporaryAccountsForPrototypes": true,
|
||||
"AllowPCNTE": true,
|
||||
"AllowSameAccountConcurrentLogins": true,
|
||||
"EnableChatCommands": true,
|
||||
"CompatibilityGroups": [0x0000, 0x0000, 0x0004, 0x0008, 0x00B0, 0x00B0, 0x0040, 0x00B0, 0x0100, 0x1200, 0x0400, 0x0800, 0x1200, 0x2000],
|
||||
"VersionNameColors": [
|
||||
|
||||
Reference in New Issue
Block a user