DWORD WINAPI Interface::CommandThreadSend( LPVOID data )
{
    try
    {
        while (!wakeup && !endThread)
            Sleep(10);

		while ( !endThread )
		{
			CommandList::iterator it;
			CommandList::iterator insertAt = cmdlist.end();

			if ( !tmplist.empty() )
			{
				cs.StartSession();
				cmdlist.splice( cmdlist.begin(), tmplist );
				cs.EndSession();
			}

			for ( it = cmdlist.begin(); it != cmdlist.end() && !endThread; )
			{
				if ( !tmplist.empty() )
				{
					cs.StartSession();

                    unsigned int count = tmplist.size();

					if ( insertAt != cmdlist.end() )
					{
						CommandList::iterator insertAt_tmp = insertAt;
						++insertAt_tmp;
						cmdlist.splice( insertAt_tmp, tmplist );
					}

					else
					{
						CommandList::iterator it_tmp = it;
						++it_tmp;
						cmdlist.splice( it_tmp, tmplist );
					}

					CommandList::iterator it_tmp = it;
					advance( it_tmp, count );

					insertAt = it_tmp;

					cs.EndSession();
				}

                map<string, string>::iterator al = alias.find(it->first->first);
                string name = (al != alias.end() ? al->second : it->first->first);
                string def = defs.find(name)->second;
                ParamContainer& param = it->first->second;
                vector<signed int>& data = it->second;

                if (data[2] != 0)
                {
                    data[2]--;
                    ++it;
                    continue;
                }

                multimap<string, string> cmd = Interface::Evaluate(name, def, param);

                if (cmd.size() != 0)
                {
                    signed int key = data[3];

                    CommandParsed stream = API::Translate(cmd, key);

                    if (stream.size() != 0)
                    {
                        CommandParsed::iterator it2;

                        for (it2 = stream.begin(); it2 != stream.end() && !endThread; ++it2)
                        {
                            char* content = *it2;
                            pipeServer->Send(content);
                        }

                        for (it2 = stream.begin(); it2 != stream.end(); ++it2)
                        {
                            char* content = *it2;
                            delete[] content;
                        }
                    }
                }

                if (data[0] == 0)
                {
                    FreeContainer(param);
                    natives.erase(it->first);
                    it = cmdlist.erase(it);
                }
                else
                    ++it;
            }
        }
    }
    catch (std::exception& e)
    {
        try
        {
            VaultException& vaulterror = dynamic_cast<VaultException&>(e);
            vaulterror.Message();
        }
        catch (std::bad_cast& no_vaulterror)
        {
            VaultException vaulterror(e.what());
            vaulterror.Message();
        }

#ifdef VAULTMP_DEBUG
        if (debug != NULL)
            debug->Print("Send thread is going to terminate (ERROR)", true);
#endif

        return ((DWORD) data);
    }

    return ((DWORD) data);
}
DWORD WINAPI Interface::CommandThreadReceive( LPVOID data )
{
	try
	{
		pipeClient->SetPipeAttributes( "BethesdaClient", PIPE_LENGTH );
		pipeClient->CreateServer();
		pipeClient->ConnectToServer();

		pipeServer->SetPipeAttributes( "BethesdaServer", PIPE_LENGTH );

		while ( !pipeServer->ConnectToServer() && !endThread );

		char buffer[PIPE_LENGTH];
		char code;

		if ( !endThread )
		{
			do
			{
				ZeroMemory( buffer, sizeof( buffer ) );

				pipeClient->Receive( buffer );
				code = buffer[0];
				char* content = buffer + 1;

				if ( code == PIPE_OP_RETURN || code == PIPE_OP_RETURN_BIG )
				{
					vector<CommandResult> result = API::Translate( buffer );
					vector<CommandResult>::iterator it;

					for ( it = result.begin(); it != result.end(); ++it )
						resultHandler( it->first.first.first, it->first.first.second, it->first.second, it->second );
				}

				else if ( code == PIPE_SYS_WAKEUP )
				{
					wakeup = true;

#ifdef VAULTMP_DEBUG

					if ( debug != NULL )
						debug->Print( "vaultmp process waked up (game patched)", true );

#endif
				}

				else if ( code )
					throw VaultException( "Unknown pipe code identifier %02X", code );

				if ( lookupProgramID( ( char* ) data ) == 0 )
				{
					endThread = true;

#ifdef VAULTMP_DEBUG

					if ( debug != NULL )
						debug->Print( "Game process missing, shutting down", true );

#endif
				}
			}
			while ( code != PIPE_ERROR_CLOSE && !endThread );
		}

		// kill game process if running
	}

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

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

#ifdef VAULTMP_DEBUG

		if ( debug != NULL )
			debug->Print( "Receive thread is going to terminate (ERROR)", true );

#endif

		endThread = true;

		return ( ( DWORD ) data );
	}

#ifdef VAULTMP_DEBUG

	if ( debug != NULL )
		debug->Print( "Receive thread is going to terminate", true );

#endif

	endThread = true;

	return ( ( DWORD ) data );
}
Esempio n. 3
0
void Interface::CommandThreadReceive(bool steam)
{
	try
	{
		pipeClient->SetPipeAttributes("BethesdaClient", PIPE_LENGTH);
		pipeClient->CreateServer();
		pipeClient->ConnectToServer();

		pipeServer->SetPipeAttributes("BethesdaServer", PIPE_LENGTH);

		while (!pipeServer->ConnectToServer() && !endThread);

		unsigned char buffer[PIPE_LENGTH];

		buffer[0] = steam;
		pipeClient->Send(buffer);

		if (!endThread)
		{
			unsigned char code;

			while (!endThread)
			{
				ZeroMemory(buffer, sizeof(buffer));

				pipeClient->Receive(buffer);
				code = buffer[0];

				if (code == PIPE_OP_RETURN || code == PIPE_OP_RETURN_BIG || code == PIPE_OP_RETURN_RAW)
				{
					vector<CommandResult> result = API::Translate(buffer);

					for (CommandResult& _result : result)
					{
						resultHandler(get<0>(_result), get<1>(_result), get<2>(_result), get<3>(_result));

						if (endThread)
							break;
					}
				}
				else if (code == PIPE_SYS_WAKEUP)
				{
					wakeup = true;

#ifdef VAULTMP_DEBUG
					if (debug)
						debug->Print("vaultmp process waked up (game patched)", true);
#endif
				}
				else if (code == PIPE_ERROR_CLOSE)
				{
					if (!endThread)
						throw VaultException("Error in vaultmp.dll");
				}
				else if (code)
					throw VaultException("Unknown pipe code identifier %02X", code);
				else
					endThread = true;
			}
		}
	}
	catch (exception& e)
	{
		try
		{
			VaultException& vaulterror = dynamic_cast<VaultException&>(e);
			vaulterror.Message();
		}
		catch (bad_cast& no_vaulterror)
		{
			VaultException vaulterror(e.what());
			vaulterror.Message();
		}

#ifdef VAULTMP_DEBUG
		if (debug)
			debug->Print("Receive thread is going to terminate (ERROR)", true);
#endif
	}

	endThread = true;
}
Esempio n. 4
0
void Interface::CommandThreadSend()
{
	try
	{
		while (!wakeup && !endThread)
			this_thread::sleep_for(chrono::milliseconds(10));

		while (!endThread)
		{
			static_cs.StartSession();

			for (auto it = static_cmdlist.begin(); (it != static_cmdlist.end() || !dynamic_cmdlist.empty()) && !endThread;)
			{
				if (it != static_cmdlist.end())
				{
					const auto& next_list = *it;

					for (auto it = next_list.begin(); it != next_list.end() && !endThread; ++it)
					{
						vector<string> cmd = Interface::Evaluate(*it);

						if (!cmd.empty())
						{
							CommandParsed stream = API::Translate(cmd);

							for (auto it = stream.begin(); it != stream.end() && !endThread; ++it)
								pipeServer->Send(it->get());
						}
					}

					++it;
				}

				dynamic_cs.StartSession();

				for (; !dynamic_cmdlist.empty() && !endThread; natives.erase(dynamic_cmdlist.front().first), dynamic_cmdlist.pop_front())
				{
					dynamic_cs.EndSession();

					const auto& dynamic = dynamic_cmdlist.front();

					vector<string> cmd = Interface::Evaluate(dynamic.first);

					if (!cmd.empty())
					{
						CommandParsed stream = API::Translate(cmd, dynamic.second);

						for (auto it = stream.begin(); it != stream.end() && !endThread; ++it)
							pipeServer->Send(it->get());
					}

					dynamic_cs.StartSession();
				}

				dynamic_cs.EndSession();

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

			static_cs.EndSession();
		}
	}
	catch (exception& e)
	{
		try
		{
			VaultException& vaulterror = dynamic_cast<VaultException&>(e);
			vaulterror.Message();
		}
		catch (bad_cast& no_vaulterror)
		{
			VaultException vaulterror(e.what());
			vaulterror.Message();
		}

#ifdef VAULTMP_DEBUG

		if (debug)
			debug->Print("Send thread is going to terminate (ERROR)", true);

#endif
	}

	if (wakeup)
	{
		unsigned char buffer[PIPE_LENGTH];
		buffer[0] = PIPE_ERROR_CLOSE;
		pipeServer->Send(buffer);
	}

	endThread = true;
}
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;
}