/*!
	If share is NULL, the default authentication for the server is returned.
*/
bool
AuthenticationServer::_GetAuthentication(const char* context,
	const char* server, const char* share, String* user, String* password)
{
	if (!context || !server || !user || !password)
		return B_BAD_VALUE;
	// get the server entry
	AutoLocker<Locker> _(fLock);
	ServerKey key(context, server);
	ServerEntry* serverEntry = fServerEntries->Get(key);
	if (!serverEntry)
		return false;
	// get the authentication
	const Authentication* authentication = NULL;
	if (share) {
		serverEntry->GetAuthentication(share);
		if (!authentication && serverEntry->UseDefaultAuthentication())
			authentication = &serverEntry->GetDefaultAuthentication();
	} else
		authentication = &serverEntry->GetDefaultAuthentication();
	if (!authentication || !authentication->IsValid())
		return false;
	return (user->SetTo(authentication->GetUser())
		&& password->SetTo(authentication->GetPassword()));
}
// _AddAuthentication
status_t
AuthenticationServer::_AddAuthentication(const char* context,
	const char* server, const char* share, const char* user,
	const char* password, bool makeDefault)
{
	AutoLocker<Locker> _(fLock);
	ServerKey key(context, server);
	// get the server entry
	ServerEntry* serverEntry = fServerEntries->Get(key);
	if (!serverEntry) {
		// server entry does not exist yet: create a new one
		serverEntry = new(nothrow) ServerEntry;
		if (!serverEntry)
			return B_NO_MEMORY;
		status_t error = fServerEntries->Put(key, serverEntry);
		if (error != B_OK) {
			delete serverEntry;
			return error;
		}
	}
	// put the authentication
	status_t error = serverEntry->SetAuthentication(share, user, password);
	if (error == B_OK) {
		if (makeDefault || !serverEntry->UseDefaultAuthentication())
			serverEntry->SetDefaultAuthentication(user, password);
		if (makeDefault)
			serverEntry->SetUseDefaultAuthentication(true);
	}
	return error;
}
int main(int argc, char* argv[])
{
#ifdef VAULTMP_DEBUG
#ifdef __WIN32__

	if (LoadLibrary("exchndl.dll") == NULL)
		return 0;

#else
	system("ulimit -c unlimited");
#endif
#endif

#ifdef __WIN32__
	printf("Vault-Tec dedicated server %s (Windows)\n----------------------------------------------------------\n", DEDICATED_VERSION);
#else
	printf("Vault-Tec dedicated server %s (Unix)\n----------------------------------------------------------\n", DEDICATED_VERSION);
#endif

	unsigned char game;
	int port;
	int players;
	int fileslots;
	bool query;
	bool files;
	const char* announce;
	const char* scripts;
	const char* mods;
	const char* savegame;

	dictionary* config = iniparser_load(argc > 1 ? argv[1] : "vaultserver.ini");

	const char* game_str = iniparser_getstring(config, "general:game", "fallout3");

	if (stricmp(game_str, "newvegas") == 0)
		game = NEWVEGAS;
	else
		game = FALLOUT3;

	port = iniparser_getint(config, "general:port", RAKNET_STANDARD_PORT);
	players = iniparser_getint(config, "general:players", RAKNET_STANDARD_CONNECTIONS);
	query = (bool) iniparser_getboolean(config, "general:query", 1);
	files = (bool) iniparser_getboolean(config, "general:fileserve", 0);
	fileslots = iniparser_getint(config, "general:fileslots", 8);
	announce = iniparser_getstring(config, "general:master", "vaultmp.com");
	savegame = iniparser_getstring(config, "general:save", "default.fos");
	scripts = iniparser_getstring(config, "scripts:scripts", "");
	mods = iniparser_getstring(config, "mods:mods", "");

	ServerEntry* self = new ServerEntry(game);
	self->SetServerRule("version", DEDICATED_VERSION);
	Dedicated::SetServerEntry(self);

	char base[MAX_PATH];
	_getcwd(base, sizeof(base));

	try
	{
		putenv(PWNFILES_PATH);
		char _scripts[strlen(scripts) + 1];
		snprintf(_scripts, sizeof(_scripts), "%s", scripts);
		Script::LoadScripts(_scripts, base);
	}

	catch (std::exception& e)
	{
		try
		{
			VaultException& vaulterror = dynamic_cast<VaultException&>(e);
			vaulterror.Console();
		}

		catch (std::bad_cast& no_vaulterror)
		{
			VaultException vaulterror(e.what());
			vaulterror.Console();
		}
	}

	try
	{
		char file[MAX_PATH];
		snprintf(file, sizeof(file), "%s/%s/%s", base, SAVEGAME_PATH, savegame);

		unsigned int crc;

		if (!Utils::crc32file(file, &crc))
			throw VaultException("Could not find savegame %s in folder %s", savegame, SAVEGAME_PATH);

		Dedicated::SetSavegame(Savegame(string(savegame), crc));

		char buf[strlen(mods) + 1];
		strcpy(buf, mods);
		char* token = strtok(buf, ",");
		ModList modfiles;

		while (token != NULL)
		{
			snprintf(file, sizeof(file), "%s/%s/%s", base, MODFILES_PATH, token);

			if (!Utils::crc32file(file, &crc))
				throw VaultException("Could not find modfile %s in folder %s", token, MODFILES_PATH);

			modfiles.push_back(pair<string, unsigned int>(string(token), crc));

			token = strtok(NULL, ",");
		}

		Dedicated::SetModfiles(modfiles);

		thread hDedicatedThread = Dedicated::InitializeServer(port, players, announce, query, files, fileslots);
		thread hInputThread = thread(InputThread);

		hDedicatedThread.join();

		if (hInputThread.joinable())
			hInputThread.join();
	}

	catch (std::exception& e)
	{
		try
		{
			VaultException& vaulterror = dynamic_cast<VaultException&>(e);
			vaulterror.Console();
		}

		catch (std::bad_cast& no_vaulterror)
		{
			VaultException vaulterror(e.what());
			vaulterror.Console();
		}
	}

	Script::UnloadScripts();
	iniparser_freedict(config);
	delete self;

#ifdef __WIN32__
	system("PAUSE");
#endif

	return 0;
}
Exemplo n.º 4
0
void MasterServer::MasterThread()
{
	sockdescr = new SocketDescriptor(RAKNET_PORT, 0);
	peer = RakPeerInterface::GetInstance();
	peer->Startup(RAKNET_CONNECTIONS, sockdescr, 1, THREAD_PRIORITY_NORMAL);
	peer->SetMaximumIncomingConnections(RAKNET_CONNECTIONS);
	peer->SetIncomingPassword(MASTER_VERSION, sizeof(MASTER_VERSION));

	Packet* packet;

	while (thread)
	{
		for (packet = peer->Receive(); packet; peer->DeallocatePacket(packet), packet = peer->Receive())
		{
			switch (packet->data[0])
			{
				case ID_NEW_INCOMING_CONNECTION:
					Utils::timestamp();
					printf("New incoming connection from %s\n", packet->systemAddress.ToString());
					break;

				case ID_DISCONNECTION_NOTIFICATION:
					Utils::timestamp();
					printf("Client disconnected (%s)\n", packet->systemAddress.ToString());
					RemoveServer(packet->systemAddress);
					break;

				case ID_CONNECTION_LOST:
					Utils::timestamp();
					printf("Lost connection (%s)\n", packet->systemAddress.ToString());
					RemoveServer(packet->systemAddress);
					break;

				case ID_MASTER_QUERY:
				{
					BitStream query;
					query.Write((MessageID) ID_MASTER_QUERY);
					query.Write((unsigned int) serverList.size());

					for (map<SystemAddress, ServerEntry>::iterator i = serverList.begin(); i != serverList.end(); ++i)
					{
						SystemAddress addr = i->first;
						ServerEntry entry = i->second;
						RakString name(entry.GetServerName().c_str());
						RakString map(entry.GetServerMap().c_str());
						unsigned int players = entry.GetServerPlayers().first;
						unsigned int playersMax = entry.GetServerPlayers().second;
						const std::map<string, string>& rules = entry.GetServerRules();
						const std::vector<string>& modfiles = entry.GetServerModFiles();

						query.Write(addr);
						query.Write(name);
						query.Write(map);
						query.Write(players);
						query.Write(playersMax);
						query.Write(rules.size());

						for (const auto& k : rules)
						{
							RakString key(k.first.c_str());
							RakString value(k.second.c_str());
							query.Write(key);
							query.Write(value);
						}

						query.Write(modfiles.size());

						for (const auto& k : modfiles)
						{
						    RakString mod_name(k.c_str());
						    query.Write(mod_name);
						}
					}

					peer->Send(&query, HIGH_PRIORITY, RELIABLE, 0, packet->systemAddress, false, 0);

					Utils::timestamp();
					printf("Query processed (%s)\n", packet->systemAddress.ToString());
					break;
				}

				case ID_MASTER_UPDATE:
				{
					BitStream queryy(packet->data, packet->length, false);
					queryy.IgnoreBytes(sizeof(MessageID));

					SystemAddress addr;
					queryy.Read(addr);

					BitStream query;

					map<SystemAddress, ServerEntry>::iterator i;
					i = serverList.find(addr);

					query.Write((MessageID) ID_MASTER_UPDATE);
					query.Write(addr);

					if (i != serverList.end())
					{
						ServerEntry entry = i->second;
						RakString name(entry.GetServerName().c_str());
						RakString map(entry.GetServerMap().c_str());
						unsigned int players = entry.GetServerPlayers().first;
						unsigned int playersMax = entry.GetServerPlayers().second;
						const std::map<string, string>& rules = entry.GetServerRules();
						const std::vector<string>& modfiles = entry.GetServerModFiles();

						query.Write(name);
						query.Write(map);
						query.Write(players);
						query.Write(playersMax);
						query.Write(rules.size());

						for (const auto& k : rules)
						{
							RakString key(k.first.c_str());
							RakString value(k.second.c_str());
							query.Write(key);
							query.Write(value);
						}

						query.Write(modfiles.size());

						for (const auto& k : modfiles)
						{
						    RakString mod_name(k.c_str());
						    query.Write(mod_name);
						}
					}

					peer->Send(&query, HIGH_PRIORITY, RELIABLE, 0, packet->systemAddress, false, 0);

					Utils::timestamp();
					printf("Update processed (%s)\n", packet->systemAddress.ToString());
					break;
				}

				case ID_MASTER_ANNOUNCE:
				{
					BitStream query(packet->data, packet->length, false);
					query.IgnoreBytes(sizeof(MessageID));

					bool announce;
					query.Read(announce);

					map<SystemAddress, ServerEntry>::iterator i;
					i = serverList.find(packet->systemAddress);

					if (announce)
					{
						RakString name, map;
						unsigned int players, playersMax, rsize, msize;

						query.Read(name);
						query.Read(map);
						query.Read(players);
						query.Read(playersMax);
						query.Read(rsize);

						ServerEntry* entry;

						if (i == serverList.end())
						{
							std::pair<std::map<SystemAddress, ServerEntry>::iterator, bool> k;
							k = serverList.insert(make_pair(packet->systemAddress, ServerEntry(name.C_String(), map.C_String(), make_pair(players, playersMax), 999)));
							entry = &(k.first)->second;
						}
						else
						{
							entry = &i->second;
							entry->SetServerName(name.C_String());
							entry->SetServerMap(map.C_String());
							entry->SetServerPlayers(make_pair(players, playersMax));
						}

						for (unsigned int j = 0; j < rsize; j++)
						{
							RakString key, value;
							query.Read(key);
							query.Read(value);
							entry->SetServerRule(key.C_String(), value.C_String());
						}

						entry->ClearModFiles();
						query.Read(msize);

                        for (unsigned int j = 0; j < msize; j++)
                        {
                            RakString mod_name;
                            query.Read(mod_name);
                            entry->SetModFiles(mod_name.C_String());
                        }
					}
					else if (i != serverList.end())
						serverList.erase(i);

					Utils::timestamp();
					printf("Announce processed (%s)\n", packet->systemAddress.ToString());
					break;
				}
			}
		}

		this_thread::sleep_for(chrono::milliseconds(1));
	}

	peer->Shutdown(300);
	RakPeerInterface::DestroyInstance(peer);
}