View Single Post
  #13  
Old 01-01-2010, 08:39 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,449
Default

Quote:
Originally Posted by trevius View Post
Yeah, adding a simple in game command that forces a query to be done to copy the information over shouldn't be too hard.
Yup, tested it and it works flawlessly with Image's LS.

This has no conflicts as far as I know in regards to account names, and it preserves the other LS' ID to sync the two. The #setpass command in-game is reworked to allow only the character who used the command's account to be changed, and the only parameter for it now is password.

Enjoy!

Code:
Index: common/database.cpp
===================================================================
--- common/database.cpp	(revision 1068)
+++ common/database.cpp	(working copy)
@@ -382,7 +382,7 @@
 	return false;
 }
 
-bool Database::SetLocalPassword(int32 accid, const char* password) {
+bool Database::SetLocalPassword(int32 accid, const char* password, const char* name, int32 lsid ) {
 	char errbuf[MYSQL_ERRMSG_SIZE];
     char *query = 0;
 
@@ -392,6 +392,12 @@
 		return false;
 	}
 
+	if (!RunQuery(query, MakeAnyLenString(&query, "REPLACE INTO `login_accounts` SET id = %i, name='%s', password=MD5('%s');", lsid, name, password), errbuf)) {
+		cerr << "Error in SetLocalPassword query '" << query << "' " << errbuf << endl;
+		safe_delete_array(query);
+		return false;
+	}
+
 	safe_delete_array(query);
 	return true;
 }
Index: common/database.h
===================================================================
--- common/database.h	(revision 1068)
+++ common/database.h	(working copy)
@@ -215,7 +215,7 @@
 	int32	CreateAccount(const char* name, const char* password, sint16 status, int32 lsaccount_id = 0);
 	bool	DeleteAccount(const char* name);
  	bool	SetAccountStatus(const char* name, sint16 status);
-	bool	SetLocalPassword(uint32 accid, const char* password);
+	bool	SetLocalPassword(uint32 accid, const char* password, const char* name, int32 lsid);
 	int32	GetAccountIDFromLSID(int32 iLSID, char* oAccountName = 0, sint16* oStatus = 0);
 	bool	UpdateLiveChar(char* charname,int32 lsaccount_id);
 	bool	GetLiveChar(int32 account_id, char* cname);
Index: common/EQEmuConfig.cpp
===================================================================
--- common/EQEmuConfig.cpp	(revision 1068)
+++ common/EQEmuConfig.cpp	(working copy)
@@ -70,6 +70,21 @@
 		text=ParseTextBlock(sub_ele,"password",true);
 		if (text)
 			LoginPassword=text;
+		text=ParseTextBlock(sub_ele,"host2",true);
+		if (text)
+			LoginHost2=text;
+
+		text=ParseTextBlock(sub_ele,"port2",true);
+		if (text)
+			LoginPort2=atoi(text);
+		
+		text=ParseTextBlock(sub_ele,"account2",true);
+		if (text)
+			LoginAccount2=text;
+
+		text=ParseTextBlock(sub_ele,"password2",true);
+		if (text)
+			LoginPassword2=text;
 	}
 	
 	// Check for locked
@@ -305,6 +320,14 @@
 		return(LoginPassword);
 	if(var_name == "LoginPort")
 		return(itoa(LoginPort));
+	if(var_name == "LoginHost2")
+		return(LoginHost2);
+	if(var_name == "LoginAccount2")
+		return(LoginAccount2);
+	if(var_name == "LoginPassword2")
+		return(LoginPassword2);
+	if(var_name == "LoginPort2")
+		return(itoa(LoginPort2));
 	if(var_name == "Locked")
 		return(Locked?"true":"false");
 	if(var_name == "WorldTCPPort")
@@ -377,6 +400,10 @@
 	cout << "LoginAccount = " << LoginAccount << endl;
 	cout << "LoginPassword = " << LoginPassword << endl;
 	cout << "LoginPort = " << LoginPort << endl;
+	cout << "LoginHost2 = " << LoginHost2 << endl;
+	cout << "LoginAccount2 = " << LoginAccount2 << endl;
+	cout << "LoginPassword2 = " << LoginPassword2 << endl;
+	cout << "LoginPort2 = " << LoginPort2 << endl;
 	cout << "Locked = " << Locked << endl;
 	cout << "WorldTCPPort = " << WorldTCPPort << endl;
 	cout << "WorldIP = " << WorldIP << endl;
Index: common/EQEmuConfig.h
===================================================================
--- common/EQEmuConfig.h	(revision 1068)
+++ common/EQEmuConfig.h	(working copy)
@@ -33,6 +33,10 @@
 	string LoginAccount;
 	string LoginPassword;
 	uint16 LoginPort;
+	string LoginHost2;
+	string LoginAccount2;
+	string LoginPassword2;
+	uint16 LoginPort2;
 	bool Locked;
 	uint16 WorldTCPPort;
 	string WorldIP;
@@ -109,6 +113,8 @@
 		// Login server
 		LoginHost="eqemulator.net";
 		LoginPort=5998;
+		LoginHost2="eqemulator.net2";
+		LoginPort2=5999;
 
 		// World
 		Locked=false;
Index: world/client.cpp
===================================================================
--- world/client.cpp	(revision 1068)
+++ world/client.cpp	(working copy)
@@ -298,6 +298,7 @@
 					strcpy(join->key,GetLSKey());
 					join->lsaccount_id = GetLSID();
 					loginserver.SendPacket(pack);
+					loginserver.SendPacket2(pack);
 					safe_delete(pack);
 				}
 
@@ -795,6 +796,7 @@
 			strcpy(logout->key,GetLSKey());
 			logout->lsaccount_id = GetLSID();
 			loginserver.SendPacket(pack);
+			loginserver.SendPacket2(pack);
 			safe_delete(pack);
 		}
 		clog(WORLD__CLIENT,"Client disconnected (not active in process)");
Index: world/cliententry.cpp
===================================================================
--- world/cliententry.cpp	(revision 1068)
+++ world/cliententry.cpp	(working copy)
@@ -126,7 +126,7 @@
 		zone->count=iZS->NumPlayers();
 		zone->zone = iZS->GetZoneID();
 		zone->zone_wid = iZS->GetID();
-		loginserver.SendPacket(pack);
+		loginserver.SendPacket2(pack);
 		safe_delete(pack);
 	}
 }
@@ -141,6 +141,7 @@
 		zonechange->from = ztz->current_zone_id;
 		zonechange->to = ztz->requested_zone_id;
 		loginserver.SendPacket(pack);
+		loginserver.SendPacket2(pack);
 		safe_delete(pack);
 	}
 }
Index: world/console.cpp
===================================================================
--- world/console.cpp	(revision 1068)
+++ world/console.cpp	(working copy)
@@ -454,23 +454,6 @@
 			else if (strcasecmp(sep.arg[0], "ping") == 0) {
 				// do nothing
 			}
-			else if (strcasecmp(sep.arg[0], "setpass") == 0 && admin >= consolePassStatus) {
-				if (sep.argnum != 2)
-					SendMessage(1, "Format: setpass accountname password");
-				else {
-
-					sint16 tmpstatus = 0;
-					int32 tmpid = database.GetAccountIDByName(sep.arg[1], &tmpstatus);
-					if (!tmpid)
-						SendMessage(1, "Error: Account not found");
-					else if (tmpstatus > admin)
-						SendMessage(1, "Cannot change password: Account's status is higher than yours");
-					else if (database.SetLocalPassword(tmpid, sep.arg[2]))
-						SendMessage(1, "Password changed.");
-					else
-						SendMessage(1, "Error changing password."); 
-				}
-			}
 			else if (strcasecmp(sep.arg[0], "uptime") == 0) {
 				if (sep.IsNumber(1) && atoi(sep.arg[1]) > 0) {
 					ServerPacket* pack = new ServerPacket(ServerOP_Uptime, sizeof(ServerUptime_Struct));
Index: world/LoginServer.cpp
===================================================================
--- world/LoginServer.cpp	(revision 1068)
+++ world/LoginServer.cpp	(working copy)
@@ -83,10 +83,13 @@
 	LoginServerPort = iPort;
 	tcpc = new EmuTCPConnection(true);
 	tcpc->SetPacketMode(EmuTCPConnection::packetModeLogin);
+	tcpc2 = new EmuTCPConnection(true);
+	tcpc2->SetPacketMode(EmuTCPConnection::packetModeLogin);
 }
 
 LoginServer::~LoginServer() {
 	delete tcpc;
+	delete tcpc2;
 }
 
 bool LoginServer::Process() {
@@ -98,6 +101,7 @@
     
 	/************ Get all packets from packet manager out queue and process them ************/
 	ServerPacket *pack = 0;
+	ServerPacket *pack2 = 0;
 	while((pack = tcpc->PopPacket()))
 	{
 		_log(WORLD__LS_TRACE,"Recevied ServerPacket from LS OpCode 0x04x",pack->opcode);
@@ -196,6 +200,104 @@
 		delete pack;
 	}
 
+		while((pack2 = tcpc2->PopPacket()))
+	{
+		_log(WORLD__LS_TRACE,"Recevied ServerPacket from LS OpCode 0x04x",pack2->opcode);
+		_hex(WORLD__LS_TRACE,pack2->pBuffer,pack2->size);
+
+		switch(pack2->opcode) {
+		case 0:
+			break;
+		case ServerOP_KeepAlive: {
+			// ignore this
+			break;
+		}
+		case ServerOP_UsertoWorldReq: {
+			UsertoWorldRequest_Struct* utwr = (UsertoWorldRequest_Struct*) pack2->pBuffer;	
+			int32 id = database.GetAccountIDFromLSID(utwr->lsaccountid);
+			sint16 status = database.CheckStatus(id);
+
+			ServerPacket* 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;
+			utwrs->lsaccountid = utwr->lsaccountid;
+			utwrs->ToID = utwr->FromID;
+
+			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;
+			}
+
+			sint32 x = Config->MaxClients;
+			if( (sint32)numplayers >= x && x != -1 && x != 255 && status < 80)
+				utwrs->response = -3;
+
+			if(status == -1)
+				utwrs->response = -1;
+			if(status == -2)
+				utwrs->response = -2;
+
+			utwrs->worldid = utwr->worldid;
+			SendPacket2(outpack);
+			delete outpack;
+			break;
+		}
+		case ServerOP_LSClientAuth: {
+			ServerLSClientAuth* slsca = (ServerLSClientAuth*) pack2->pBuffer;
+
+			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);
+			break;
+		}
+		case ServerOP_LSFatalError: {
+#ifndef IGNORE_LS_FATAL_ERROR
+			WorldConfig::DisableLoginserver();
+			_log(WORLD__LS_ERR, "Login server responded with FatalError. Disabling reconnect.");
+#else
+		_log(WORLD__LS_ERR, "Login server responded with FatalError.");
+#endif
+			if (pack2->size > 1) {
+				_log(WORLD__LS_ERR, "     %s",pack2->pBuffer);
+			}
+			break;
+		}
+		case ServerOP_SystemwideMessage: {
+			ServerSystemwideMessage* swm = (ServerSystemwideMessage*) pack2->pBuffer;
+			zoneserver_list.SendEmoteMessageRaw(0, 0, 0, swm->type, swm->message);
+			break;
+		}
+		case ServerOP_LSRemoteAddr: {
+			if (!Config->WorldAddress.length()) {
+				WorldConfig::SetWorldAddress((char *)pack2->pBuffer);
+				_log(WORLD__LS, "Loginserver provided %s as world address",pack2->pBuffer);
+			}
+			break;
+		}
+		default:
+		{
+			_log(WORLD__LS_ERR, "Unknown LSOpCode: 0x%04x size=%d",(int)pack2->opcode,pack->size);
+DumpPacket(pack2->pBuffer, pack2->size);
+			break;
+		}
+		}
+
+		delete pack2;
+		}
+
 	return true;
 }
 
@@ -206,7 +308,7 @@
 	void *AutoInitLoginServer(void *tmp) {
 #endif
 	srand(time(NULL));
-	if (loginserver.ConnectReady()) {
+	if (loginserver.ConnectReady() && loginserver.ConnectReady2()) {
 		InitLoginServer();
 	}
 #ifndef WIN32
@@ -227,11 +329,11 @@
 	}
 
 	AttemptingConnect = true;
-	loginserver.Connect(Config->LoginHost.c_str(), Config->LoginPort);
+	loginserver.Connect(Config->LoginHost.c_str(), Config->LoginPort, Config->LoginHost2.c_str(), Config->LoginPort2);
 	return true;
 }
 
-bool LoginServer::Connect(const char* iAddress, int16 iPort) {
+bool LoginServer::Connect(const char* iAddress, int16 iPort, const char* iAddress2, int16 iPort2) {
 	char tmp[25];
 	if(database.GetVariable("loginType",tmp,sizeof(tmp)) && strcasecmp(tmp,"MinILogin") == 0){
 		minilogin = true;
@@ -264,8 +366,28 @@
 		return false;
 	}
 
-	if (tcpc->ConnectIP(LoginServerIP, LoginServerPort, errbuf)) {
+	if (iAddress2 == 0) {
+		_log(WORLD__LS_ERR, "Null address given to LoginServer::Connect");
+		return false;
+	}
+	else {
+		if ((LoginServerIP2 = ResolveIP(iAddress2, errbuf)) == 0) {
+			_log(WORLD__LS_ERR, "Unable to resolve '%s' to an IP.",iAddress2);
+			return false;
+		}
+	}
+	if (iPort2 != 0)
+		LoginServerPort2 = iPort2;
+
+	if (LoginServerIP == 0 || LoginServerPort == 0) {
+		_log(WORLD__LS_ERR, "LoginServer::Connect: Connect info incomplete, cannot connect");
+		return false;
+	}
+
+
+	if (tcpc->ConnectIP(LoginServerIP, LoginServerPort, errbuf) && tcpc2->ConnectIP(LoginServerIP2, LoginServerPort2)) {
 		_log(WORLD__LS, "Connected to Loginserver: %s:%d",iAddress,LoginServerPort);
+		_log(WORLD__LS, "Connected to Alternative Loginserver: %s:%d",iAddress2,LoginServerPort2);
 		if (minilogin)
 			SendInfo();
 		else
@@ -279,6 +401,8 @@
 		return false;
 	}
 }
+
+
 void LoginServer::SendInfo() {
 	const WorldConfig *Config=WorldConfig::get();
 
@@ -295,7 +419,23 @@
 	strcpy(lsi->password, Config->LoginPassword.c_str());
 	strcpy(lsi->address, Config->WorldAddress.c_str());
 	SendPacket(pack);
+
+
+	ServerPacket* pack2 = new ServerPacket;
+	pack2->opcode = ServerOP_LSInfo;
+	pack2->size = sizeof(ServerLSInfo_Struct);
+	pack2->pBuffer = new uchar[pack2->size];
+	memset(pack2->pBuffer, 0, pack2->size);
+	ServerLSInfo_Struct* lsi2 = (ServerLSInfo_Struct*) pack2->pBuffer;
+	strcpy(lsi2->protocolversion, EQEMU_PROTOCOL_VERSION);
+	strcpy(lsi2->serverversion, CURRENT_VERSION);
+	strcpy(lsi2->name, Config->LongName.c_str());
+	strcpy(lsi2->account, Config->LoginAccount2.c_str());
+	strcpy(lsi2->password, Config->LoginPassword2.c_str());
+	strcpy(lsi2->address, Config->WorldAddress.c_str());
+	SendPacket2(pack2);
 	delete pack;
+	delete pack2;
 }
 
 void LoginServer::SendNewInfo() {
@@ -323,7 +463,32 @@
 		WorldConfig::SetLocalAddress(lsi->local_address);
 	}
 	SendPacket(pack);
+
+	ServerPacket* pack2 = new ServerPacket;
+	pack2->opcode = ServerOP_NewLSInfo;
+	pack2->size = sizeof(ServerNewLSInfo_Struct);
+	pack2->pBuffer = new uchar[pack2->size];
+	memset(pack2->pBuffer, 0, pack2->size);
+	ServerNewLSInfo_Struct* lsi2 = (ServerNewLSInfo_Struct*) pack2->pBuffer;
+	strcpy(lsi2->protocolversion, EQEMU_PROTOCOL_VERSION);
+	strcpy(lsi2->serverversion, CURRENT_VERSION);
+	strcpy(lsi2->name, Config->LongName.c_str());
+	strcpy(lsi2->shortname, Config->ShortName.c_str());
+	strcpy(lsi2->account, Config->LoginAccount.c_str());
+	strcpy(lsi2->password, Config->LoginPassword.c_str());
+	if (Config->WorldAddress.length())
+		strcpy(lsi2->remote_address, Config->WorldAddress.c_str());
+	if (Config->LocalAddress.length())
+		strcpy(lsi2->local_address, Config->LocalAddress.c_str());
+	else {
+		tcpc2->GetSockName(lsi2->local_address,&port);
+		WorldConfig::SetLocalAddress(lsi2->local_address);
+	}
+	SendPacket(pack);
+
+	SendPacket2(pack);
 	delete pack;
+	delete pack2;
 }
 
 void LoginServer::SendStatus() {
@@ -345,6 +510,7 @@
 	lss->num_zones = numzones;
 	lss->num_players = numplayers;
 	SendPacket(pack);
+	SendPacket2(pack);
 	delete pack;
 }
 
Index: world/LoginServer.h
===================================================================
--- world/LoginServer.h	(revision 1068)
+++ world/LoginServer.h	(working copy)
@@ -39,22 +39,28 @@
     ~LoginServer();
 
 	bool Process();
-	bool Connect(const char* iAddress = 0, int16 iPort = 0);
+	bool Connect(const char* iAddress = 0, int16 iPort = 0, const char *iAddress2 = 0, int16 iPort2 = 0);
 
 	void SendInfo();
 	void SendNewInfo();
 	void SendStatus();
 
 	void SendPacket(ServerPacket* pack) { tcpc->SendPacket(pack); }
+	void SendPacket2(ServerPacket* pack) { tcpc2->SendPacket(pack); }
 	bool ConnectReady() { return tcpc->ConnectReady(); }
+	bool ConnectReady2() { return tcpc2->ConnectReady(); }
 	bool Connected() { return tcpc->Connected(); }
+	bool Connected2() { return tcpc2->Connected(); }
 	bool MiniLogin() { return minilogin; }
 
 private:
 	bool minilogin;
 	EmuTCPConnection* tcpc;
+	EmuTCPConnection* tcpc2;
 	int32	LoginServerIP;
 	int16	LoginServerPort;
+	int32	LoginServerIP2;
+	int16	LoginServerPort2;
 
 	Timer statusupdate_timer;
 };
Index: world/zoneserver.cpp
===================================================================
--- world/zoneserver.cpp	(revision 1068)
+++ world/zoneserver.cpp	(working copy)
@@ -120,6 +120,7 @@
 			zsd->zone = zoneid;
 		zsd->zone_wid = GetID();
 		loginserver.SendPacket(pack);
+		loginserver.SendPacket2(pack);
 		safe_delete(pack);
 	}
 }
@@ -140,6 +141,7 @@
 		bootup->zone_wid = GetID();
 		bootup->instance = instanceid;
 		loginserver.SendPacket(pack);
+		loginserver.SendPacket2(pack);
 		safe_delete(pack);
 	}
 }
@@ -155,6 +157,7 @@
 		sleep->zone = zoneid;
 		sleep->zone_wid = GetID();
 		loginserver.SendPacket(pack);
+		loginserver.SendPacket2(pack);
 		safe_delete(pack);
 	}
 }
Index: zone/command.cpp
===================================================================
--- zone/command.cpp	(revision 1068)
+++ zone/command.cpp	(working copy)
@@ -2374,16 +2374,14 @@
 
 void command_setpass(Client *c, const Seperator *sep)
 {
-	if(sep->argnum != 2)
-		c->Message(0, "Format: #setpass accountname password");
+	if(sep->argnum != 1)
+		c->Message(0, "Format: #setpass password");
 	else {
-		sint16 tmpstatus = 0;
-		int32 tmpid = database.GetAccountIDByName(sep->arg[1], &tmpstatus);
-		if (!tmpid)
+		int32 lsid = c->LSAccountID();
+		int32 acctid = database.GetAccountIDByChar(c->GetName());
+		if (!acctid)
 			c->Message(0, "Error: Account not found");
-		else if (tmpstatus > c->Admin())
-			c->Message(0, "Cannot change password: Account's status is higher than yours");
-		else if (database.SetLocalPassword(tmpid, sep->arg[2]))
+		else if (database.SetLocalPassword(acctid, sep->arg[1], c->AccountName(), lsid))
 			c->Message(0, "Password changed.");
 		else
 			c->Message(0, "Error changing password.");
Reply With Quote