Browse Source

Fixed bug #3 (World crashing when port already in use) - will gracefully exit
Changed string* WorldDatabase::GetZoneName to string WorldDatabase::GetZoneName, this will prevent memory leaks when people forget to delete the memory
Changed ZoneScripts to use the one in the ZoneScripts directory if the lua_script field in the zones table is empty, but the zonescript file exists on disk, warning is displayed it World

LethalEncounter 3 years ago
parent
commit
09bf3a3378

+ 11 - 12
EQ2/source/WorldServer/Commands/Commands.cpp

@@ -2562,9 +2562,8 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 			break;
 							 }
 		case COMMAND_ZONE:{
-			string* zonename = 0;
 			int32 instanceID = 0;
-			const char* zone = 0;
+			string zone;
 			int32 zone_id = 0;
 			bool listSearch = false;
 			bool isInstance = false;
@@ -2629,10 +2628,10 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 					if(sep->IsNumber(0))
 					{
 						zone_id = atoul(sep->arg[0]);
-						zonename = database.GetZoneName(zone_id);
+						string zonename = database.GetZoneName(zone_id);
 
-						if(zonename)
-							zone = zonename->c_str();
+						if(zonename.length() > 0)
+							zone = zonename;
 					}
 					else
 						zone = sep->arg[0];
@@ -2653,24 +2652,25 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 
 			if(!listSearch)
 			{
-				if(!zone)
+				if(zone.length() == 0)
 					client->Message(CHANNEL_COLOR_RED, "Error: Invalid Zone");
 				else if(instanceID != client->GetCurrentZone()->GetInstanceID() || 
 					zone_id != client->GetCurrentZone()->GetZoneID())
 				{
-					if(database.VerifyZone(zone))
+					const char* zonestr = zone.c_str();
+					if(database.VerifyZone(zonestr))
 					{
-						if(client->CheckZoneAccess(zone))
+						if(client->CheckZoneAccess(zonestr))
 						{
-							client->Message(CHANNEL_COLOR_YELLOW,"Zoning to %s...", zone);
+							client->Message(CHANNEL_COLOR_YELLOW,"Zoning to %s...", zonestr);
 							if(isInstance)
 								client->Zone(instanceID,true,true);
 							else
-								client->Zone(zone);
+								client->Zone(zonestr);
 						}
 					}
 					else
-						client->Message(CHANNEL_COLOR_RED, "Error: Zone '%s' not found.  To get a list type /zone list", zone);
+						client->Message(CHANNEL_COLOR_RED, "Error: Zone '%s' not found.  To get a list type /zone list", zonestr);
 				}
 				else
 					client->Message(CHANNEL_COLOR_RED, "Error: You are already in that zone!");
@@ -2708,7 +2708,6 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 					client->SimpleMessage(CHANNEL_COLOR_YELLOW,"Syntax: /zone list [partial zone name]");
 				}
 			}
-			safe_delete(zonename);
 			break;
 		}
 		case COMMAND_USE: {

+ 3 - 2
EQ2/source/WorldServer/Housing/HousingPackets.cpp

@@ -80,8 +80,9 @@ void ClientPacketFunctions::SendHousingList(Client* client) {
 		name.append("'s ");
 		name.append(hz->name);
 		packet->setArrayDataByName("house_id", ph->unique_id, i);
-		string* zone_name = database.GetZoneName(hz->zone_id);
-		packet->setArrayDataByName("zone", zone_name->c_str(), i);
+		string zone_name = database.GetZoneName(hz->zone_id);
+		if(zone_name.length() > 0)
+			packet->setArrayDataByName("zone", zone_name.c_str(), i);
 		packet->setArrayDataByName("house_city", hz->name.c_str(), i);
 		packet->setArrayDataByName("house_address", "", i); // need this pulled from live
 		packet->setArrayDataByName("house_description", name.c_str(), i);

+ 17 - 25
EQ2/source/WorldServer/Player.cpp

@@ -415,21 +415,17 @@ PacketStruct* PlayerInfo::serialize2(int16 version){
 		packet->setDataByName("max_weight", info_struct->max_weight);
 		packet->setDataByName("pet_name", info_struct->pet_name);
 		packet->setDataByName("status_points", info_struct->status_points);
-		string* bind_name = 0;
-		if(bind_zone_id > 0)
-			bind_name = database.GetZoneName(bind_zone_id);
-		if(bind_name){
-			packet->setDataByName("bind_zone", bind_name->c_str());
-			safe_delete(bind_name);
+		if(bind_zone_id > 0){
+			string bind_name = database.GetZoneName(bind_zone_id);
+			if (bind_name.length() > 0)
+				packet->setDataByName("bind_zone", bind_name.c_str());
 		}
 		else
 			packet->setDataByName("bind_zone", "None");
-		string* house_name = 0;
-		if(house_zone_id > 0)
-			house_name = database.GetZoneName(house_zone_id);
-		if(house_name){
-			packet->setDataByName("house_zone", house_name->c_str());
-			safe_delete(house_name);
+		if(house_zone_id > 0){
+			string house_name = database.GetZoneName(house_zone_id);
+			if (house_name.length() > 0)
+				packet->setDataByName("house_zone", house_name.c_str());
 		}
 		else
 			packet->setDataByName("house_zone", "None");
@@ -922,22 +918,18 @@ EQ2Packet* PlayerInfo::serialize(int16 version, int16 modifyPos, int32 modifyVal
 		packet->setDataByName("status_points", 999999);// info_struct->status_points);
 		packet->setDataByName("guild_status", 888888);
 		//unknown_1096_44_MJ
-		string* house_name = 0;
-		if (house_zone_id > 0)
-			house_name = database.GetZoneName(house_zone_id);
-		if (house_name) {
-			packet->setDataByName("house_zone", house_name->c_str());
-			safe_delete(house_name);
+		if (house_zone_id > 0){
+			string house_name = database.GetZoneName(house_zone_id);
+			if(house_name.length() > 0)
+				packet->setDataByName("house_zone", house_name.c_str());
 		}
 		else
 			packet->setDataByName("house_zone", "abcdefghijklmnopqrst");
-		//unknown_1096_45_MJ
-		string* bind_name = 0;
-		if (bind_zone_id > 0)
-			bind_name = database.GetZoneName(bind_zone_id);
-		if (bind_name) {
-			packet->setDataByName("bind_zone", bind_name->c_str());
-			safe_delete(bind_name);
+		//unknown_1096_45_MJ		
+		if (bind_zone_id > 0){
+			string bind_name = database.GetZoneName(bind_zone_id);
+			if(bind_name.length() > 0)
+				packet->setDataByName("bind_zone", bind_name.c_str());
 		}
 		else
 			packet->setDataByName("bind_zone", "abcdefghijklmnopqrst");

+ 4 - 7
EQ2/source/WorldServer/Sign.cpp

@@ -245,11 +245,10 @@ void Sign::HandleUse(Client* client, string command)
 	{
 		if( GetSignDistance() == 0 || client->GetPlayer()->GetDistance(this) <= GetSignDistance() )
 		{
-			string* name = database.GetZoneName(GetSignZoneID());
-
-			if( name )
+			string name = database.GetZoneName(GetSignZoneID());
+			if( name.length() >0 )
 			{
-				if( !client->CheckZoneAccess(name->c_str()) )
+				if( !client->CheckZoneAccess(name.c_str()) )
 					return;
 
 				// determine if the coordinates should be set (returns false if they should)
@@ -275,10 +274,8 @@ void Sign::HandleUse(Client* client, string command)
 				if ( !client->TryZoneInstance(GetSignZoneID(), zone_coords_invalid) )
 				{
 					LogWrite(SIGN__DEBUG, 0, "Sign", "Sending client to instance of zone_id: %u", GetSignZoneID());
-					client->Zone(name->c_str(), zone_coords_invalid);
+					client->Zone(name.c_str(), zone_coords_invalid);
 				}
-
-				safe_delete(name);
 			}
 			else
 			{

+ 6 - 8
EQ2/source/WorldServer/World.cpp

@@ -554,12 +554,11 @@ ZoneServer* ZoneList::Get(int32 id, bool loadZone) {
 	if(ret)
 		tmp = ret;
 	else if (loadZone) {
-		string* zonename = database.GetZoneName(id);
-		if(zonename){
-			tmp = new ZoneServer(zonename->c_str());
+		string zonename = database.GetZoneName(id);
+		if(zonename.length() >0){
+			tmp = new ZoneServer(zonename.c_str());
 			database.LoadZoneInfo(tmp);
 			tmp->Init();
-			safe_delete(zonename);
 		}
 	}
 	return tmp;
@@ -604,9 +603,9 @@ ZoneServer* ZoneList::GetByInstanceID(int32 id, int32 zone_id) {
 	if(ret)
 		tmp = ret;
 	else if ( zone_id > 0 ){
-		string* zonename = database.GetZoneName(zone_id);
-		if(zonename){
-			tmp = new ZoneServer(zonename->c_str());
+		string zonename = database.GetZoneName(zone_id);
+		if(zonename.length() > 0){
+			tmp = new ZoneServer(zonename.c_str());
 
 			// the player is trying to preload an already existing instance but it isn't loaded
 			if ( id > 0 )
@@ -614,7 +613,6 @@ ZoneServer* ZoneList::GetByInstanceID(int32 id, int32 zone_id) {
 
 			database.LoadZoneInfo(tmp);
 			tmp->Init();
-			safe_delete(zonename);
 		}
 	}
 	return tmp;

+ 26 - 8
EQ2/source/WorldServer/WorldDatabase.cpp

@@ -3500,8 +3500,13 @@ void WorldDatabase::UpdateStartingZone(int32 char_id, int8 class_id, int8 race_i
 		return;
  	}
 
-	if(query.GetAffectedRows() > 0)
-		LogWrite(PLAYER__DEBUG, 0, "Player", "Setting New Character Starting Zone to '%s' due to no valid options!", GetZoneName(1)->c_str());
+	if (query.GetAffectedRows() > 0) {
+		string zone_name = GetZoneName(1);
+		if(zone_name.length() > 0)
+			LogWrite(PLAYER__DEBUG, 0, "Player", "Setting New Character Starting Zone to '%s' due to no valid options!", zone_name.c_str());
+		else
+			LogWrite(PLAYER__DEBUG, 0, "Player", "Unable to set New Character Starting Zone due to no valid options!");
+	}
 
 	return;
 }
@@ -3635,11 +3640,9 @@ string WorldDatabase::GetZoneDescription(int32 id){
 	return ret;
 }
 
-string* WorldDatabase::GetZoneName(int32 id){
-	string* ret = new string;
+string WorldDatabase::GetZoneName(int32 id){
 	if (zone_names.count(id) > 0){
-		ret->assign(zone_names[id]);
-		return ret;
+		return zone_names[id];
 	}
 	Query query;
 	MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT `name` FROM zones where `id` = %u", id);
@@ -3647,9 +3650,9 @@ string* WorldDatabase::GetZoneName(int32 id){
 		MYSQL_ROW row;
 		row = mysql_fetch_row(result);
 		zone_names[id] = row[0];
-		ret->assign(zone_names[id]);
+		return zone_names[id];
 	}
-	return ret;
+	return string("");
 }
 
 bool WorldDatabase::VerifyZone(const char* name){
@@ -3930,6 +3933,21 @@ void WorldDatabase::LoadZoneScriptData() {
 					world.AddZoneScript(zone_id, zone_script.c_str());
 					total++;
 				}
+				else if (zone_id > 0) {
+					
+					string tmpScript;
+					tmpScript.append("ZoneScripts/");
+					string zonename = GetZoneName(zone_id);
+					tmpScript.append(zonename);
+					tmpScript.append(".lua");
+					struct stat buffer;
+					bool fileExists = (stat(tmpScript.c_str(), &buffer) == 0);
+					if (fileExists)
+					{
+						LogWrite(LUA__INFO, 0, "LUA", "No zonescript file described in the database, overriding with ZoneScript %s for Zone ID %u", (char*)tmpScript.c_str(), zone_id);
+						world.AddZoneScript(zone_id, tmpScript.c_str());
+					}
+				}
 			}
 		}
 	}

+ 1 - 1
EQ2/source/WorldServer/WorldDatabase.h

@@ -129,7 +129,7 @@ public:
 
 	void PingNewDB();
 
-	string*	GetZoneName(int32 id);
+	string	GetZoneName(int32 id);
 	string	GetZoneDescription(int32 id);
 	int32	LoadCharacterSkills(int32 char_id, Player* player);
 	void	DeleteCharacterSkill(int32 char_id, Skill* skill);

+ 3 - 4
EQ2/source/WorldServer/client.cpp

@@ -558,8 +558,8 @@ void Client::HandlePlayerRevive(int32 point_id)
 
 	if (revive_point && revive_point->zone_id != GetCurrentZone()->GetZoneID() && revive_point->zone_id != 0)
 	{
-		string* zone_name = database.GetZoneName(revive_point->zone_id);
-		if (!zone_name || zone_name->length() == 0)
+		string zone_name = database.GetZoneName(revive_point->zone_id);
+		if (zone_name.length() == 0)
 		{
 			LogWrite(CCLIENT__WARNING, 0, "Client", "Unable to zone player to revive zone ID '%u', using current zone's safe coords.", revive_point->zone_id);
 			x = GetCurrentZone()->GetSafeX();
@@ -573,9 +573,8 @@ void Client::HandlePlayerRevive(int32 point_id)
 			LogWrite(CCLIENT__DEBUG, 0, "Client", "Sending player to revive zone ID '%u', using current zone's safe coords.", revive_point->zone_id);
 			location_name = revive_point->location_name.c_str();
 			player->ClearEverything();
-			Zone(zone_name->c_str(), false);
+			Zone(zone_name.c_str(), false);
 		}
-		safe_delete(zone_name);
 	}
 
 	zone_desc = GetCurrentZone()->GetZoneDescription();

+ 114 - 112
EQ2/source/WorldServer/net.cpp

@@ -350,7 +350,7 @@ int main(int argc, char** argv) {
 	}
 
 	LogWrite(WORLD__INFO, 0, "World", "Total World startup time: %u seconds.", Timer::GetUnixTimeStamp() - t_total);
-
+	int ret_code = 0;
 	if (eqsf.Open(net.GetWorldPort())) {
 		if (strlen(net.GetWorldAddress()) == 0)
 			LogWrite(NET__INFO, 0, "Net", "World server listening on port %i", net.GetWorldPort());
@@ -362,133 +362,135 @@ int main(int argc, char** argv) {
 	}
 	else {
 		LogWrite(NET__ERROR, 0, "Net", "Failed to open port %i.", net.GetWorldPort());
-		return 1;
-	}
-
-	Timer InterserverTimer(INTERSERVER_TIMER); // does MySQL pings and auto-reconnect
-	InterserverTimer.Trigger();
-	Timer* TimeoutTimer = new Timer(5000);
-	TimeoutTimer->Start();
-	EQStream* eqs = 0;
-	UpdateWindowTitle(0);
-	LogWrite(ZONE__INFO, 0, "Zone", "Starting static zones...");
-	database.LoadSpecialZones();
-	map<EQStream*, int32> connecting_clients;
-	map<EQStream*, int32>::iterator cc_itr;
-
-	// Check to see if a global channel is enabled, if so try to connect to it
-	if (rule_manager.GetGlobalRule(R_World, IRCGlobalEnabled)->GetBool()) {
-		LogWrite(CHAT__INFO, 0, "IRC", "Starting global IRC server...");
-		// Set the irc nick name to: ServerName[IRCBot]
-		string world_name = net.GetWorldName();
-		// Remove all white spaces from the server name
-		world_name.erase(std::remove(world_name.begin(), world_name.end(), ' '), world_name.end());
-		string nick = world_name + string("[IRCBot]");
-		// Connect the global server
-		irc.ConnectToGlobalServer(rule_manager.GetGlobalRule(R_World, IRCAddress)->GetString(), rule_manager.GetGlobalRule(R_World, IRCPort)->GetInt16(), nick.c_str());
-	}
-
-	// JohnAdams - trying to make multi-char console input
-	LogWrite(WORLD__DEBUG, 0, "Thread", "Starting console command thread...");
-	#ifdef WIN32
-					_beginthread(EQ2ConsoleListener, 0, NULL);
-	#else
-					/*pthread_t thread;
-					pthread_create(&thread, NULL, &EQ2ConsoleListener, NULL);
-					pthread_detach(thread);*/
-	#endif
-	//
+		ret_code = 1;
+	}
+	Timer* TimeoutTimer = 0;
+	if (ret_code == 0) {
+		Timer InterserverTimer(INTERSERVER_TIMER); // does MySQL pings and auto-reconnect
+		InterserverTimer.Trigger();
+		TimeoutTimer = new Timer(5000);
+		TimeoutTimer->Start();
+		EQStream* eqs = 0;
+		UpdateWindowTitle(0);
+		LogWrite(ZONE__INFO, 0, "Zone", "Starting static zones...");
+		database.LoadSpecialZones();
+		map<EQStream*, int32> connecting_clients;
+		map<EQStream*, int32>::iterator cc_itr;
+
+		// Check to see if a global channel is enabled, if so try to connect to it
+		if (rule_manager.GetGlobalRule(R_World, IRCGlobalEnabled)->GetBool()) {
+			LogWrite(CHAT__INFO, 0, "IRC", "Starting global IRC server...");
+			// Set the irc nick name to: ServerName[IRCBot]
+			string world_name = net.GetWorldName();
+			// Remove all white spaces from the server name
+			world_name.erase(std::remove(world_name.begin(), world_name.end(), ' '), world_name.end());
+			string nick = world_name + string("[IRCBot]");
+			// Connect the global server
+			irc.ConnectToGlobalServer(rule_manager.GetGlobalRule(R_World, IRCAddress)->GetString(), rule_manager.GetGlobalRule(R_World, IRCPort)->GetInt16(), nick.c_str());
+		}
+
+		// JohnAdams - trying to make multi-char console input
+		LogWrite(WORLD__DEBUG, 0, "Thread", "Starting console command thread...");
+#ifdef WIN32
+		_beginthread(EQ2ConsoleListener, 0, NULL);
+#else
+		/*pthread_t thread;
+		pthread_create(&thread, NULL, &EQ2ConsoleListener, NULL);
+		pthread_detach(thread);*/
+#endif
+		//
 
-	// just before starting loops, announce how to get console help
-	LogWrite(WORLD__INFO, 0, "Console", "Type 'help' or '?' and press enter for menu options.");
+		// just before starting loops, announce how to get console help
+		LogWrite(WORLD__INFO, 0, "Console", "Type 'help' or '?' and press enter for menu options.");
 
 
-	std::chrono::time_point<std::chrono::system_clock> frame_prev = std::chrono::system_clock::now();
-	while(RunLoops) {
-		Timer::SetCurrentTime();
-		std::chrono::time_point<std::chrono::system_clock> frame_now = std::chrono::system_clock::now();
-		frame_time = std::chrono::duration_cast<std::chrono::duration<double>>(frame_now - frame_prev).count();
-		frame_prev = frame_now;
-		
+		std::chrono::time_point<std::chrono::system_clock> frame_prev = std::chrono::system_clock::now();
+		while (RunLoops) {
+			Timer::SetCurrentTime();
+			std::chrono::time_point<std::chrono::system_clock> frame_now = std::chrono::system_clock::now();
+			frame_time = std::chrono::duration_cast<std::chrono::duration<double>>(frame_now - frame_prev).count();
+			frame_prev = frame_now;
+
 #ifndef NO_CATCH
-		try
-		{
+			try
+			{
 #endif
-			while ((eqs = eqsf.Pop())) {
-				struct in_addr	in;
-				in.s_addr = eqs->GetRemoteIP();
-				LogWrite(NET__DEBUG, 0, "Net", "New client from ip: %s port: %i", inet_ntoa(in), ntohs(eqs->GetRemotePort()));
-
-				// JA: Check for BannedIPs
-				if (rule_manager.GetGlobalRule(R_World, UseBannedIPsTable)->GetInt8() == 1)
-				{
-					LogWrite(WORLD__DEBUG, 0, "World", "Checking inbound connection %s against BannedIPs table", inet_ntoa(in));
- 					if (database.CheckBannedIPs(inet_ntoa(in)))
-					{ 
- 						LogWrite(WORLD__DEBUG, 0, "World", "Connection from %s FAILED banned IPs check.  Closing connection.", inet_ntoa(in));
- 						eqs->Close(); // JA: If the inbound IP is on the banned table, close the EQStream.
- 					}
-				}
+				while ((eqs = eqsf.Pop())) {
+					struct in_addr	in;
+					in.s_addr = eqs->GetRemoteIP();
+					LogWrite(NET__DEBUG, 0, "Net", "New client from ip: %s port: %i", inet_ntoa(in), ntohs(eqs->GetRemotePort()));
+
+					// JA: Check for BannedIPs
+					if (rule_manager.GetGlobalRule(R_World, UseBannedIPsTable)->GetInt8() == 1)
+					{
+						LogWrite(WORLD__DEBUG, 0, "World", "Checking inbound connection %s against BannedIPs table", inet_ntoa(in));
+						if (database.CheckBannedIPs(inet_ntoa(in)))
+						{
+							LogWrite(WORLD__DEBUG, 0, "World", "Connection from %s FAILED banned IPs check.  Closing connection.", inet_ntoa(in));
+							eqs->Close(); // JA: If the inbound IP is on the banned table, close the EQStream.
+						}
+					}
 
-				if(eqs && eqs->CheckActive() && client_list.ContainsStream(eqs) == false){
-					LogWrite(NET__DEBUG, 0, "Net", "Adding new client...");
-					Client* client = new Client(eqs);
-					client_list.Add(client);
-				}
-				else if(eqs && !client_list.ContainsStream(eqs)){
-					LogWrite(NET__DEBUG, 0, "Net", "Adding client to waiting list...");
-					connecting_clients[eqs] = Timer::GetCurrentTime2();
-				}
-			}
-			if(connecting_clients.size() > 0){
-				for(cc_itr = connecting_clients.begin(); cc_itr!=connecting_clients.end(); cc_itr++){
-					if(cc_itr->first && cc_itr->first->CheckActive() && client_list.ContainsStream(cc_itr->first) == false){
-						LogWrite(NET__DEBUG, 0, "Net", "Removing client from waiting list...");
-						Client* client = new Client(cc_itr->first);
+					if (eqs && eqs->CheckActive() && client_list.ContainsStream(eqs) == false) {
+						LogWrite(NET__DEBUG, 0, "Net", "Adding new client...");
+						Client* client = new Client(eqs);
 						client_list.Add(client);
-						connecting_clients.erase(cc_itr);
-						break;
 					}
-					else if(Timer::GetCurrentTime2() >= (cc_itr->second + 10000)){
-						connecting_clients.erase(cc_itr);
-						break;
+					else if (eqs && !client_list.ContainsStream(eqs)) {
+						LogWrite(NET__DEBUG, 0, "Net", "Adding client to waiting list...");
+						connecting_clients[eqs] = Timer::GetCurrentTime2();
 					}
 				}
-			}
-			world.Process();
-			client_list.Process();
-			loginserver.Process();
-			if(TimeoutTimer->Check()){
-				eqsf.CheckTimeout();
-			}
-			if (InterserverTimer.Check()) {
-				InterserverTimer.Start();
-				database.ping();
-				database.PingNewDB();
-				database.PingAsyncDatabase();
-
-				if (net.LoginServerInfo && loginserver.Connected() == false && loginserver.CanReconnect()) {
-					LogWrite(WORLD__DEBUG, 0, "Thread", "Starting autoinit loginserver thread...");
+				if (connecting_clients.size() > 0) {
+					for (cc_itr = connecting_clients.begin(); cc_itr != connecting_clients.end(); cc_itr++) {
+						if (cc_itr->first && cc_itr->first->CheckActive() && client_list.ContainsStream(cc_itr->first) == false) {
+							LogWrite(NET__DEBUG, 0, "Net", "Removing client from waiting list...");
+							Client* client = new Client(cc_itr->first);
+							client_list.Add(client);
+							connecting_clients.erase(cc_itr);
+							break;
+						}
+						else if (Timer::GetCurrentTime2() >= (cc_itr->second + 10000)) {
+							connecting_clients.erase(cc_itr);
+							break;
+						}
+					}
+				}
+				world.Process();
+				client_list.Process();
+				loginserver.Process();
+				if (TimeoutTimer->Check()) {
+					eqsf.CheckTimeout();
+				}
+				if (InterserverTimer.Check()) {
+					InterserverTimer.Start();
+					database.ping();
+					database.PingNewDB();
+					database.PingAsyncDatabase();
+
+					if (net.LoginServerInfo && loginserver.Connected() == false && loginserver.CanReconnect()) {
+						LogWrite(WORLD__DEBUG, 0, "Thread", "Starting autoinit loginserver thread...");
 #ifdef WIN32
-					_beginthread(AutoInitLoginServer, 0, NULL);
+						_beginthread(AutoInitLoginServer, 0, NULL);
 #else
-					pthread_t thread;
-					pthread_create(&thread, NULL, &AutoInitLoginServer, NULL);
-					pthread_detach(thread);
+						pthread_t thread;
+						pthread_create(&thread, NULL, &AutoInitLoginServer, NULL);
+						pthread_detach(thread);
 #endif
+					}
 				}
-			}
 #ifndef NO_CATCH
-		}
-		catch(...) {
-			LogWrite(WORLD__ERROR, 0, "World", "Exception caught in net main loop!");
-		}
+			}
+			catch (...) {
+				LogWrite(WORLD__ERROR, 0, "World", "Exception caught in net main loop!");
+			}
 #endif
-		if (numclients == 0) {
-			Sleep(10);
-			continue;
+			if (numclients == 0) {
+				Sleep(10);
+				continue;
+			}
+			Sleep(1);
 		}
-		Sleep(1);
 	}
 	LogWrite(WORLD__DEBUG, 0, "World", "The world is ending!");
 
@@ -515,7 +517,7 @@ int main(int argc, char** argv) {
 
 	LogWrite(WORLD__INFO, 0, "World", "Exiting... we hope you enjoyed your flight.");
 	LogStop();
-	return 0;
+	return ret_code;
 }
 
 ThreadReturnType ItemLoad (void* tmp)

+ 6 - 5
EQ2/source/common/EQStreamFactory.cpp

@@ -87,13 +87,14 @@ void EQStreamFactory::Close()
 {
 	CheckTimeout(true);
 	Stop();
-
+	if (sock != -1) {
 #ifdef WIN32
-	closesocket(sock);
+		closesocket(sock);
 #else
-	close(sock);
+		close(sock);
 #endif
-	sock=-1;
+		sock = -1;
+	}
 }
 bool EQStreamFactory::Open()
 {
@@ -121,7 +122,7 @@ struct sockaddr_in address;
 	}
 
 	if (bind(sock, (struct sockaddr *) &address, sizeof(address)) < 0) {
-		close(sock);
+		//close(sock);
 		sock=-1;
 		return false;
 	}

BIN
server/EQ2World__Debug_x64.exe