mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 23:01:30 +00:00
[Bug Fix] Fix IP Exemptions. (#2189)
* [Bug Fix] Fix IP Exemptions. - IP Exemptions were broken due to GetAccountID() returning 0 in logic somehow, resolved this by setting a variable to GetAccountID() at the beginning of the method. - Fixed weird IP messages where the long form of IP was displayed instead of the string form. - Fixes edge case where IP rule may be set to -1 and this will make anyone get instantly kicked if IP Exemptions were enabled as their IP Count would always be greater than -1. * Update client.cpp * Update client.cpp * Update clientlist.cpp * Update clientlist.cpp
This commit is contained in:
parent
aaaee6c6a4
commit
7de50d0e60
@ -1469,41 +1469,25 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16
|
|||||||
return base_cap;
|
return base_cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetCharacterInfo(
|
uint32 Database::GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id)
|
||||||
const char *iName,
|
|
||||||
uint32 *oAccID,
|
|
||||||
uint32 *oZoneID,
|
|
||||||
uint32 *oInstanceID,
|
|
||||||
float *oX,
|
|
||||||
float *oY,
|
|
||||||
float *oZ
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
std::string query = StringFormat(
|
auto query = fmt::format(
|
||||||
"SELECT `id`, `account_id`, `zone_id`, `zone_instance`, `x`, `y`, `z` FROM `character_data` WHERE `name` = '%s'",
|
"SELECT `id`, `account_id`, `zone_id`, `zone_instance` FROM `character_data` WHERE `name` = '{}'",
|
||||||
EscapeString(iName).c_str()
|
EscapeString(character_name)
|
||||||
);
|
);
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success() || !results.RowCount()) {
|
||||||
if (!results.Success()) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.RowCount() != 1) {
|
auto row = results.begin();
|
||||||
return 0;
|
auto character_id = std::stoul(row[0]);
|
||||||
}
|
*account_id = std::stoul(row[1]);
|
||||||
|
*zone_id = std::stoul(row[2]);
|
||||||
|
*instance_id = std::stoul(row[3]);
|
||||||
|
|
||||||
auto row = results.begin();
|
return character_id;
|
||||||
uint32 charid = atoi(row[0]);
|
|
||||||
if (oAccID) { *oAccID = atoi(row[1]); }
|
|
||||||
if (oZoneID) { *oZoneID = atoi(row[2]); }
|
|
||||||
if (oInstanceID) { *oInstanceID = atoi(row[3]); }
|
|
||||||
if (oX) { *oX = atof(row[4]); }
|
|
||||||
if (oY) { *oY = atof(row[5]); }
|
|
||||||
if (oZ) { *oZ = atof(row[6]); }
|
|
||||||
|
|
||||||
return charid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::UpdateLiveChar(char* charname, uint32 account_id) {
|
bool Database::UpdateLiveChar(char* charname, uint32 account_id) {
|
||||||
@ -1627,29 +1611,36 @@ uint32 Database::GetGroupID(const char* name){
|
|||||||
return atoi(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is this really getting used properly... A half implementation ? Akkadius */
|
std::string Database::GetGroupLeaderForLogin(std::string character_name) {
|
||||||
char* Database::GetGroupLeaderForLogin(const char* name, char* leaderbuf) {
|
|
||||||
strcpy(leaderbuf, "");
|
|
||||||
uint32 group_id = 0;
|
uint32 group_id = 0;
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT `groupid` FROM `group_id` WHERE `name` = '%s'", name);
|
auto query = fmt::format(
|
||||||
|
"SELECT `groupid` FROM `group_id` WHERE `name` = '{}'",
|
||||||
|
character_name
|
||||||
|
);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row)
|
if (results.Success() && results.RowCount()) {
|
||||||
if (row[0])
|
auto row = results.begin();
|
||||||
group_id = atoi(row[0]);
|
group_id = std::stoul(row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
if (group_id == 0)
|
if (!group_id) {
|
||||||
return leaderbuf;
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
query = StringFormat("SELECT `leadername` FROM `group_leaders` WHERE `gid` = '%u' LIMIT 1", group_id);
|
query = fmt::format(
|
||||||
|
"SELECT `leadername` FROM `group_leaders` WHERE `gid` = {} LIMIT 1",
|
||||||
|
group_id
|
||||||
|
);
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row)
|
if (results.Success() && results.RowCount()) {
|
||||||
if (row[0])
|
auto row = results.begin();
|
||||||
strcpy(leaderbuf, row[0]);
|
return row[0];
|
||||||
|
}
|
||||||
|
|
||||||
return leaderbuf;
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetGroupLeaderName(uint32 gid, const char* name) {
|
void Database::SetGroupLeaderName(uint32 gid, const char* name) {
|
||||||
@ -2244,28 +2235,32 @@ bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Database::GetIPExemption(std::string account_ip) {
|
int Database::GetIPExemption(std::string account_ip) {
|
||||||
std::string query = StringFormat("SELECT `exemption_amount` FROM `ip_exemptions` WHERE `exemption_ip` = '%s'", account_ip.c_str());
|
auto query = fmt::format(
|
||||||
auto results = QueryDatabase(query);
|
"SELECT `exemption_amount` FROM `ip_exemptions` WHERE `exemption_ip` = '{}'",
|
||||||
|
|
||||||
if (results.Success() && results.RowCount() > 0) {
|
|
||||||
auto row = results.begin();
|
|
||||||
return atoi(row[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return RuleI(World, MaxClientsPerIP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
|
||||||
std::string query = fmt::format(
|
|
||||||
"SELECT `exemption_id` FROM `ip_exemptions` WHERE `exemption_ip` = '{}'",
|
|
||||||
account_ip
|
account_ip
|
||||||
);
|
);
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success() || !results.RowCount()) {
|
||||||
|
return RuleI(World, MaxClientsPerIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
return std::stoi(row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
||||||
|
auto query = fmt::format(
|
||||||
|
"SELECT `exemption_id` FROM `ip_exemptions` WHERE `exemption_ip` = '{}'",
|
||||||
|
account_ip
|
||||||
|
);
|
||||||
|
|
||||||
uint32 exemption_id = 0;
|
uint32 exemption_id = 0;
|
||||||
if (results.Success() && results.RowCount() > 0) {
|
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if (results.Success() && results.RowCount()) {
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
exemption_id = atoi(row[0]);
|
exemption_id = std::stoul(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
@ -2274,13 +2269,14 @@ void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
|||||||
exemption_amount
|
exemption_amount
|
||||||
);
|
);
|
||||||
|
|
||||||
if (exemption_id != 0) {
|
if (exemption_id) {
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
"UPDATE `ip_exemptions` SET `exemption_amount` = {} WHERE `exemption_ip` = '{}'",
|
"UPDATE `ip_exemptions` SET `exemption_amount` = {} WHERE `exemption_ip` = '{}'",
|
||||||
exemption_amount,
|
exemption_amount,
|
||||||
account_ip
|
account_ip
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryDatabase(query);
|
QueryDatabase(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -131,7 +131,7 @@ public:
|
|||||||
uint32 GetAccountIDByChar(uint32 char_id);
|
uint32 GetAccountIDByChar(uint32 char_id);
|
||||||
uint32 GetAccountIDByName(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
|
uint32 GetAccountIDByName(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
|
||||||
uint32 GetCharacterID(const char *name);
|
uint32 GetCharacterID(const char *name);
|
||||||
uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0);
|
uint32 GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id);
|
||||||
uint32 GetGuildIDByCharID(uint32 char_id);
|
uint32 GetGuildIDByCharID(uint32 char_id);
|
||||||
uint32 GetGroupIDByCharID(uint32 char_id);
|
uint32 GetGroupIDByCharID(uint32 char_id);
|
||||||
uint32 GetRaidIDByCharID(uint32 char_id);
|
uint32 GetRaidIDByCharID(uint32 char_id);
|
||||||
@ -207,8 +207,8 @@ public:
|
|||||||
|
|
||||||
/* Groups */
|
/* Groups */
|
||||||
|
|
||||||
char* GetGroupLeaderForLogin(const char* name,char* leaderbuf);
|
std::string GetGroupLeaderForLogin(std::string character_name);
|
||||||
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||||
|
|
||||||
uint32 GetGroupID(const char* name);
|
uint32 GetGroupID(const char* name);
|
||||||
|
|
||||||
|
|||||||
219
world/client.cpp
219
world/client.cpp
@ -721,38 +721,40 @@ bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||||
if (GetAccountID() == 0) {
|
auto account_id = GetAccountID();
|
||||||
LogInfo("Enter world with no logged in account");
|
if (!account_id) {
|
||||||
|
LogInfo("Enter world with no logged in account.");
|
||||||
eqs->Close();
|
eqs->Close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetAdmin() < 0)
|
if (GetAdmin() < 0) {
|
||||||
{
|
LogInfo("Account [{}] is banned or suspended.", account_id);
|
||||||
LogInfo("Account banned or suspended");
|
|
||||||
eqs->Close();
|
eqs->Close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RuleB(World, EnableIPExemptions) || RuleI(World, MaxClientsPerIP) >= 0) {
|
if (
|
||||||
|
RuleB(World, EnableIPExemptions) ||
|
||||||
|
RuleI(World, MaxClientsPerIP) > 0
|
||||||
|
) {
|
||||||
client_list.GetCLEIP(GetIP()); //Check current CLE Entry IPs against incoming connection
|
client_list.GetCLEIP(GetIP()); //Check current CLE Entry IPs against incoming connection
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterWorld_Struct *ew=(EnterWorld_Struct *)app->pBuffer;
|
auto ew = (EnterWorld_Struct *) app->pBuffer;
|
||||||
strn0cpy(char_name, ew->name, 64);
|
strn0cpy(char_name, ew->name, sizeof(char_name));
|
||||||
|
|
||||||
EQApplicationPacket *outapp;
|
uint32 temporary_account_id = 0;
|
||||||
uint32 tmpaccid = 0;
|
charid = database.GetCharacterInfo(char_name, &temporary_account_id, &zone_id, &instance_id);
|
||||||
charid = database.GetCharacterInfo(char_name, &tmpaccid, &zone_id, &instance_id);
|
if (!charid) {
|
||||||
if (charid == 0) {
|
|
||||||
LogInfo("Could not get CharInfo for [{}]", char_name);
|
LogInfo("Could not get CharInfo for [{}]", char_name);
|
||||||
eqs->Close();
|
eqs->Close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure this account owns this character
|
// Make sure this account owns this character
|
||||||
if (tmpaccid != GetAccountID()) {
|
if (temporary_account_id != account_id) {
|
||||||
LogInfo("This account does not own the character named [{}]", char_name);
|
LogInfo("Account [{}] does not own the character named [{}] from account [{}]", account_id, char_name, temporary_account_id);
|
||||||
eqs->Close();
|
eqs->Close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -761,25 +763,26 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
|||||||
// (This is a literal translation of the original process..I don't see why it can't be changed to a single-target query over account iteration)
|
// (This is a literal translation of the original process..I don't see why it can't be changed to a single-target query over account iteration)
|
||||||
if (!is_player_zoning) {
|
if (!is_player_zoning) {
|
||||||
size_t character_limit = EQ::constants::StaticLookup(eqs->ClientVersion())->CharacterCreationLimit;
|
size_t character_limit = EQ::constants::StaticLookup(eqs->ClientVersion())->CharacterCreationLimit;
|
||||||
if (character_limit > EQ::constants::CHARACTER_CREATION_LIMIT) { character_limit = EQ::constants::CHARACTER_CREATION_LIMIT; }
|
if (character_limit > EQ::constants::CHARACTER_CREATION_LIMIT) {
|
||||||
if (eqs->ClientVersion() == EQ::versions::ClientVersion::Titanium) { character_limit = Titanium::constants::CHARACTER_CREATION_LIMIT; }
|
character_limit = EQ::constants::CHARACTER_CREATION_LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
std::string tgh_query = StringFormat(
|
if (eqs->ClientVersion() == EQ::versions::ClientVersion::Titanium) {
|
||||||
"SELECT "
|
character_limit = Titanium::constants::CHARACTER_CREATION_LIMIT;
|
||||||
"`id`, "
|
}
|
||||||
"name, "
|
|
||||||
"`level`, "
|
auto query = fmt::format(
|
||||||
"last_login "
|
"SELECT `id`, `name`, `level`, `last_login` FROM character_data WHERE `account_id` = {} ORDER BY `name` LIMIT {}",
|
||||||
"FROM "
|
account_id,
|
||||||
"character_data "
|
character_limit
|
||||||
"WHERE `account_id` = %i ORDER BY `name` LIMIT %u", GetAccountID(), character_limit);
|
);
|
||||||
auto tgh_results = database.QueryDatabase(tgh_query);
|
auto results = database.QueryDatabase(query);
|
||||||
|
|
||||||
/* Check GoHome */
|
/* Check GoHome */
|
||||||
if (ew->return_home && !ew->tutorial) {
|
if (ew->return_home && !ew->tutorial) {
|
||||||
bool home_enabled = false;
|
bool home_enabled = false;
|
||||||
for (auto row = tgh_results.begin(); row != tgh_results.end(); ++row) {
|
for (auto row : results) {
|
||||||
if (strcasecmp(row[1], char_name) == 0) {
|
if (!strcasecmp(row[1], char_name)) {
|
||||||
if (RuleB(World, EnableReturnHomeButton)) {
|
if (RuleB(World, EnableReturnHomeButton)) {
|
||||||
int now = time(nullptr);
|
int now = time(nullptr);
|
||||||
if ((now - atoi(row[3])) >= RuleI(World, MinOfflineTimeToReturnHome)) {
|
if ((now - atoi(row[3])) >= RuleI(World, MinOfflineTimeToReturnHome)) {
|
||||||
@ -792,9 +795,8 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
|||||||
|
|
||||||
if (home_enabled) {
|
if (home_enabled) {
|
||||||
zone_id = database.MoveCharacterToBind(charid, 4);
|
zone_id = database.MoveCharacterToBind(charid, 4);
|
||||||
}
|
} else {
|
||||||
else {
|
LogInfo("[{}] is trying to go home before they're able.", char_name);
|
||||||
LogInfo("[{}] is trying to go home before they're able", char_name);
|
|
||||||
database.SetHackerFlag(GetAccountName(), char_name, "MQGoHome: player tried to go home before they were able.");
|
database.SetHackerFlag(GetAccountName(), char_name, "MQGoHome: player tried to go home before they were able.");
|
||||||
eqs->Close();
|
eqs->Close();
|
||||||
return true;
|
return true;
|
||||||
@ -804,9 +806,12 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
|||||||
/* Check Tutorial*/
|
/* Check Tutorial*/
|
||||||
if (RuleB(World, EnableTutorialButton) && (ew->tutorial || StartInTutorial)) {
|
if (RuleB(World, EnableTutorialButton) && (ew->tutorial || StartInTutorial)) {
|
||||||
bool tutorial_enabled = false;
|
bool tutorial_enabled = false;
|
||||||
for (auto row = tgh_results.begin(); row != tgh_results.end(); ++row) {
|
for (auto row : results) {
|
||||||
if (strcasecmp(row[1], char_name) == 0) {
|
if (!strcasecmp(row[1], char_name)) {
|
||||||
if (RuleB(World, EnableTutorialButton) && ((uint8)atoi(row[2]) <= RuleI(World, MaxLevelForTutorial))) {
|
if (
|
||||||
|
RuleB(World, EnableTutorialButton) &&
|
||||||
|
std::stoi(row[2]) <= RuleI(World, MaxLevelForTutorial)
|
||||||
|
) {
|
||||||
tutorial_enabled = true;
|
tutorial_enabled = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -816,9 +821,8 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
|||||||
if (tutorial_enabled) {
|
if (tutorial_enabled) {
|
||||||
zone_id = RuleI(World, TutorialZoneID);
|
zone_id = RuleI(World, TutorialZoneID);
|
||||||
database.MoveCharacterToZone(charid, zone_id);
|
database.MoveCharacterToZone(charid, zone_id);
|
||||||
}
|
} else {
|
||||||
else {
|
LogInfo("[{}] is trying to go to the Tutorial but they are not allowed.", char_name);
|
||||||
LogInfo("[{}] is trying to go to tutorial but are not allowed", char_name);
|
|
||||||
database.SetHackerFlag(GetAccountName(), char_name, "MQTutorial: player tried to enter the tutorial without having tutorial enabled for this character.");
|
database.SetHackerFlag(GetAccountName(), char_name, "MQTutorial: player tried to enter the tutorial without having tutorial enabled for this character.");
|
||||||
eqs->Close();
|
eqs->Close();
|
||||||
return true;
|
return true;
|
||||||
@ -826,17 +830,17 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zone_id == 0 || !ZoneName(zone_id)) {
|
if (!zone_id || !ZoneName(zone_id)) {
|
||||||
// This is to save people in an invalid zone, once it's removed from the DB
|
// This is to save people in an invalid zone, once it's removed from the DB
|
||||||
database.MoveCharacterToZone(charid, ZoneID("arena"));
|
database.MoveCharacterToZone(charid, ZoneID("arena"));
|
||||||
LogInfo("Zone not found in database zone_id=[{}], moveing char to arena character:[{}]", zone_id, char_name);
|
LogInfo("Zone [{}] not found, moving [{}] to Arena.", zone_id, char_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(instance_id > 0)
|
if (instance_id) {
|
||||||
{
|
if (
|
||||||
if (!database.VerifyInstanceAlive(instance_id, GetCharID()) ||
|
!database.VerifyInstanceAlive(instance_id, GetCharID()) ||
|
||||||
!database.VerifyZoneInstance(zone_id, instance_id))
|
!database.VerifyZoneInstance(zone_id, instance_id)
|
||||||
{
|
) {
|
||||||
zone_id = database.MoveCharacterToInstanceSafeReturn(charid, zone_id, instance_id);
|
zone_id = database.MoveCharacterToInstanceSafeReturn(charid, zone_id, instance_id);
|
||||||
instance_id = 0;
|
instance_id = 0;
|
||||||
}
|
}
|
||||||
@ -845,83 +849,80 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
|||||||
if(!is_player_zoning) {
|
if(!is_player_zoning) {
|
||||||
database.SetGroupID(char_name, 0, charid);
|
database.SetGroupID(char_name, 0, charid);
|
||||||
database.SetLoginFlags(charid, false, false, 1);
|
database.SetLoginFlags(charid, false, false, 1);
|
||||||
}
|
} else {
|
||||||
else{
|
auto group_id = database.GetGroupID(char_name);
|
||||||
uint32 groupid = database.GetGroupID(char_name);
|
if (group_id) {
|
||||||
if(groupid > 0){
|
auto leader_name = database.GetGroupLeaderForLogin(char_name);
|
||||||
char* leader = 0;
|
if (!leader_name.empty()) {
|
||||||
char leaderbuf[64] = {0};
|
auto pack = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
|
||||||
if((leader = database.GetGroupLeaderForLogin(char_name, leaderbuf)) && strlen(leader)>1){
|
auto gj = (GroupJoin_Struct*) pack->pBuffer;
|
||||||
auto outapp3 = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
|
|
||||||
GroupJoin_Struct* gj=(GroupJoin_Struct*)outapp3->pBuffer;
|
|
||||||
gj->action=8;
|
gj->action=8;
|
||||||
strcpy(gj->yourname, char_name);
|
strn0cpy(gj->yourname, char_name, sizeof(gj->yourname));
|
||||||
strcpy(gj->membername, leader);
|
strn0cpy(gj->membername, leader_name.c_str(), sizeof(gj->membername));
|
||||||
QueuePacket(outapp3);
|
QueuePacket(pack);
|
||||||
safe_delete(outapp3);
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outapp = new EQApplicationPacket(OP_MOTD);
|
auto outapp = new EQApplicationPacket(OP_MOTD);
|
||||||
std::string tmp;
|
std::string motd_message;
|
||||||
if (database.GetVariable("MOTD", tmp)) {
|
if (database.GetVariable("MOTD", motd_message)) {
|
||||||
outapp->size = tmp.length() + 1;
|
outapp->size = motd_message.length() + 1;
|
||||||
outapp->pBuffer = new uchar[outapp->size];
|
outapp->pBuffer = new uchar[outapp->size];
|
||||||
memset(outapp->pBuffer,0,outapp->size);
|
memset(outapp->pBuffer, 0, outapp->size);
|
||||||
strcpy((char*)outapp->pBuffer, tmp.c_str());
|
strcpy((char*)outapp->pBuffer, motd_message.c_str());
|
||||||
|
} else { // Null Message of the Day. :)
|
||||||
} else {
|
|
||||||
// Null Message of the Day. :)
|
|
||||||
outapp->size = 1;
|
outapp->size = 1;
|
||||||
outapp->pBuffer = new uchar[outapp->size];
|
outapp->pBuffer = new uchar[outapp->size];
|
||||||
outapp->pBuffer[0] = 0;
|
outapp->pBuffer[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
// set mailkey - used for duration of character session
|
// set mailkey - used for duration of character session
|
||||||
int MailKey = emu_random.Int(1, INT_MAX);
|
int mail_key = emu_random.Int(1, INT_MAX);
|
||||||
|
|
||||||
database.SetMailKey(charid, GetIP(), MailKey);
|
database.SetMailKey(charid, GetIP(), mail_key);
|
||||||
if (UCSServerAvailable_) {
|
if (UCSServerAvailable_) {
|
||||||
const WorldConfig *Config = WorldConfig::get();
|
auto config = WorldConfig::get();
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
|
|
||||||
EQ::versions::UCSVersion ConnectionType = EQ::versions::ucsUnknown;
|
auto connection_type = EQ::versions::ucsUnknown;
|
||||||
|
|
||||||
// chat server packet
|
// chat server packet
|
||||||
switch (GetClientVersion()) {
|
switch (GetClientVersion()) {
|
||||||
case EQ::versions::ClientVersion::Titanium:
|
case EQ::versions::ClientVersion::Titanium:
|
||||||
ConnectionType = EQ::versions::ucsTitaniumChat;
|
connection_type = EQ::versions::ucsTitaniumChat;
|
||||||
break;
|
break;
|
||||||
case EQ::versions::ClientVersion::SoF:
|
case EQ::versions::ClientVersion::SoF:
|
||||||
ConnectionType = EQ::versions::ucsSoFCombined;
|
connection_type = EQ::versions::ucsSoFCombined;
|
||||||
break;
|
break;
|
||||||
case EQ::versions::ClientVersion::SoD:
|
case EQ::versions::ClientVersion::SoD:
|
||||||
ConnectionType = EQ::versions::ucsSoDCombined;
|
connection_type = EQ::versions::ucsSoDCombined;
|
||||||
break;
|
break;
|
||||||
case EQ::versions::ClientVersion::UF:
|
case EQ::versions::ClientVersion::UF:
|
||||||
ConnectionType = EQ::versions::ucsUFCombined;
|
connection_type = EQ::versions::ucsUFCombined;
|
||||||
break;
|
break;
|
||||||
case EQ::versions::ClientVersion::RoF:
|
case EQ::versions::ClientVersion::RoF:
|
||||||
ConnectionType = EQ::versions::ucsRoFCombined;
|
connection_type = EQ::versions::ucsRoFCombined;
|
||||||
break;
|
break;
|
||||||
case EQ::versions::ClientVersion::RoF2:
|
case EQ::versions::ClientVersion::RoF2:
|
||||||
ConnectionType = EQ::versions::ucsRoF2Combined;
|
connection_type = EQ::versions::ucsRoF2Combined;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ConnectionType = EQ::versions::ucsUnknown;
|
connection_type = EQ::versions::ucsUnknown;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = StringFormat("%s,%i,%s.%s,%c%08X",
|
buffer = fmt::format("{},{},{}.{},{}{:08X}",
|
||||||
Config->ChatHost.c_str(),
|
config->ChatHost,
|
||||||
Config->ChatPort,
|
config->ChatPort,
|
||||||
Config->ShortName.c_str(),
|
config->ShortName,
|
||||||
GetCharName(),
|
GetCharName(),
|
||||||
ConnectionType,
|
static_cast<char>(connection_type),
|
||||||
MailKey
|
mail_key
|
||||||
);
|
);
|
||||||
|
|
||||||
outapp = new EQApplicationPacket(OP_SetChatServer, (buffer.length() + 1));
|
outapp = new EQApplicationPacket(OP_SetChatServer, (buffer.length() + 1));
|
||||||
@ -933,21 +934,21 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
|||||||
|
|
||||||
// mail server packet
|
// mail server packet
|
||||||
switch (GetClientVersion()) {
|
switch (GetClientVersion()) {
|
||||||
case EQ::versions::ClientVersion::Titanium:
|
case EQ::versions::ClientVersion::Titanium:
|
||||||
ConnectionType = EQ::versions::ucsTitaniumMail;
|
connection_type = EQ::versions::ucsTitaniumMail;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// retain value from previous switch
|
// retain value from previous switch
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = StringFormat("%s,%i,%s.%s,%c%08X",
|
buffer = fmt::format("{},{},{}.{},{}{:08X}",
|
||||||
Config->MailHost.c_str(),
|
config->MailHost,
|
||||||
Config->MailPort,
|
config->MailPort,
|
||||||
Config->ShortName.c_str(),
|
config->ShortName,
|
||||||
GetCharName(),
|
GetCharName(),
|
||||||
ConnectionType,
|
static_cast<char>(connection_type),
|
||||||
MailKey
|
mail_key
|
||||||
);
|
);
|
||||||
|
|
||||||
outapp = new EQApplicationPacket(OP_SetChatServer2, (buffer.length() + 1));
|
outapp = new EQApplicationPacket(OP_SetChatServer2, (buffer.length() + 1));
|
||||||
|
|||||||
@ -100,67 +100,101 @@ ClientListEntry* ClientList::GetCLE(uint32 iID) {
|
|||||||
|
|
||||||
//Check current CLE Entry IPs against incoming connection
|
//Check current CLE Entry IPs against incoming connection
|
||||||
|
|
||||||
void ClientList::GetCLEIP(uint32 iIP) {
|
void ClientList::GetCLEIP(uint32 in_ip) {
|
||||||
ClientListEntry* countCLEIPs = 0;
|
ClientListEntry* cle = nullptr;
|
||||||
LinkedListIterator<ClientListEntry*> iterator(clientlist);
|
LinkedListIterator<ClientListEntry*> iterator(clientlist);
|
||||||
|
|
||||||
int IPInstances = 0;
|
int count = 0;
|
||||||
iterator.Reset();
|
iterator.Reset();
|
||||||
|
|
||||||
while(iterator.MoreElements()) {
|
while (iterator.MoreElements()) {
|
||||||
countCLEIPs = iterator.GetData();
|
cle = iterator.GetData();
|
||||||
if ((countCLEIPs->GetIP() == iIP) && ((countCLEIPs->Admin() < (RuleI(World, ExemptMaxClientsStatus))) || (RuleI(World, ExemptMaxClientsStatus) < 0))) { // If the IP matches, and the connection admin status is below the exempt status, or exempt status is less than 0 (no-one is exempt)
|
if (
|
||||||
IPInstances++; // Increment the occurences of this IP address
|
cle->GetIP() == in_ip &&
|
||||||
LogClientLogin("Account ID: [{}] Account Name: [{}] IP: [{}]", countCLEIPs->LSID(), countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str());
|
(
|
||||||
|
cle->Admin() < RuleI(World, ExemptMaxClientsStatus) ||
|
||||||
|
RuleI(World, ExemptMaxClientsStatus) < 0
|
||||||
|
)
|
||||||
|
) { // If the IP matches, and the connection admin status is below the exempt status, or exempt status is less than 0 (no-one is exempt)
|
||||||
|
auto ip_string = long2ip(cle->GetIP());
|
||||||
|
count++; // Increment the occurences of this IP address
|
||||||
|
LogClientLogin("Account ID: [{}] Account Name: [{}] IP: [{}]", cle->LSID(), cle->LSName(), ip_string);
|
||||||
|
|
||||||
if (RuleB(World, EnableIPExemptions)) {
|
if (RuleB(World, EnableIPExemptions)) {
|
||||||
LogClientLogin("Account ID: [{}] Account Name: [{}] IP: [{}] IP Instances: [{}] Max IP Instances: [{}]", countCLEIPs->LSID(), countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str(), IPInstances, database.GetIPExemption(long2ip(countCLEIPs->GetIP()).c_str()));
|
LogClientLogin(
|
||||||
if (IPInstances > database.GetIPExemption(long2ip(countCLEIPs->GetIP()).c_str())) {
|
"Account ID: [{}] Account Name: [{}] IP: [{}] IP Instances: [{}] Max IP Instances: [{}]",
|
||||||
if(RuleB(World, IPLimitDisconnectAll)) {
|
cle->LSID(),
|
||||||
LogClientLogin("Disconnect: All accounts on IP [{}]", long2ip(countCLEIPs->GetIP()).c_str());
|
cle->LSName(),
|
||||||
DisconnectByIP(iIP);
|
ip_string,
|
||||||
|
count,
|
||||||
|
database.GetIPExemption(ip_string)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto exemption_amount = database.GetIPExemption(ip_string);
|
||||||
|
if (exemption_amount > 0 && count > exemption_amount) {
|
||||||
|
if (RuleB(World, IPLimitDisconnectAll)) {
|
||||||
|
LogClientLogin("Disconnect: All Accounts on IP [{}]", ip_string);
|
||||||
|
DisconnectByIP(in_ip);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
LogClientLogin("Disconnect: Account [{}] on IP [{}]", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str());
|
LogClientLogin("Disconnect: Account [{}] on IP [{}]", cle->LSName(), ip_string);
|
||||||
countCLEIPs->SetOnline(CLE_Status::Offline);
|
cle->SetOnline(CLE_Status::Offline);
|
||||||
iterator.RemoveCurrent();
|
iterator.RemoveCurrent();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (IPInstances > (RuleI(World, MaxClientsPerIP))) { // If the number of connections exceeds the lower limit
|
if (
|
||||||
|
RuleI(World, MaxClientsPerIP) > 0 &&
|
||||||
|
count > RuleI(World, MaxClientsPerIP)
|
||||||
|
) { // If the number of connections exceeds the lower limit
|
||||||
if (RuleB(World, MaxClientsSetByStatus)) { // If MaxClientsSetByStatus is set to True, override other IP Limit Rules
|
if (RuleB(World, MaxClientsSetByStatus)) { // If MaxClientsSetByStatus is set to True, override other IP Limit Rules
|
||||||
LogClientLogin("Account ID: [{}] Account Name: [{}] IP: [{}] IP Instances: [{}] Max IP Instances: [{}]", countCLEIPs->LSID(), countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str(), IPInstances, countCLEIPs->Admin());
|
LogClientLogin(
|
||||||
if (IPInstances > countCLEIPs->Admin()) { // The IP Limit is set by the status of the account if status > MaxClientsPerIP
|
"Account ID: [{}] Account Name: [{}] IP: [{}] IP Instances: [{}] Max IP Instances: [{}]",
|
||||||
if(RuleB(World, IPLimitDisconnectAll)) {
|
cle->LSID(),
|
||||||
LogClientLogin("Disconnect: All accounts on IP [{}]", long2ip(countCLEIPs->GetIP()).c_str());
|
cle->LSName(),
|
||||||
DisconnectByIP(iIP);
|
ip_string,
|
||||||
|
count,
|
||||||
|
cle->Admin()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (count > cle->Admin()) { // The IP Limit is set by the status of the account if status > MaxClientsPerIP
|
||||||
|
if (RuleB(World, IPLimitDisconnectAll)) {
|
||||||
|
LogClientLogin("Disconnect: All Accounts on IP [{}]", ip_string);
|
||||||
|
DisconnectByIP(in_ip);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
LogClientLogin("Disconnect: Account [{}] on IP [{}]", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str());
|
LogClientLogin("Disconnect: Account [{}] on IP [{}]", cle->LSName(), ip_string);
|
||||||
countCLEIPs->SetOnline(CLE_Status::Offline); // Remove the connection
|
cle->SetOnline(CLE_Status::Offline); // Remove the connection
|
||||||
iterator.RemoveCurrent();
|
iterator.RemoveCurrent();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((countCLEIPs->Admin() < RuleI(World, AddMaxClientsStatus)) || (RuleI(World, AddMaxClientsStatus) < 0)) { // Else if the Admin status of the connection is not eligible for the higher limit, or there is no higher limit (AddMaxClientStatus < 0)
|
} else if (
|
||||||
if(RuleB(World, IPLimitDisconnectAll)) {
|
cle->Admin() < RuleI(World, AddMaxClientsStatus) ||
|
||||||
LogClientLogin("Disconnect: All accounts on IP [{}]", long2ip(countCLEIPs->GetIP()).c_str());
|
RuleI(World, AddMaxClientsStatus) < 0
|
||||||
DisconnectByIP(iIP);
|
) { // Else if the Admin status of the connection is not eligible for the higher limit, or there is no higher limit (AddMaxClientStatus < 0)
|
||||||
|
if (RuleB(World, IPLimitDisconnectAll)) {
|
||||||
|
LogClientLogin("Disconnect: All Accounts on IP [{}]", ip_string);
|
||||||
|
DisconnectByIP(in_ip);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
LogClientLogin("Disconnect: Account [{}] on IP [{}]", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str());
|
LogClientLogin("Disconnect: Account [{}] on IP [{}]", cle->LSName(), ip_string);
|
||||||
countCLEIPs->SetOnline(CLE_Status::Offline); // Remove the connection
|
cle->SetOnline(CLE_Status::Offline); // Remove the connection
|
||||||
iterator.RemoveCurrent();
|
iterator.RemoveCurrent();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (IPInstances > RuleI(World, AddMaxClientsPerIP)) { // else they are eligible for the higher limit, but if they exceed that
|
} else if (
|
||||||
if(RuleB(World, IPLimitDisconnectAll)) {
|
RuleI(World, AddMaxClientsPerIP) > 0 &&
|
||||||
LogClientLogin("Disconnect: All accounts on IP [{}]", long2ip(countCLEIPs->GetIP()).c_str());
|
count > RuleI(World, AddMaxClientsPerIP)
|
||||||
DisconnectByIP(iIP);
|
) { // else they are eligible for the higher limit, but if they exceed that
|
||||||
|
if (RuleB(World, IPLimitDisconnectAll)) {
|
||||||
|
LogClientLogin("Disconnect: All Accounts on IP [{}]", ip_string);
|
||||||
|
DisconnectByIP(in_ip);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
LogClientLogin("Disconnect: Account [{}] on IP [{}]", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str());
|
LogClientLogin("Disconnect: Account [{}] on IP [{}]", cle->LSName(), ip_string);
|
||||||
countCLEIPs->SetOnline(CLE_Status::Offline); // Remove the connection
|
cle->SetOnline(CLE_Status::Offline); // Remove the connection
|
||||||
iterator.RemoveCurrent();
|
iterator.RemoveCurrent();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -168,46 +202,54 @@ void ClientList::GetCLEIP(uint32 iIP) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator.Advance();
|
iterator.Advance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 ClientList::GetCLEIPCount(uint32 iIP) {
|
uint32 ClientList::GetCLEIPCount(uint32 in_ip) {
|
||||||
ClientListEntry* countCLEIPs = 0;
|
ClientListEntry* cle = nullptr;
|
||||||
LinkedListIterator<ClientListEntry*> iterator(clientlist);
|
LinkedListIterator<ClientListEntry*> iterator(clientlist);
|
||||||
|
|
||||||
int IPInstances = 0;
|
int count = 0;
|
||||||
iterator.Reset();
|
iterator.Reset();
|
||||||
|
|
||||||
while (iterator.MoreElements()) {
|
while (iterator.MoreElements()) {
|
||||||
countCLEIPs = iterator.GetData();
|
cle = iterator.GetData();
|
||||||
if ((countCLEIPs->GetIP() == iIP) && ((countCLEIPs->Admin() < (RuleI(World, ExemptMaxClientsStatus))) || (RuleI(World, ExemptMaxClientsStatus) < 0)) && countCLEIPs->Online() >= CLE_Status::Online) { // If the IP matches, and the connection admin status is below the exempt status, or exempt status is less than 0 (no-one is exempt)
|
if (
|
||||||
IPInstances++; // Increment the occurences of this IP address
|
cle->GetIP() == in_ip &&
|
||||||
|
(
|
||||||
|
cle->Admin() < RuleI(World, ExemptMaxClientsStatus) ||
|
||||||
|
RuleI(World, ExemptMaxClientsStatus) < 0
|
||||||
|
) &&
|
||||||
|
cle->Online() >= CLE_Status::Online
|
||||||
|
) { // If the IP matches, and the connection admin status is below the exempt status, or exempt status is less than 0 (no-one is exempt)
|
||||||
|
count++; // Increment the occurences of this IP address
|
||||||
}
|
}
|
||||||
iterator.Advance();
|
iterator.Advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
return IPInstances;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientList::DisconnectByIP(uint32 iIP) {
|
void ClientList::DisconnectByIP(uint32 in_ip) {
|
||||||
ClientListEntry* countCLEIPs = 0;
|
ClientListEntry* cle = nullptr;
|
||||||
LinkedListIterator<ClientListEntry*> iterator(clientlist);
|
LinkedListIterator<ClientListEntry*> iterator(clientlist);
|
||||||
iterator.Reset();
|
iterator.Reset();
|
||||||
|
|
||||||
while(iterator.MoreElements()) {
|
while (iterator.MoreElements()) {
|
||||||
countCLEIPs = iterator.GetData();
|
cle = iterator.GetData();
|
||||||
if ((countCLEIPs->GetIP() == iIP)) {
|
if (cle->GetIP() == in_ip) {
|
||||||
if(strlen(countCLEIPs->name())) {
|
if (strlen(cle->name())) {
|
||||||
auto pack = new ServerPacket(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
|
auto pack = new ServerPacket(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
|
||||||
ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer;
|
auto skp = (ServerKickPlayer_Struct*) pack->pBuffer;
|
||||||
strcpy(skp->adminname, "SessionLimit");
|
strn0cpy(skp->adminname, "SessionLimit", sizeof(skp->adminname));
|
||||||
strcpy(skp->name, countCLEIPs->name());
|
strn0cpy(skp->name, cle->name(), sizeof(skp->name));
|
||||||
skp->adminrank = 255;
|
skp->adminrank = 255;
|
||||||
zoneserver_list.SendPacket(pack);
|
zoneserver_list.SendPacket(pack);
|
||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
countCLEIPs->SetOnline(CLE_Status::Offline);
|
cle->SetOnline(CLE_Status::Offline);
|
||||||
iterator.RemoveCurrent();
|
iterator.RemoveCurrent();
|
||||||
}
|
}
|
||||||
iterator.Advance();
|
iterator.Advance();
|
||||||
|
|||||||
@ -57,9 +57,9 @@ public:
|
|||||||
ClientListEntry* FindCLEByCharacterID(uint32 iCharID);
|
ClientListEntry* FindCLEByCharacterID(uint32 iCharID);
|
||||||
ClientListEntry* FindCLEByLSID(uint32 iLSID);
|
ClientListEntry* FindCLEByLSID(uint32 iLSID);
|
||||||
ClientListEntry* GetCLE(uint32 iID);
|
ClientListEntry* GetCLE(uint32 iID);
|
||||||
void GetCLEIP(uint32 iIP);
|
void GetCLEIP(uint32 in_ip);
|
||||||
uint32 GetCLEIPCount(uint32 iLSAccountID);
|
uint32 GetCLEIPCount(uint32 iLSAccountID);
|
||||||
void DisconnectByIP(uint32 iIP);
|
void DisconnectByIP(uint32 in_ip);
|
||||||
void CLCheckStale();
|
void CLCheckStale();
|
||||||
void CLEKeepAlive(uint32 numupdates, uint32* wid);
|
void CLEKeepAlive(uint32 numupdates, uint32* wid);
|
||||||
void CLEAdd(uint32 iLSID, const char* iLoginServerName, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = AccountStatus::Player, uint32 ip = 0, uint8 local=0);
|
void CLEAdd(uint32 iLSID, const char* iLoginServerName, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = AccountStatus::Player, uint32 ip = 0, uint8 local=0);
|
||||||
|
|||||||
@ -44,6 +44,7 @@
|
|||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "../common/platform.h"
|
#include "../common/platform.h"
|
||||||
#include "../common/crash.h"
|
#include "../common/crash.h"
|
||||||
|
#include "../common/misc.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "worlddb.h"
|
#include "worlddb.h"
|
||||||
|
|
||||||
@ -658,7 +659,7 @@ int main(int argc, char **argv)
|
|||||||
eqsm.OnNewConnection(
|
eqsm.OnNewConnection(
|
||||||
[&stream_identifier](std::shared_ptr<EQ::Net::EQStream> stream) {
|
[&stream_identifier](std::shared_ptr<EQ::Net::EQStream> stream) {
|
||||||
stream_identifier.AddStream(stream);
|
stream_identifier.AddStream(stream);
|
||||||
LogInfo("New connection from IP {0}:{1}", stream->GetRemoteIP(), ntohs(stream->GetRemotePort()));
|
LogInfo("New connection from IP {}:{}", long2ip(stream->GetRemoteIP()), ntohs(stream->GetRemotePort()));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,7 @@
|
|||||||
#include "../common/memory_mapped_file.h"
|
#include "../common/memory_mapped_file.h"
|
||||||
#include "../common/spdat.h"
|
#include "../common/spdat.h"
|
||||||
#include "../common/eqemu_logsys.h"
|
#include "../common/eqemu_logsys.h"
|
||||||
|
#include "../common/misc.h"
|
||||||
|
|
||||||
#include "api_service.h"
|
#include "api_service.h"
|
||||||
#include "zone_config.h"
|
#include "zone_config.h"
|
||||||
@ -514,7 +515,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
eqsm->OnNewConnection([&stream_identifier](std::shared_ptr<EQ::Net::EQStream> stream) {
|
eqsm->OnNewConnection([&stream_identifier](std::shared_ptr<EQ::Net::EQStream> stream) {
|
||||||
stream_identifier.AddStream(stream);
|
stream_identifier.AddStream(stream);
|
||||||
LogF(Logs::Detail, Logs::WorldServer, "New connection from IP {0}:{1}", stream->GetRemoteIP(), ntohs(stream->GetRemotePort()));
|
LogInfo("New connection from IP {}:{}", long2ip(stream->GetRemoteIP()), ntohs(stream->GetRemotePort()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user