示例#1
0
void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
{
	if(logged_in)
	{
		server_log->Log(log_network_error, "WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting.");
		return;
	}

	if(strlen(i->account) <= 30)
	{
		account_name = i->account;
	}
	else
	{
		server_log->Log(log_network_error, "Handle_NewLSInfo error, account name was too long.");
		return;
	}

	if(strlen(i->password) <= 30)
	{
		account_password = i->password;
	}
	else
	{
		server_log->Log(log_network_error, "Handle_NewLSInfo error, account password was too long.");
		return;
	}

	if(strlen(i->name) <= 200)
	{
		long_name = i->name;
	}
	else
	{
		server_log->Log(log_network_error, "Handle_NewLSInfo error, long name was too long.");
		return;
	}

	if(strlen(i->shortname) <= 50)
	{
		short_name = i->shortname;
	}
	else
	{
		server_log->Log(log_network_error, "Handle_NewLSInfo error, short name was too long.");
		return;
	}

	if(strlen(i->local_address) <= 125)
	{
		if(strlen(i->local_address) == 0)
		{
			server_log->Log(log_network_error, "Handle_NewLSInfo error, local address was null, defaulting to localhost");
			local_ip = "127.0.0.1";
		}
		else
		{
			local_ip = i->local_address;
		}
	}
	else
	{
		server_log->Log(log_network_error, "Handle_NewLSInfo error, local address was too long.");
		return;
	}

	if(strlen(i->remote_address) <= 125)
	{
		if(strlen(i->remote_address) == 0)
		{
			in_addr in;
			in.s_addr = GetConnection()->GetrIP();
			remote_ip = inet_ntoa(in);
			server_log->Log(log_network_error, "Handle_NewLSInfo error, remote address was null, defaulting to stream address %s.", remote_ip.c_str());
		}
		else
		{
			remote_ip = i->remote_address;
		}
	}
	else
	{
		in_addr in;
		in.s_addr = GetConnection()->GetrIP();
		remote_ip = inet_ntoa(in);
		server_log->Log(log_network_error, "Handle_NewLSInfo error, remote address was too long, defaulting to stream address %s.", remote_ip.c_str());
	}

	if(strlen(i->serverversion) <= 64)
	{
		version = i->serverversion;
	}
	else
	{
		server_log->Log(log_network_error, "Handle_NewLSInfo error, server version was too long.");
		return;
	}

	if(strlen(i->protocolversion) <= 25)
	{
		protocol = i->protocolversion;
	}
	else
	{
		server_log->Log(log_network_error, "Handle_NewLSInfo error, protocol version was too long.");
		return;
	}

	server_type = i->servertype;
	logged_in = true;

	if (db.LoadServerSettings("options", "reject_duplicate_servers") == "TRUE")
	{
		if(server.SM->ServerExists(long_name, short_name, this))
		{
			server_log->Log(log_world_error, "World tried to login but there already exists a server that has that name.");
			return;
		}
	}
	else
	{
		if(server.SM->ServerExists(long_name, short_name, this))
		{
			server_log->Log(log_world_error, "World tried to login but there already exists a server that has that name.");
			server.SM->DestroyServerByName(long_name, short_name, this);
		}
	}

	if (db.LoadServerSettings("options", "unregistered_allowed") == "FALSE")
	{
		if(account_name.size() > 0 && account_password.size() > 0)
		{
			unsigned int s_id = 0;
			unsigned int s_list_type = 0;
			unsigned int s_trusted = 0;
			string s_desc;
			string s_list_desc;
			string s_acct_name;
			string s_acct_pass;
			if(db.GetWorldRegistration(s_id, s_desc, s_trusted, s_list_type, s_acct_name, s_acct_pass, long_name, short_name))
			{
				if(s_acct_name.size() == 0 || s_acct_pass.size() == 0)
				{
					server_log->Log(log_world, "Server %s(%s) successfully logged into account that had no user/password requirement.",
						long_name.c_str(), short_name.c_str());
					authorized = true;
					SetRuntimeID(s_id);
					server_list_type = s_list_type;
					desc = s_desc;
				}
				else if(s_acct_name.compare(account_name) == 0 && s_acct_pass.compare(account_password) == 0)
				{
					server_log->Log(log_world, "Server %s(%s) successfully logged in.",
						long_name.c_str(), short_name.c_str());
					authorized = true;
					SetRuntimeID(s_id);
					server_list_type = s_list_type;
					desc = s_desc;
					if(s_trusted)
					{
						server_log->Log(log_network_trace, "ServerOP_LSAccountUpdate sent to world");
						trusted = true;
						ServerPacket *outapp = new ServerPacket(ServerOP_LSAccountUpdate, 0);
						connection->SendPacket(outapp);
					}
				}
				else
				{
					server_log->Log(log_world, "Server %s(%s) attempted to log in but account and password did not match the entry in the database, and only"
						" registered servers are allowed.", long_name.c_str(), short_name.c_str());
					return;
				}
			}
			else
			{
				server_log->Log(log_world, "Server %s(%s) attempted to log in but database couldn't find an entry and only registered servers are allowed.",
					long_name.c_str(), short_name.c_str());
				return;
			}
		}
		else
		{
			server_log->Log(log_world, "Server %s(%s) did not attempt to log in but only registered servers are allowed.",
				long_name.c_str(), short_name.c_str());
			return;
		}
	}
	else
	{
		unsigned int s_id = 0;
		unsigned int s_list_type = 0;
		unsigned int s_trusted = 0;
		string s_desc;
		string s_list_desc;
		string s_acct_name;
		string s_acct_pass;

		if (db.GetWorldRegistration(s_id, s_desc, s_trusted, s_list_type, s_acct_name, s_acct_pass, long_name, short_name))
		{
			if(account_name.size() > 0 && account_password.size() > 0)
			{
				if(s_acct_name.compare(account_name) == 0 && s_acct_pass.compare(account_password) == 0)
				{
					server_log->Log(log_world, "Server %s(%s) successfully logged in.", long_name.c_str(), short_name.c_str());
					authorized = true;
					SetRuntimeID(s_id);
					server_list_type = s_list_type;
					desc = s_desc;
					if(s_trusted)
					{
						server_log->Log(log_network_trace, "ServerOP_LSAccountUpdate sent to world");
						trusted = true;
						ServerPacket *outapp = new ServerPacket(ServerOP_LSAccountUpdate, 0);
						connection->SendPacket(outapp);
					}
				}
				else
				{
					// this is the first of two cases where we should deny access even if unregistered is allowed
					server_log->Log(log_world, "Server %s(%s) attempted to log in but account and password did not match the entry in the database.",
						long_name.c_str(), short_name.c_str());
				}
			}
			else
			{
				if(s_acct_name.size() > 0 || s_acct_pass.size() > 0)
				{
					// this is the second of two cases where we should deny access even if unregistered is allowed
					server_log->Log(log_world, "Server %s(%s) did not attempt to log in but this server requires a password.",
						long_name.c_str(), short_name.c_str());
				}
				else
				{
					server_log->Log(log_world, "Server %s(%s) did not attempt to log in but unregistered servers are allowed.",
						long_name.c_str(), short_name.c_str());
					authorized = true;
					SetRuntimeID(s_id);
					server_list_type = 0;
				}
			}
		}
		else
		{
			s_id = 0;
			server_log->Log(log_world, "Server %s(%s) attempted to log in but database couldn't find an entry but unregistered servers are allowed.",
				long_name.c_str(), short_name.c_str());
			if(db.CreateWorldRegistration(long_name, short_name, s_id))
			{
				authorized = true;
				SetRuntimeID(s_id);
				server_list_type = 0;
			}
		}
	}

	in_addr in;
	in.s_addr = connection->GetrIP();
	db.UpdateWorldRegistration(GetRuntimeID(), long_name, string(inet_ntoa(in)));

	if(authorized)
	{
		server.CM->UpdateServerList();
	}
}