Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #1  
Old 03-24-2008, 06:48 PM
TheLieka
Developer
 
Join Date: Oct 2004
Location: THE ATL (wut wut)
Posts: 325
Default Limiting client connections by IP address (Integrated into Rules System)

I've seen several people asking / talking about limiting client connections by IP address lately, so I figure I'd just post my implementation of it. Give it a try and let me know what you think.

.\common\ruletypes.h


Change:
Code:
RULE_CATEGORY( World )
RULE_INT ( World, ZoneAutobootTimeoutMS, 60000 )
RULE_INT ( World, ClientKeepaliveTimeoutMS, 65000 )
RULE_CATEGORY_END()
To:
Code:
RULE_CATEGORY( World )
RULE_INT ( World, ZoneAutobootTimeoutMS, 60000 )
RULE_INT ( World, ClientKeepaliveTimeoutMS, 65000 )
RULE_INT ( World, MaxClientsPerIP, -1 ) //Lieka Edit: Maximum number of clients allowed to connect per IP address.  Default value: -1 (feature disabled)
RULE_INT ( World, ExemptMaxClientsStatus, -1 ) //Lieka Edit: Exempt accounts from the MaxClientsPerIP rule, if their status is >= this value.  Default value: -1 (feature disabled)
RULE_CATEGORY_END()

.\world\clientlist.h


Change:
Code:
void	ClientUpdate(ZoneServer* zoneserver, ServerClientList_Struct* scl);
void	CLERemoveZSRef(ZoneServer* iZS);
ClientListEntry* CheckAuth(int32 iLSID, const char* iKey);
ClientListEntry* CheckAuth(const char* iName, const char* iPassword);
ClientListEntry* CheckAuth(int32 id, const char* iKey, int32 ip);
ClientListEntry* FindCharacter(const char* name);
ClientListEntry* FindCLEByAccountID(int32 iAccID);
ClientListEntry* FindCLEByCharacterID(int32 iAccID);
ClientListEntry* GetCLE(int32 iID);
void	CLCheckStale();
void	CLEKeepAlive(int32 numupdates, int32* wid);
void	CLEAdd(int32 iLSID, const char* iLoginName, const char* iLoginKey, sint16 iWorldAdmin = 0, int32 ip = 0, uint8 local=0);
void	UpdateClientGuild(int32 char_id, int32 guild_id);
To:

Code:
void	ClientUpdate(ZoneServer* zoneserver, ServerClientList_Struct* scl);
void	CLERemoveZSRef(ZoneServer* iZS);
ClientListEntry* CheckAuth(int32 iLSID, const char* iKey);
ClientListEntry* CheckAuth(const char* iName, const char* iPassword);
ClientListEntry* CheckAuth(int32 id, const char* iKey, int32 ip);
ClientListEntry* FindCharacter(const char* name);
ClientListEntry* FindCLEByAccountID(int32 iAccID);
ClientListEntry* FindCLEByCharacterID(int32 iAccID);
ClientListEntry* GetCLE(int32 iID);
void	GetCLEIP(int32 iIP);
void	CLCheckStale();
void	CLEKeepAlive(int32 numupdates, int32* wid);
void	CLEAdd(int32 iLSID, const char* iLoginName, const char* iLoginKey, sint16 iWorldAdmin = 0, int32 ip = 0, uint8 local=0);
void	UpdateClientGuild(int32 char_id, int32 guild_id);
.\world\clientlist.cpp

After:
Code:
void ClientList::CLERemoveZSRef(ZoneServer* iZS) {
	LinkedListIterator<ClientListEntry*> iterator(clientlist);

	iterator.Reset();
	while(iterator.MoreElements()) {
		if (iterator.GetData()->Server() == iZS) {
			iterator.GetData()->ClearServer(); // calling this before LeavingZone() makes CLE not update the number of players in a zone
			iterator.GetData()->LeavingZone();
		}
		iterator.Advance();
	}
}

ClientListEntry* ClientList::GetCLE(int32 iID) {
	LinkedListIterator<ClientListEntry*> iterator(clientlist);


	iterator.Reset();
	while(iterator.MoreElements()) {
		if (iterator.GetData()->GetID() == iID) {
			return iterator.GetData();
		}
		iterator.Advance();
	}
	return 0;
}
Add:
Code:
 //Lieka Edit Begin:  Check current CLE Entry IPs against incoming connection

void ClientList::GetCLEIP(int32 iIP) {
	ClientListEntry* countCLEIPs = 0;
	LinkedListIterator<ClientListEntry*> iterator(clientlist);

	int IPInstances = 0;
	iterator.Reset();
	while(iterator.MoreElements()) {
		countCLEIPs = iterator.GetData();
		if ((countCLEIPs->GetIP() == iIP) && ((countCLEIPs->Admin() <= (RuleI(World, ExemptMaxClientsStatus))) || (RuleI(World, ExemptMaxClientsStatus) < 0)) {
			IPInstances++;
			if (IPInstances > (RuleI(World, MaxClientsPerIP)){
				countCLEIPs->SetOnline(CLE_Status_Offline);
				iterator.RemoveCurrent();
			}
		}
		iterator.Advance();
	}
}
//Lieka Edit End

.\world\client.cpp


After:
Code:
		case OP_EnterWorld: // Enter world
		{
			if (GetAccountID() == 0) {
				clog(WORLD__CLIENT_ERR,"Enter world with no logged in account");
				eqs->Close();
				break;
			}
			if(GetAdmin() < 0)
			{
				clog(WORLD__CLIENT,"Account banned or suspended.");
				eqs->Close();
				break;
			}
Add:
Code:

if (RuleI(World, MaxClientsPerIP) >= 0) {
client_list.GetCLEIP(this->GetIP());  //Lieka Edit Begin:  Check current CLE Entry IPs against incoming connection
}
Required SQL:
Code:
Insert into rule_values values (0, 'World:MaxClientsPerIP', -1);
Insert into rule_values values (0, 'World:ExemptMaxClientsStatus', -1);
There are 2 new rule values.
World:MaxClientsPerIP = Maximum number of simultaneous EQ Client connections allowed per IP address. Set the rule value to -1 to disable this feature.
World:ExemptMaxClientsStatus = Minimum Account status to exempt the MaxClientsPerIP rule. This is helpful for the inevitable random family of 16 that live together, and all want to play on your server, as well as GMs, Devs, and QA staff. Again, set the rule value to -1 to disable this feature.

It's commented throughout, but let me know if you have questions.

Thanks,
Dax
__________________
Daxum



Former ServerOp - Vallon Zek / Tallon Zek Emu Server - Legit / Guild PvP - (2007 - 2011 RIP)

Last edited by KLS; 06-15-2008 at 01:08 PM..
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 10:30 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3