Try this:
Code:
Index: world/clientlist.cpp
===================================================================
--- world/clientlist.cpp (revision 432)
+++ world/clientlist.cpp (working copy)
@@ -100,17 +100,32 @@
//Account Limiting Code to limit the number of characters allowed on from a single account at once.
void ClientList::GetCLEAccount(int32 iAccID) {
ClientListEntry* count_Chars_On = 0;
- LinkedListIterator<ClientListEntry*> iterator(clientlist);
+ LinkedListIterator<ClientListEntry*> iterator(clientlist, BACKWARD);
int Chars_On = 0;
iterator.Reset();
while(iterator.MoreElements()) {
count_Chars_On = iterator.GetData();
- if ((count_Chars_On->AccountID() == iAccID) && ((count_Chars_On->Admin() <= (RuleI(World, ExemptAccountLimitStatus))) || (RuleI(World, ExemptAccountLimitStatus) < 0))) {
+ if ((count_Chars_On->LSAccountID() == iAccID) && ((count_Chars_On->Admin() <= (RuleI(World, ExemptAccountLimitStatus))) || (RuleI(World, ExemptAccountLimitStatus) < 0))) {
Chars_On++;
- if (Chars_On > (RuleI(World, AccountSessionLimit))){
+ _log(NET__ERROR, "LSAccount: %i has %i connections.", iAccID, Chars_On);
+ if (Chars_On >= (RuleI(World, AccountSessionLimit))){
+ // If we have a char name, they are in a zone, so send a kick to the zone server
+ if(strlen(count_Chars_On->name())) {
+ _log(NET__ERROR, "Sending kick to %s", count_Chars_On->name());
+
+ ServerPacket* pack = new ServerPacket(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
+ ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer;
+ strcpy(skp->adminname, "SessionLimit");
+ strcpy(skp->name, count_Chars_On->name());
+ skp->adminrank = 255;
+ zoneserver_list.SendPacket(pack);
+ safe_delete(pack);
+ }
+ _log(NET__ERROR, "Putting CLE offline");
count_Chars_On->SetOnline(CLE_Status_Offline);
iterator.RemoveCurrent();
+ continue;
}
}
iterator.Advance();
Index: world/LoginServer.cpp
===================================================================
--- world/LoginServer.cpp (revision 432)
+++ world/LoginServer.cpp (working copy)
@@ -151,6 +151,11 @@
}
case ServerOP_LSClientAuth: {
ServerLSClientAuth* slsca = (ServerLSClientAuth*) pack->pBuffer;
+
+ if (RuleI(World, AccountSessionLimit) >= 0) {
+ client_list.GetCLEAccount(slsca->lsaccount_id); //Check current CLE Accounts against incoming connection
+ }
+
client_list.CLEAdd(slsca->lsaccount_id, slsca->name, slsca->key, slsca->worldadmin, slsca->ip, slsca->local);
break;
}
Index: world/client.cpp
===================================================================
--- world/client.cpp (revision 432)
+++ world/client.cpp (working copy)
@@ -490,10 +490,6 @@
break;
}
- if (RuleI(World, AccountSessionLimit) >= 0) {
- client_list.GetCLEAccount(this->GetAccountID()); //Check current CLE Accounts against incoming connection
- }
-
if (RuleI(World, MaxClientsPerIP) >= 0) {
client_list.GetCLEIP(this->GetIP()); //Lieka Edit Begin: Check current CLE Entry IPs against incoming connection
}
In my limited testing on my private server, this seems to have the desired effect of kicking the existing connection and letting the new one in.
I moved the check, so it will kick the existing connection before the new one even gets to Character Select.
Edit: Code updated to remove memory leak.