mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-01 11:36:36 +00:00
Add support for single account login to both world and login server, should also work with eqemu login server, can be turned off in rules if you don't mind the side effects double logins cause. Also lowered the linkdead time to 30s + 90s default (2min)
This commit is contained in:
+16
-49
@@ -99,52 +99,6 @@ ClientListEntry* ClientList::GetCLE(uint32 iID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Account Limiting Code to limit the number of characters allowed on from a single account at once.
|
||||
void ClientList::EnforceSessionLimit(uint32 iLSAccountID) {
|
||||
|
||||
ClientListEntry* ClientEntry = 0;
|
||||
|
||||
LinkedListIterator<ClientListEntry*> iterator(clientlist, BACKWARD);
|
||||
|
||||
int CharacterCount = 0;
|
||||
|
||||
iterator.Reset();
|
||||
|
||||
while(iterator.MoreElements()) {
|
||||
|
||||
ClientEntry = iterator.GetData();
|
||||
|
||||
if ((ClientEntry->LSAccountID() == iLSAccountID) &&
|
||||
((ClientEntry->Admin() <= (RuleI(World, ExemptAccountLimitStatus))) || (RuleI(World, ExemptAccountLimitStatus) < 0))) {
|
||||
|
||||
CharacterCount++;
|
||||
|
||||
if (CharacterCount >= (RuleI(World, AccountSessionLimit))){
|
||||
// If we have a char name, they are in a zone, so send a kick to the zone server
|
||||
if(strlen(ClientEntry->name())) {
|
||||
|
||||
auto pack =
|
||||
new ServerPacket(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
|
||||
ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer;
|
||||
strcpy(skp->adminname, "SessionLimit");
|
||||
strcpy(skp->name, ClientEntry->name());
|
||||
skp->adminrank = 255;
|
||||
zoneserver_list.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
ClientEntry->SetOnline(CLE_Status_Offline);
|
||||
|
||||
iterator.RemoveCurrent();
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Check current CLE Entry IPs against incoming connection
|
||||
|
||||
void ClientList::GetCLEIP(uint32 iIP) {
|
||||
@@ -272,7 +226,7 @@ ClientListEntry* ClientList::FindCharacter(const char* name) {
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ClientListEntry* ClientList::FindCLEByAccountID(uint32 iAccID) {
|
||||
@@ -285,7 +239,7 @@ ClientListEntry* ClientList::FindCLEByAccountID(uint32 iAccID) {
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ClientListEntry* ClientList::FindCLEByCharacterID(uint32 iCharID) {
|
||||
@@ -298,7 +252,20 @@ ClientListEntry* ClientList::FindCLEByCharacterID(uint32 iCharID) {
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ClientListEntry* ClientList::FindCLEByLSID(uint32 iLSID) {
|
||||
LinkedListIterator<ClientListEntry*> 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) {
|
||||
|
||||
+1
-1
@@ -57,11 +57,11 @@ 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);
|
||||
void DisconnectByIP(uint32 iIP);
|
||||
void EnforceSessionLimit(uint32 iLSAccountID);
|
||||
void CLCheckStale();
|
||||
void CLEKeepAlive(uint32 numupdates, uint32* wid);
|
||||
void CLEAdd(uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0);
|
||||
|
||||
+43
-29
@@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "worlddb.h"
|
||||
#include "zonelist.h"
|
||||
#include "clientlist.h"
|
||||
#include "cliententry.h"
|
||||
#include "world_config.h"
|
||||
|
||||
extern ZSList zoneserver_list;
|
||||
@@ -65,38 +66,58 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) {
|
||||
uint32 id = database.GetAccountIDFromLSID(utwr->lsaccountid);
|
||||
int16 status = database.CheckStatus(id);
|
||||
|
||||
auto outpack = new ServerPacket;
|
||||
outpack->opcode = ServerOP_UsertoWorldResp;
|
||||
outpack->size = sizeof(UsertoWorldResponse_Struct);
|
||||
outpack->pBuffer = new uchar[outpack->size];
|
||||
memset(outpack->pBuffer, 0, outpack->size);
|
||||
UsertoWorldResponse_Struct* utwrs = (UsertoWorldResponse_Struct*)outpack->pBuffer;
|
||||
ServerPacket outpack;
|
||||
outpack.opcode = ServerOP_UsertoWorldResp;
|
||||
outpack.size = sizeof(UsertoWorldResponse_Struct);
|
||||
outpack.pBuffer = new uchar[outpack.size];
|
||||
memset(outpack.pBuffer, 0, outpack.size);
|
||||
UsertoWorldResponse_Struct* utwrs = (UsertoWorldResponse_Struct*)outpack.pBuffer;
|
||||
utwrs->lsaccountid = utwr->lsaccountid;
|
||||
utwrs->ToID = utwr->FromID;
|
||||
utwrs->worldid = utwr->worldid;
|
||||
utwrs->response = UserToWorldStatusSuccess;
|
||||
|
||||
if (Config->Locked == true)
|
||||
{
|
||||
if ((status == 0 || status < 100) && (status != -2 || status != -1))
|
||||
utwrs->response = 0;
|
||||
if (status >= 100)
|
||||
utwrs->response = 1;
|
||||
}
|
||||
else {
|
||||
utwrs->response = 1;
|
||||
if (status < 100) {
|
||||
utwrs->response = UserToWorldStatusWorldUnavail;
|
||||
SendPacket(&outpack);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int32 x = Config->MaxClients;
|
||||
if ((int32)numplayers >= x && x != -1 && x != 255 && status < 80)
|
||||
utwrs->response = -3;
|
||||
if ((int32)numplayers >= x && x != -1 && x != 255 && status < 80) {
|
||||
utwrs->response = UserToWorldStatusWorldAtCapacity;
|
||||
SendPacket(&outpack);
|
||||
return;
|
||||
}
|
||||
|
||||
if (status == -1)
|
||||
utwrs->response = -1;
|
||||
if (status == -2)
|
||||
utwrs->response = -2;
|
||||
if (status == -1) {
|
||||
utwrs->response = UserToWorldStatusSuspended;
|
||||
SendPacket(&outpack);
|
||||
return;
|
||||
}
|
||||
|
||||
utwrs->worldid = utwr->worldid;
|
||||
SendPacket(outpack);
|
||||
delete outpack;
|
||||
if (status == -2) {
|
||||
utwrs->response = UserToWorldStatusBanned;
|
||||
SendPacket(&outpack);
|
||||
return;
|
||||
}
|
||||
|
||||
if (RuleB(World, DisallowDuplicateAccountLogins)) {
|
||||
auto cle = client_list.FindCLEByLSID(utwr->lsaccountid);
|
||||
if (cle != nullptr) {
|
||||
auto status = cle->GetOnline();
|
||||
if (CLE_Status_Never != status && CLE_Status_Offline != status) {
|
||||
utwrs->response = UserToWorldStatusAlreadyOnline;
|
||||
SendPacket(&outpack);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendPacket(&outpack);
|
||||
}
|
||||
|
||||
void LoginServer::ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p) {
|
||||
@@ -105,13 +126,6 @@ void LoginServer::ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p) {
|
||||
|
||||
try {
|
||||
auto slsca = p.GetSerialize<ClientAuth_Struct>(0);
|
||||
|
||||
if (RuleI(World, AccountSessionLimit) >= 0) {
|
||||
// Enforce the limit on the number of characters on the same account that can be
|
||||
// online at the same time.
|
||||
client_list.EnforceSessionLimit(slsca.lsaccount_id);
|
||||
}
|
||||
|
||||
client_list.CLEAdd(slsca.lsaccount_id, slsca.name, slsca.key, slsca.worldadmin, slsca.ip, slsca.local);
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
|
||||
Reference in New Issue
Block a user