Beispiel #1
0
FactoryObject GameFactory::GetObject(NetworkID id)
{
	Reference* reference;
	unsigned char type;

	cs.StartSession();

	reference = Network::Manager()->GET_OBJECT_FROM_ID<Reference*>(id);

	if (reference)
		type = GetShared(reference)->second;

	cs.EndSession();

	if (!reference)
		throw VaultException("Unknown object with NetworkID %llu", id);

	return FactoryObject(reference, type);
}
Beispiel #2
0
unsigned int GameFactory::LookupRefID(NetworkID id)
{
	Reference* reference;
	unsigned int refID;

	cs.StartSession();

	reference = Network::Manager()->GET_OBJECT_FROM_ID<Reference*>(id);

	if (reference)
		refID = reference->GetReference();

	cs.EndSession();

	if (!reference)
		throw VaultException("Unknown object with NetworkID %llu", id);

	return refID;
}
Lockable* Lockable::Retrieve(unsigned int key)
{
	Lockable* locked;

	cs.StartSession();

	try
	{
		locked = keymap.at(key)->Unlock(key);
	}
	catch (...)
	{
		cs.EndSession();
		throw VaultException("Key %08X did not unlock anything", key);
	}

	cs.EndSession();

	return locked;
}
unsigned int Lockable::NextKey()
{
	unsigned int next_key;
	unsigned int temp_key = key;

	while (keymap.find(temp_key) != keymap.end())
	{
		if (temp_key == UINT_MAX)
			temp_key = 0x01;
		else
			++temp_key;

		if (temp_key == key)
			throw VaultException("Lockable class ran out of keys");
	}

	next_key = temp_key;
	key = (temp_key == UINT_MAX ? (0x01) : (temp_key + 0x01));

	return next_key;
}
unsigned int GameFactory::LookupRefID(NetworkID id)
{
	unsigned int refID;

	cs.StartSession();

	try
	{
		Reference* reference = Network::Manager()->GET_OBJECT_FROM_ID<Reference*>(id);
		refID = (reference != NULL ? reference->GetReference() : throw VaultException("Unknown object with NetworkID %lld", id));
	}
	catch (...)
	{
		cs.EndSession();
		throw;
	}

	cs.EndSession();

	return refID;
}
weak_ptr<Lockable> Lockable::Poll(unsigned int key)
{
	weak_ptr<Lockable> shared;

	cs.StartSession();

	try
	{
		shared = sharemap.at(key);
		keymap.erase(key);
		sharemap.erase(key);
	}
	catch (...)
	{
		cs.EndSession();
		throw VaultException("Key %08X did not share anything", key);
	}

	cs.EndSession();

	return shared;
}
vector<FactoryObject> GameFactory::GetMultiple(const vector<unsigned int>& objects)
{
	vector<FactoryObject> result(objects.size());
	multimap<Reference*, unsigned int> sort;

	cs.StartSession();

	try
	{
		ReferenceList::iterator it;
		unsigned int i = 0;

		for (const NetworkID& id : objects)
		{
			for (it = instances.begin(); it != instances.end() && it->first->GetReference() != id; ++it);

			Reference* reference = (it != instances.end() ? it->first : NULL);

			if (!reference)
				throw VaultException("Unknown object with reference %08X", id);

			sort.insert(pair<Reference*, unsigned int>(reference, i));

			++i;
		}
	}
	catch (...)
	{
		cs.EndSession();
		throw;
	}

	cs.EndSession();

	for (const pair<Reference*, unsigned int>& reference : sort)
		result[reference.second] = FactoryObject(reference.first);

	return result;
}
Beispiel #8
0
vector<FactoryObject> GameFactory::GetMultiple(const vector<unsigned int>& objects)
{
	vector<FactoryObject> result(objects.size());
	multimap<ReferenceList::value_type, unsigned int> sort;

	cs.StartSession();

	try
	{
		ReferenceList::iterator it;
		unsigned int i = 0;

		for (const auto& refID : objects)
		{
			for (it = instances.begin(); it != instances.end() && it->first->GetReference() != refID; ++it);

			if (it == instances.end())
				throw VaultException("Unknown object with reference %08X", refID);

			// emplace
			sort.insert(make_pair(*it, i));

			++i;
		}
	}
	catch (...)
	{
		cs.EndSession();
		throw;
	}

	cs.EndSession();

	for (const auto& reference : sort)
		result[reference.second] = FactoryObject(reference.first.first.get(), reference.first.second);

	return result;
}
Beispiel #9
0
Exterior::Exterior(const string& table, sqlite3_stmt* stmt)
{
	if (sqlite3_column_count(stmt) != 5)
		throw VaultException("Malformed input database (exteriors): %s", table.c_str());

	unsigned int dlc = static_cast<unsigned int>(sqlite3_column_int(stmt, 4));
	// if DLC enabled

	dlc <<= 24;

	baseID = static_cast<unsigned int>(sqlite3_column_int(stmt, 0));
	x = sqlite3_column_int(stmt, 1);
	y = sqlite3_column_int(stmt, 2);
	world = static_cast<unsigned int>(sqlite3_column_int(stmt, 3));

	if (world & 0xFF000000)
	{
		world &= 0x00FFFFFF;
		world |= dlc;
	}

	if (baseID & 0xFF000000)
	{
		baseID &= 0x00FFFFFF;
		baseID |= dlc;
	}
	else
	{
		cells.erase(baseID);
		worlds[world].erase(remove_if(worlds[world].begin(), worlds[world].end(), [=](const Exterior* cell) { return cell->GetBase() == baseID; }), worlds[world].end());
	}

	cells.emplace(baseID, this);
	worlds[world].emplace_back(this);

	//All exteriors are also CELLs
	//const Record& record = Record::Lookup(baseID, "CELL");
}
NetworkID GameFactory::LookupNetworkID(unsigned int refID)
{
	NetworkID id;

	cs.StartSession();

	try
	{
		ReferenceList::iterator it;

		for (it = instances.begin(); it != instances.end() && it->first->GetReference() != refID; ++it);
		id = (it != instances.end() ? it->first->GetNetworkID() : throw VaultException("Unknown object with reference %08X", refID));
	}
	catch (...)
	{
		cs.EndSession();
		throw;
	}

	cs.EndSession();

	return id;
}
Beispiel #11
0
vector<FactoryObject> GameFactory::GetMultiple(const vector<NetworkID>& objects)
{
	vector<FactoryObject> result(objects.size());
	multimap<ReferenceList::value_type, unsigned int> sort;

	cs.StartSession();

	try
	{
		unsigned int i = 0;

		for (const auto& id : objects)
		{
			Reference* reference = Network::Manager()->GET_OBJECT_FROM_ID<Reference*>(id);

			if (!reference)
				throw VaultException("Unknown object with NetworkID %llu", id);

			// emplace
			sort.insert(make_pair(*GetShared(reference), i));

			++i;
		}
	}
	catch (...)
	{
		cs.EndSession();
		throw;
	}

	cs.EndSession();

	for (const auto& reference : sort)
		result[reference.second] = FactoryObject(reference.first.first.get(), reference.first.second);

	return result;
}
vector<FactoryObject> GameFactory::GetMultiple(const vector<NetworkID>& objects)
{
	vector<FactoryObject> result(objects.size());
	multimap<Reference*, unsigned int> sort;

	cs.StartSession();

	try
	{
		unsigned int i = 0;

		for (const NetworkID& id : objects)
		{
			Reference* reference = Network::Manager()->GET_OBJECT_FROM_ID<Reference*>(id);

			if (!reference)
				throw VaultException("Unknown object with NetworkID %lld", id);

			sort.insert(pair<Reference*, unsigned int>(reference, i));

			++i;
		}
	}
	catch (...)
	{
		cs.EndSession();
		throw;
	}

	cs.EndSession();

	for (const pair<Reference*, unsigned int>& reference : sort)
		result[reference.second] = FactoryObject(reference.first);

	return result;
}
NetworkResponse NetworkClient::ProcessEvent(unsigned char id)
{
	switch (id)
	{
		case ID_EVENT_CLIENT_ERROR:
		case ID_EVENT_INTERFACE_LOST:
			return NetworkResponse{Network::CreateResponse(
				PacketFactory::CreatePacket(ID_GAME_END, ID_REASON_ERROR),
				HIGH_PRIORITY, RELIABLE_ORDERED, CHANNEL_GAME, Game::server)
			};

		case ID_EVENT_GAME_STARTED:
			Network::ToggleDequeue(false);

			return NetworkResponse{Network::CreateResponse(
				PacketFactory::CreatePacket(ID_GAME_LOAD),
				HIGH_PRIORITY, RELIABLE_ORDERED, CHANNEL_GAME, Game::server)
			};

		case ID_EVENT_GAME_LOADED:
		{
			Network::ToggleDequeue(true);

			FactoryObject reference = GameFactory::GetObject(PLAYER_REFERENCE);
			Player* self = vaultcast<Player>(reference);

			return NetworkResponse{Network::CreateResponse(
				self->toPacket(),
				HIGH_PRIORITY, RELIABLE_ORDERED, CHANNEL_GAME, Game::server)
			};
		}

		default:
			throw VaultException("Unhandled event type %d", id);
	}
}
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 );
}
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;
}
Beispiel #16
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;
}
NetworkResponse NetworkClient::ProcessPacket(Packet* data)
{
	NetworkResponse response;
	pDefault* packet;

	switch (data->data[0])
	{
		case ID_CONNECTION_REQUEST_ACCEPTED:
		{
#ifdef VAULTMP_DEBUG
			debug->PrintFormat("Connection request accepted (%s)", true, data->systemAddress.ToString());
#endif
			response = Game::Authenticate(Bethesda::password);
			break;
		}

		case ID_DISCONNECTION_NOTIFICATION:
		{
#ifdef VAULTMP_DEBUG
			debug->PrintFormat("Connection closed (%s)", true, data->systemAddress.ToString());
#endif
			break;
		}

		case ID_INVALID_PASSWORD:
			throw VaultException("Dedicated server version mismatch.\nPlease download the most recent binaries from www.vaultmp.com");

		case ID_NO_FREE_INCOMING_CONNECTIONS:
			throw VaultException("The server is full");

		case ID_CONNECTION_ATTEMPT_FAILED:
			throw VaultException("Failed to connect to the server");

		case ID_CONNECTION_BANNED:
			throw VaultException("You are banned from the server");

		case ID_CONNECTION_LOST:
			throw VaultException("Lost connection to the server");

		case ID_UNCONNECTED_PONG:
			break;

		default:
		{
			pPacket _packet = PacketFactory::CreatePacket(data->data, data->length);
			const pDefault* packet = _packet.get();

			switch (data->data[0])
			{
				case ID_GAME_MOD:
				{
					char modfile[MAX_MOD_FILE + 1];
					ZeroMemory(modfile, sizeof(modfile));
					unsigned int crc;
					PacketFactory::Access(packet, modfile, &crc);
					Bethesda::modfiles.push_back(pair<string, unsigned int>(string(modfile), crc));
					break;
				}

				case ID_GAME_START:
				{
#ifdef VAULTMP_DEBUG
					debug->PrintFormat("We were successfully authenticated (%s)", true, data->systemAddress.ToString());
					debug->Print("Initiating vaultmp game thread...", true);
#endif
					char savegame[MAX_SAVEGAME_FILE + 1];
					ZeroMemory(savegame, sizeof(savegame));
					unsigned int crc;
					PacketFactory::Access(packet, savegame, &crc);
					Bethesda::savegame = Savegame(string(savegame), crc);

					Bethesda::Initialize();
					Game::LoadGame(Utils::FileOnly(Bethesda::savegame.first.c_str()));
					Game::LoadEnvironment();

					response = NetworkClient::ProcessEvent(ID_EVENT_GAME_STARTED);
					break;
				}

				case ID_GAME_LOAD:
				{
					Game::Startup();
					response = NetworkClient::ProcessEvent(ID_EVENT_GAME_LOADED);
					break;
				}

				case ID_GAME_END:
				{
					unsigned char reason;
					PacketFactory::Access(packet, &reason);

					switch (reason)
					{
						case ID_REASON_KICK:
							throw VaultException("You have been kicked from the server");

						case ID_REASON_BAN:
							throw VaultException("You have been banned from the server");

						case ID_REASON_ERROR:
							throw VaultException("The server encountered an internal error");

						case ID_REASON_DENIED:
							throw VaultException("Your authentication has been denied");

						case ID_REASON_NONE:
							break;
					}

					break;
				}

				case ID_GAME_MESSAGE:
				{
					char message[MAX_MESSAGE_LENGTH + 1];
					ZeroMemory(message, sizeof(message));
					PacketFactory::Access(packet, message);
					Game::net_UIMessage(message);
					break;
				}

				case ID_GAME_CHAT:
				{
					char message[MAX_CHAT_LENGTH + 1];
					ZeroMemory(message, sizeof(message));
					PacketFactory::Access(packet, message);
					Game::net_ChatMessage(message);
					break;
				}

				case ID_OBJECT_NEW:
				{
					NetworkID id = GameFactory::CreateKnownInstance(ID_OBJECT, packet);
					FactoryObject reference = GameFactory::GetObject(id);
					Game::NewObject(reference);
					break;
				}

				case ID_ITEM_NEW:
				{
					NetworkID id = GameFactory::CreateKnownInstance(ID_ITEM, packet);
					FactoryObject reference = GameFactory::GetObject(id);
					Game::NewItem(reference);
					break;
				}

				case ID_CONTAINER_NEW:
				{
					NetworkID id = GameFactory::CreateKnownInstance(ID_CONTAINER, packet);
					FactoryObject reference = GameFactory::GetObject(id);
					Game::NewContainer(reference);
					break;
				}

				case ID_ACTOR_NEW:
				{
					NetworkID id = GameFactory::CreateKnownInstance(ID_ACTOR, packet);
					FactoryObject reference = GameFactory::GetObject(id);
					Game::NewActor(reference);
					break;
				}

				case ID_PLAYER_NEW:
				{
					NetworkID id = GameFactory::CreateKnownInstance(ID_PLAYER, packet);
					FactoryObject reference = GameFactory::GetObject(id);
					Game::NewPlayer(reference);
					break;
				}

				case ID_OBJECT_REMOVE:
				{
					NetworkID id;
					PacketFactory::Access(packet, &id);
					FactoryObject reference = GameFactory::GetObject(id);
					Game::Delete(reference);
					break;
				}

				case ID_OBJECT_UPDATE:
				case ID_CONTAINER_UPDATE:
				case ID_ACTOR_UPDATE:
				case ID_PLAYER_UPDATE:
				{
					switch (data->data[1])
					{
						case ID_UPDATE_POS:
						{
							NetworkID id;
							double X, Y, Z;
							PacketFactory::Access(packet, &id, &X, &Y, &Z);
							FactoryObject reference = GameFactory::GetObject(id);
							Game::net_SetPos(reference, X, Y, Z);
							break;
						}

						case ID_UPDATE_ANGLE:
						{
							NetworkID id;
							unsigned char axis;
							double value;
							PacketFactory::Access(packet, &id, &axis, &value);
							FactoryObject reference = GameFactory::GetObject(id);
							Game::net_SetAngle(reference, axis, value);
							break;
						}

						case ID_UPDATE_CELL:
						{
							NetworkID id;
							unsigned int cell;
							PacketFactory::Access(packet, &id, &cell);
							vector<FactoryObject> reference = GameFactory::GetMultiple(vector<unsigned int> {GameFactory::LookupRefID(id), PLAYER_REFERENCE});
							Game::net_SetCell(reference, cell);
							break;
						}

						case ID_UPDATE_CONTAINER:
						{
							NetworkID id;
							ContainerDiff diff;
							PacketFactory::Access(packet, &id, &diff);
							FactoryObject reference = GameFactory::GetObject(id);
							Game::net_ContainerUpdate(reference, diff);
							break;
						}

						case ID_UPDATE_VALUE:
						{
							NetworkID id;
							bool base;
							unsigned char index;
							double value;
							PacketFactory::Access(packet, &id, &base, &index, &value);
							FactoryObject reference = GameFactory::GetObject(id);
							Game::net_SetActorValue(reference, base, index, value);
							break;
						}

						case ID_UPDATE_STATE:
						{
							NetworkID id;
							unsigned char index;
							unsigned char moving;
							bool alerted;
							bool sneaking;
							PacketFactory::Access(packet, &id, &index, &moving, &alerted, &sneaking);
							FactoryObject reference = GameFactory::GetObject(id);
							Game::net_SetActorState(reference, index, moving, alerted, sneaking);
							break;
						}

						case ID_UPDATE_DEAD:
						{
							NetworkID id;
							bool dead;
							PacketFactory::Access(packet, &id, &dead);
							FactoryObject reference = GameFactory::GetObject(id);
							Game::net_SetActorDead(reference, dead);
							break;
						}

						default:
							throw VaultException("Unhandled object update packet type %d", (int) data->data[1]);
					}

					break;
				}

				default:
					throw VaultException("Unhandled packet type %d", (int) data->data[0]);
			}
		}
	}

	return response;
}