diff --git a/common/ruletypes.h b/common/ruletypes.h index 8dfa15f9e..cad8f455f 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -240,7 +240,7 @@ RULE_BOOL (World, IPLimitDisconnectAll, false) RULE_BOOL(World, MaxClientsSimplifiedLogic, false) // New logic that only uses ExemptMaxClientsStatus and MaxClientsPerIP. Done on the loginserver. This mimics the P99-style special IP rules. RULE_INT (World, TellQueueSize, 20) RULE_BOOL(World, StartZoneSameAsBindOnCreation, true) //Should the start zone ALWAYS be the same location as your bind? -RULE_BOOL(World, DisallowDuplicateAccountLogins, true) +RULE_BOOL(World, EnforceCharacterLimitAtLogin, false) RULE_CATEGORY_END() RULE_CATEGORY(Zone) diff --git a/world/adventure.cpp b/world/adventure.cpp index c984fa831..af3cfe0e2 100644 --- a/world/adventure.cpp +++ b/world/adventure.cpp @@ -287,7 +287,7 @@ void Adventure::Finished(AdventureWinStatus ws) ClientListEntry *current = client_list.FindCharacter((*iter).c_str()); if(current) { - if(current->Online() == CLE_Status_InZone) + if(current->Online() == CLE_Status::InZone) { //We can send our packets only. auto pack = diff --git a/world/client.cpp b/world/client.cpp index bc044dae5..3f875cafe 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -115,7 +115,7 @@ Client::Client(EQStreamInterface* ieqs) Client::~Client() { if (RunLoops && cle && zone_id == 0) - cle->SetOnline(CLE_Status_Offline); + cle->SetOnline(CLE_Status::Offline); numclients--; @@ -185,7 +185,7 @@ void Client::SendExpansionInfo() { void Client::SendCharInfo() { if (cle) { - cle->SetOnline(CLE_Status_CharSelect); + cle->SetOnline(CLE_Status::CharSelect); } if (m_ClientVersionBit & EQEmu::versions::maskRoFAndLater) { @@ -461,7 +461,7 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { // Track who is in and who is out of the game char *inout= (char *) ""; - if (cle->GetOnline() == CLE_Status_Never){ + if (cle->GetOnline() == CLE_Status::Never){ // Desktop -> Char Select inout = (char *) "In"; } @@ -474,7 +474,7 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { // Either from a fresh client launch or coming back from the game. // Exiting the game entirely does not come through here. // Could use a Logging Out Completely message somewhere. - cle->SetOnline(CLE_Status_CharSelect); + cle->SetOnline(CLE_Status::CharSelect); Log(Logs::General, Logs::World_Server, "Account (%s) Logging(%s) to character select :: LSID: %d ", @@ -1076,7 +1076,7 @@ bool Client::HandlePacket(const EQApplicationPacket *app) { { // I don't see this getting executed on logout eqs->Close(); - cle->SetOnline(CLE_Status_Offline); //allows this player to log in again without an ip restriction. + cle->SetOnline(CLE_Status::Offline); //allows this player to log in again without an ip restriction. return false; } case OP_ZoneChange: @@ -1191,6 +1191,8 @@ void Client::EnterWorld(bool TryBootup) { else zone_server = zoneserver_list.FindByZoneID(zone_id); + //Tell all the zones to drop any client with this lsid because we're coming back in. + zoneserver_list.DropClient(GetLSID()); const char *zone_name = database.GetZoneName(zone_id, true); if (zone_server) { @@ -1344,7 +1346,7 @@ void Client::Clearance(int8 response) safe_delete(outapp); if (cle) - cle->SetOnline(CLE_Status_Zoning); + cle->SetOnline(CLE_Status::Zoning); } void Client::TellClientZoneUnavailable() { diff --git a/world/cliententry.cpp b/world/cliententry.cpp index 1402b1420..67583a614 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -73,7 +73,7 @@ ClientListEntry::ClientListEntry(uint32 in_id, uint32 iAccID, const char* iAccNa memset(pLFGComments, 0, 64); } -ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline) +ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer* iZS, ServerClientList_Struct* scl, CLE_Status iOnline) : id(in_id) { ClearVars(true); @@ -94,7 +94,7 @@ ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer* iZS, ServerClientList pLFGMatchFilter = false; memset(pLFGComments, 0, 64); - if (iOnline >= CLE_Status_Zoning) + if (iOnline >= CLE_Status::Zoning) Update(iZS, scl, iOnline); else SetOnline(iOnline); @@ -115,24 +115,24 @@ void ClientListEntry::SetChar(uint32 iCharID, const char* iCharName) { strn0cpy(pname, iCharName, sizeof(pname)); } -void ClientListEntry::SetOnline(ZoneServer* iZS, int8 iOnline) { +void ClientListEntry::SetOnline(ZoneServer* iZS, CLE_Status iOnline) { if (iZS == this->Server()) SetOnline(iOnline); } -void ClientListEntry::SetOnline(int8 iOnline) { - Log(Logs::Detail, Logs::World_Server, "ClientListEntry::SetOnline for %s(%i) = %i", AccountName(), AccountID(), iOnline); +void ClientListEntry::SetOnline(CLE_Status iOnline) { + Log(Logs::General, Logs::World_Server, "ClientListEntry::SetOnline for %s(%i) = %i", AccountName(), AccountID(), iOnline); - if (iOnline >= CLE_Status_Online && pOnline < CLE_Status_Online) + if (iOnline >= CLE_Status::Online && pOnline < CLE_Status::Online) numplayers++; - else if (iOnline < CLE_Status_Online && pOnline >= CLE_Status_Online) { + else if (iOnline < CLE_Status::Online && pOnline >= CLE_Status::Online) { numplayers--; } - if (iOnline != CLE_Status_Online || pOnline < CLE_Status_Online) + if (iOnline != CLE_Status::Online || pOnline < CLE_Status::Online) pOnline = iOnline; - if (iOnline < CLE_Status_Zoning) + if (iOnline < CLE_Status::Zoning) Camp(); - if (pOnline >= CLE_Status_Online) + if (pOnline >= CLE_Status::Online) stale = 0; } void ClientListEntry::LSUpdate(ZoneServer* iZS){ @@ -163,7 +163,7 @@ void ClientListEntry::LSZoneChange(ZoneToZone_Struct* ztz){ safe_delete(pack); } } -void ClientListEntry::Update(ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline) { +void ClientListEntry::Update(ZoneServer* iZS, ServerClientList_Struct* scl, CLE_Status iOnline) { if (pzoneserver != iZS) { if (pzoneserver){ pzoneserver->RemovePlayer(); @@ -210,7 +210,7 @@ void ClientListEntry::Update(ZoneServer* iZS, ServerClientList_Struct* scl, int8 SetOnline(iOnline); } -void ClientListEntry::LeavingZone(ZoneServer* iZS, int8 iOnline) { +void ClientListEntry::LeavingZone(ZoneServer* iZS, CLE_Status iOnline) { if (iZS != 0 && iZS != pzoneserver) return; SetOnline(iOnline); @@ -225,7 +225,7 @@ void ClientListEntry::LeavingZone(ZoneServer* iZS, int8 iOnline) { void ClientListEntry::ClearVars(bool iAll) { if (iAll) { - pOnline = CLE_Status_Never; + pOnline = CLE_Status::Never; stale = 0; pLSID = 0; @@ -271,8 +271,8 @@ void ClientListEntry::Camp(ZoneServer* iZS) { bool ClientListEntry::CheckStale() { stale++; if (stale > 20) { - if (pOnline > CLE_Status_Offline) - SetOnline(CLE_Status_Offline); + if (pOnline > CLE_Status::Offline) + SetOnline(CLE_Status::Offline); else return true; } diff --git a/world/cliententry.h b/world/cliententry.h index 24a837ae9..725b7df0d 100644 --- a/world/cliententry.h +++ b/world/cliententry.h @@ -8,13 +8,15 @@ #include "../common/rulesys.h" #include - -#define CLE_Status_Never -1 -#define CLE_Status_Offline 0 -#define CLE_Status_Online 1 // Will not overwrite more specific online status -#define CLE_Status_CharSelect 2 -#define CLE_Status_Zoning 3 -#define CLE_Status_InZone 4 +typedef enum +{ + Never, + Offline, + Online, + CharSelect, + Zoning, + InZone +} CLE_Status; class ZoneServer; struct ServerClientList_Struct; @@ -23,25 +25,25 @@ class ClientListEntry { public: ClientListEntry(uint32 id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); ClientListEntry(uint32 id, uint32 iAccID, const char* iAccName, MD5& iMD5Pass, int16 iAdmin = 0); - ClientListEntry(uint32 id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline); + ClientListEntry(uint32 id, ZoneServer* iZS, ServerClientList_Struct* scl, CLE_Status iOnline); ~ClientListEntry(); bool CheckStale(); - void Update(ZoneServer* zoneserver, ServerClientList_Struct* scl, int8 iOnline = CLE_Status_InZone); + void Update(ZoneServer* zoneserver, ServerClientList_Struct* scl, CLE_Status iOnline = CLE_Status::InZone); void LSUpdate(ZoneServer* zoneserver); void LSZoneChange(ZoneToZone_Struct* ztz); bool CheckAuth(uint32 iLSID, const char* key); bool CheckAuth(const char* iName, MD5& iMD5Password); bool CheckAuth(uint32 id, const char* key, uint32 ip); - void SetOnline(ZoneServer* iZS, int8 iOnline); - void SetOnline(int8 iOnline = CLE_Status_Online); + void SetOnline(ZoneServer* iZS, CLE_Status iOnline); + void SetOnline(CLE_Status iOnline = CLE_Status::Online); void SetChar(uint32 iCharID, const char* iCharName); - inline int8 Online() { return pOnline; } + inline CLE_Status Online() { return pOnline; } inline const uint32 GetID() const { return id; } inline const uint32 GetIP() const { return pIP; } inline void SetIP(const uint32& iIP) { pIP = iIP; } inline void KeepAlive() { stale = 0; } inline uint8 GetStaleCounter() const { return stale; } - void LeavingZone(ZoneServer* iZS = 0, int8 iOnline = CLE_Status_Offline); + void LeavingZone(ZoneServer* iZS = 0, CLE_Status iOnline = CLE_Status::Offline); void Camp(ZoneServer* iZS = 0); // Login Server stuff @@ -50,7 +52,7 @@ public: inline const char* LSName() const { return plsname; } inline int16 WorldAdmin() const { return pworldadmin; } inline const char* GetLSKey() const { return plskey; } - inline const int8 GetOnline() const { return pOnline; } + inline const CLE_Status GetOnline() const { return pOnline; } // Account stuff inline uint32 AccountID() const { return paccountid; } @@ -93,7 +95,7 @@ private: const uint32 id; uint32 pIP; - int8 pOnline; + CLE_Status pOnline; uint8 stale; // Login Server stuff diff --git a/world/clientlist.cpp b/world/clientlist.cpp index cc783affd..da14ce71f 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -120,7 +120,7 @@ void ClientList::GetCLEIP(uint32 iIP) { return; } else { Log(Logs::General, Logs::Client_Login, "Disconnect: Account %s on IP %s.", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str()); - countCLEIPs->SetOnline(CLE_Status_Offline); + countCLEIPs->SetOnline(CLE_Status::Offline); iterator.RemoveCurrent(); continue; } @@ -136,7 +136,7 @@ void ClientList::GetCLEIP(uint32 iIP) { return; } else { Log(Logs::General, Logs::Client_Login, "Disconnect: Account %s on IP %s.", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str()); - countCLEIPs->SetOnline(CLE_Status_Offline); // Remove the connection + countCLEIPs->SetOnline(CLE_Status::Offline); // Remove the connection iterator.RemoveCurrent(); continue; } @@ -148,7 +148,7 @@ void ClientList::GetCLEIP(uint32 iIP) { return; } else { Log(Logs::General, Logs::Client_Login, "Disconnect: Account %s on IP %s.", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str()); - countCLEIPs->SetOnline(CLE_Status_Offline); // Remove the connection + countCLEIPs->SetOnline(CLE_Status::Offline); // Remove the connection iterator.RemoveCurrent(); continue; } @@ -159,7 +159,7 @@ void ClientList::GetCLEIP(uint32 iIP) { return; } else { Log(Logs::General, Logs::Client_Login, "Disconnect: Account %s on IP %s.", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str()); - countCLEIPs->SetOnline(CLE_Status_Offline); // Remove the connection + countCLEIPs->SetOnline(CLE_Status::Offline); // Remove the connection iterator.RemoveCurrent(); continue; } @@ -180,7 +180,7 @@ uint32 ClientList::GetCLEIPCount(uint32 iIP) { while (iterator.MoreElements()) { countCLEIPs = 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 ((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) IPInstances++; // Increment the occurences of this IP address } iterator.Advance(); @@ -206,7 +206,7 @@ void ClientList::DisconnectByIP(uint32 iIP) { zoneserver_list.SendPacket(pack); safe_delete(pack); } - countCLEIPs->SetOnline(CLE_Status_Offline); + countCLEIPs->SetOnline(CLE_Status::Offline); iterator.RemoveCurrent(); } iterator.Advance(); @@ -253,19 +253,6 @@ ClientListEntry* ClientList::FindCLEByCharacterID(uint32 iCharID) { return nullptr; } -ClientListEntry* ClientList::FindCLEByLSID(uint32 iLSID) { - LinkedListIterator iterator(clientlist); - - iterator.Reset(); - while (iterator.MoreElements()) { - if (iterator.GetData()->LSID() == iLSID) { - return iterator.GetData(); - } - iterator.Advance(); - } - return nullptr; -} - void ClientList::SendCLEList(const int16& admin, const char* to, WorldTCPConnection* connection, const char* iName) { LinkedListIterator iterator(clientlist); char* output = 0; @@ -341,10 +328,10 @@ void ClientList::ClientUpdate(ZoneServer* zoneserver, ServerClientList_Struct* s if (iterator.GetData()->GetID() == scl->wid) { cle = iterator.GetData(); if (scl->remove == 2){ - cle->LeavingZone(zoneserver, CLE_Status_Offline); + cle->LeavingZone(zoneserver, CLE_Status::Offline); } else if (scl->remove == 1) - cle->LeavingZone(zoneserver, CLE_Status_Zoning); + cle->LeavingZone(zoneserver, CLE_Status::Zoning); else cle->Update(zoneserver, scl); return; @@ -352,11 +339,11 @@ void ClientList::ClientUpdate(ZoneServer* zoneserver, ServerClientList_Struct* s iterator.Advance(); } if (scl->remove == 2) - cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status_Online); + cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status::Online); else if (scl->remove == 1) - cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status_Zoning); + cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status::Zoning); else - cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status_InZone); + cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status::InZone); clientlist.Insert(cle); zoneserver->ChangeWID(scl->charid, cle->GetID()); } @@ -536,7 +523,7 @@ void ClientList::SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_S countcle = countclients.GetData(); const char* tmpZone = database.GetZoneName(countcle->zone()); if ( - (countcle->Online() >= CLE_Status_Zoning) && + (countcle->Online() >= CLE_Status::Zoning) && (!countcle->GetGM() || countcle->Anon() != 1 || admin >= countcle->Admin()) && (whom == 0 || ( ((countcle->Admin() >= 80 && countcle->GetGM()) || whom->gmlookup == 0xFFFF) && @@ -616,7 +603,7 @@ void ClientList::SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_S const char* tmpZone = database.GetZoneName(cle->zone()); if ( - (cle->Online() >= CLE_Status_Zoning) && + (cle->Online() >= CLE_Status::Zoning) && (!cle->GetGM() || cle->Anon() != 1 || admin >= cle->Admin()) && (whom == 0 || ( ((cle->Admin() >= 80 && cle->GetGM()) || whom->gmlookup == 0xFFFF) && @@ -789,7 +776,7 @@ void ClientList::SendFriendsWho(ServerFriendsWho_Struct *FriendsWho, WorldTCPCon Friend_[Seperator - FriendsPointer] = 0; ClientListEntry* CLE = FindCharacter(Friend_); - if(CLE && CLE->name() && (CLE->Online() >= CLE_Status_Zoning) && !(CLE->GetGM() && CLE->Anon())) { + if(CLE && CLE->name() && (CLE->Online() >= CLE_Status::Zoning) && !(CLE->GetGM() && CLE->Anon())) { FriendsCLEs.push_back(CLE); TotalLength += strlen(CLE->name()); int GuildNameLength = strlen(guild_mgr.GetGuildName(CLE->GuildID())); @@ -1001,7 +988,7 @@ void ClientList::ConsoleSendWhoAll(const char* to, int16 admin, Who_All_Struct* cle = iterator.GetData(); const char* tmpZone = database.GetZoneName(cle->zone()); if ( - (cle->Online() >= CLE_Status_Zoning) + (cle->Online() >= CLE_Status::Zoning) && (whom == 0 || ( ((cle->Admin() >= 80 && cle->GetGM()) || whom->gmlookup == 0xFFFF) && (whom->lvllow == 0xFFFF || (cle->level() >= whom->lvllow && cle->level() <= whom->lvlhigh)) && @@ -1289,6 +1276,19 @@ void ClientList::RemoveCLEByLSID(uint32 iLSID) } } +bool ClientList::IsAccountInGame(uint32 iLSID) { + LinkedListIterator iterator(clientlist); + + while (iterator.MoreElements()) { + if (iterator.GetData()->LSID() == iLSID && iterator.GetData()->Online() == CLE_Status::InZone) { + return true; + } + iterator.Advance(); + } + + return false; +} + int ClientList::GetClientCount() { return(numplayers); } diff --git a/world/clientlist.h b/world/clientlist.h index 19b8adc05..2ed9c3971 100644 --- a/world/clientlist.h +++ b/world/clientlist.h @@ -57,7 +57,6 @@ public: ClientListEntry* FindCharacter(const char* name); ClientListEntry* FindCLEByAccountID(uint32 iAccID); ClientListEntry* FindCLEByCharacterID(uint32 iCharID); - ClientListEntry* FindCLEByLSID(uint32 iLSID); ClientListEntry* GetCLE(uint32 iID); void GetCLEIP(uint32 iIP); uint32 GetCLEIPCount(uint32 iLSAccountID); @@ -67,6 +66,7 @@ public: void CLEAdd(uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); void UpdateClientGuild(uint32 char_id, uint32 guild_id); void RemoveCLEByLSID(uint32 iLSID); + bool IsAccountInGame(uint32 iLSID); int GetClientCount(); void GetClients(const char *zone_name, std::vector &into); diff --git a/world/login_server.cpp b/world/login_server.cpp index e0990d964..02e9fdbab 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -105,19 +105,11 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) { return; } - if (RuleB(World, DisallowDuplicateAccountLogins)) { - auto cle = client_list.FindCLEByLSID(utwr->lsaccountid); - if (cle != nullptr) { - auto status = cle->GetOnline(); - if (CLE_Status_InZone == status) { - utwrs->response = UserToWorldStatusAlreadyOnline; - SendPacket(&outpack); - return; - } - else { - zoneserver_list.DropClient(utwrs->lsaccountid); - client_list.RemoveCLEByLSID(utwrs->lsaccountid); - } + if (RuleB(World, EnforceCharacterLimitAtLogin)) { + if (client_list.IsAccountInGame(utwr->lsaccountid)) { + utwrs->response = UserToWorldStatusAlreadyOnline; + SendPacket(&outpack); + return; } } diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index bb856c75a..21c5d8e65 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -437,7 +437,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { } ClientListEntry* cle = client_list.FindCharacter(scm->deliverto); - if (cle == 0 || cle->Online() < CLE_Status_Zoning || + if (cle == 0 || cle->Online() < CLE_Status::Zoning || (cle->TellsOff() && ((cle->Anon() == 1 && scm->fromadmin < cle->Admin()) || scm->fromadmin < 80))) { if (!scm->noreply) { ClientListEntry* sender = client_list.FindCharacter(scm->from); @@ -450,7 +450,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { sender->Server()->SendPacket(pack); } } - else if (cle->Online() == CLE_Status_Zoning) { + else if (cle->Online() == CLE_Status::Zoning) { if (!scm->noreply) { ClientListEntry* sender = client_list.FindCharacter(scm->from); if (cle->TellQueueFull()) { @@ -518,7 +518,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { ClientListEntry* cle = client_list.FindCharacter(svm->To); - if (!cle || (cle->Online() < CLE_Status_Zoning) || !cle->Server()) { + if (!cle || (cle->Online() < CLE_Status::Zoning) || !cle->Server()) { zoneserver_list.SendEmoteMessage(svm->From, 0, 0, 0, "'%s is not online at this time'", svm->To); diff --git a/zone/client.cpp b/zone/client.cpp index baf75b0fe..57f6ba865 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -446,7 +446,7 @@ Client::~Client() { numclients--; UpdateWindowTitle(); if(zone) - zone->RemoveAuth(GetName()); + zone->RemoveAuth(GetName(), lskey); //let the stream factory know were done with this stream eqs->Close(); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 54040ca5c..864f11448 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -534,6 +534,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) ServerZoneIncomingClient_Struct* szic = (ServerZoneIncomingClient_Struct*)pack->pBuffer; if (is_zone_loaded) { SetZoneData(zone->GetZoneID(), zone->GetInstanceID()); + if (szic->zoneid == zone->GetZoneID()) { zone->AddAuth(szic); // This packet also doubles as "incoming client" notification, lets not shut down before they get here diff --git a/zone/zone.cpp b/zone/zone.cpp index 01e6ad42e..185c0e65b 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1114,16 +1114,16 @@ void Zone::AddAuth(ServerZoneIncomingClient_Struct* szic) { client_auth_list.Insert(zca); } -void Zone::RemoveAuth(const char* iCharName) +void Zone::RemoveAuth(const char* iCharName, const char* iLSKey) { LinkedListIterator iterator(client_auth_list); iterator.Reset(); while (iterator.MoreElements()) { ZoneClientAuth_Struct* zca = iterator.GetData(); - if (strcasecmp(zca->charname, iCharName) == 0) { - iterator.RemoveCurrent(); - return; + if (strcasecmp(zca->charname, iCharName) == 0 && strcasecmp(zca->lskey, iLSKey) == 0) { + iterator.RemoveCurrent(); + return; } iterator.Advance(); } @@ -1138,7 +1138,6 @@ void Zone::RemoveAuth(uint32 lsid) ZoneClientAuth_Struct* zca = iterator.GetData(); if (zca->lsid == lsid) { iterator.RemoveCurrent(); - return; } iterator.Advance(); } diff --git a/zone/zone.h b/zone/zone.h index 78bcef0f3..a7de25ab4 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -244,7 +244,7 @@ public: void LoadZoneDoors(const char *zone, int16 version); void ReloadStaticData(); void ReloadWorld(uint32 Option); - void RemoveAuth(const char *iCharName); + void RemoveAuth(const char *iCharName, const char *iLSKey); void RemoveAuth(uint32 lsid); void Repop(uint32 delay = 0); void RepopClose(const glm::vec4 &client_position, uint32 repop_distance);