View Single Post
  #4  
Old 04-16-2009, 03:12 PM
Derision
Developer
 
Join Date: Feb 2004
Location: UK
Posts: 1,540
Default

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.

Last edited by Derision; 04-17-2009 at 12:22 AM.. Reason: Code updated to remove memory leak.
Reply With Quote