mirror of
https://github.com/ENSL/NS.git
synced 2024-11-30 16:30:57 +00:00
19b458f8bc
git-svn-id: https://unknownworlds.svn.cloudforge.com/ns1@141 67975925-1194-0748-b3d5-c16f83f1a3a1
752 lines
24 KiB
C++
752 lines
24 KiB
C++
//======== (C) Copyright 2002 Charles G. Cleveland All rights reserved. =========
|
|
//
|
|
// The copyright to the contents herein is the property of Charles G. Cleveland.
|
|
// The contents may be used and/or copied only with the written permission of
|
|
// Charles G. Cleveland, or in accordance with the terms and conditions stipulated in
|
|
// the agreement/contract under which the contents have been supplied.
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $Workfile: UPPUtil.h $
|
|
// $Date: 2002/11/12 22:39:25 $
|
|
//
|
|
//-------------------------------------------------------------------------------
|
|
// $Log: UPPUtil.h,v $
|
|
//===============================================================================
|
|
|
|
#ifdef USE_UPP
|
|
|
|
#include "build.h"
|
|
#include "dlls/extdll.h"
|
|
#include "util/STLUtil.h"
|
|
#include "mod/AvHServerUtil.h"
|
|
#include "mod/AvHSharedUtil.h"
|
|
#include "mod/AvHGamerules.h"
|
|
#include "mod/UPPUtil.h"
|
|
#include "AvHConstants.h"
|
|
|
|
// TODO:
|
|
// Move AuthGroup functionality into own logical section?
|
|
// Move NetworkIDManager class and functionality into another file?
|
|
// Add logic to clear temporary id cache intelligently to prevent dynamic ips from
|
|
// causing collisions across multiple players; this should be a very rare occurance
|
|
// even with the current code.
|
|
// Fix UPPUtil_GetDefaultAuthorization to match Auth system's default behavior.
|
|
// Add cheating death status to Auth mask?
|
|
// Resolve HL version
|
|
// Resolve Plugins
|
|
// Resolve Gamestate - gamestate key-value pairs hold the name of a variable and
|
|
// a concatentated listing of all of the values the variable has held at some point
|
|
// during the round, e.g. ("sv_cheats","0:1") if sv_cheats had been turned on partway
|
|
// through, then back off... a tracking method needs to be implemented for the
|
|
// variables, a list of variables to track needs to be finalized, and the code to
|
|
// transform a set of values into the final format needs to be written.
|
|
// Implement unauthorized team join handler
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
typedef map<string,int> AuthGroupMap; //CONSIDER: STLPort's hash map implementation instead
|
|
|
|
bool UPPUtil_GetDefaultAuthorization(void)
|
|
{
|
|
bool theDefaultAuthorization = true;
|
|
|
|
#ifdef AVH_PLAYTEST_BUILD
|
|
theDefaultAuthorization = false;
|
|
#endif
|
|
|
|
return theDefaultAuthorization;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
int UPPUtil_GetDefaultAuthMask(void)
|
|
{
|
|
return PLAYERAUTH_NONE;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
string UPPUtil_GetDefaultScoreboardIcon(void)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
map<string,int> UPPUtil_CreateAuthGroupMap(void)
|
|
{
|
|
AuthGroupMap theMap;
|
|
|
|
theMap.insert(AuthGroupMap::value_type("betaop",PLAYERAUTH_BETASERVEROP));
|
|
theMap.insert(AuthGroupMap::value_type("const",PLAYERAUTH_CONTRIBUTOR));
|
|
theMap.insert(AuthGroupMap::value_type("dev",PLAYERAUTH_DEVELOPER));
|
|
theMap.insert(AuthGroupMap::value_type("guide",PLAYERAUTH_GUIDE));
|
|
theMap.insert(AuthGroupMap::value_type("op",PLAYERAUTH_SERVEROP));
|
|
theMap.insert(AuthGroupMap::value_type("pt",PLAYERAUTH_PLAYTESTER));
|
|
theMap.insert(AuthGroupMap::value_type("vet",PLAYERAUTH_VETERAN));
|
|
|
|
return theMap;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
int UPPUtil_GetAuthMask(const StringSet inAuthGroups)
|
|
{
|
|
int theAuthMask = PLAYERAUTH_NONE;
|
|
|
|
//step 1 - convert auth groups into mask
|
|
if(!inAuthGroups.empty())
|
|
{
|
|
static AuthGroupMap theMap = UPPUtil_CreateAuthGroupMap();
|
|
AuthGroupMap::iterator theMapEntry;
|
|
|
|
StringSet::const_iterator end = inAuthGroups.end();
|
|
for(StringSet::const_iterator i = inAuthGroups.begin(); i != end; ++i)
|
|
{
|
|
theMapEntry = theMap.find(*i);
|
|
if(theMapEntry != theMap.end())
|
|
{
|
|
theAuthMask |= theMapEntry->second;
|
|
}
|
|
}
|
|
}
|
|
return theAuthMask;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void UPPUtil_ProcessProfileInfo(auto_ptr<UPP::ProfileInfo> inProfileInfo)
|
|
{
|
|
UPP::ProfileInfo* theProfileInfo = inProfileInfo.release();
|
|
|
|
UPPUtil_StoreProfileInfo(theProfileInfo);
|
|
if(UPP::getGeneratePerformanceData()) //report if we're profiling
|
|
{
|
|
AvHSUPrintDevMessage(string("UPP ProfileInfo Received for ") + theProfileInfo->getNetworkID() + "\n",true);
|
|
}
|
|
|
|
|
|
AvHPlayer* thePlayer = NULL;
|
|
FOR_ALL_ENTITIES(kAvHPlayerClassName, AvHPlayer*)
|
|
if(!theEntity->GetNetworkID().compare(theProfileInfo->getNetworkID()))
|
|
{
|
|
thePlayer = theEntity;
|
|
break;
|
|
}
|
|
END_FOR_ALL_ENTITIES(kAvHPlayerClassName)
|
|
if(thePlayer)
|
|
{
|
|
UPPUtil_InitializePlayer(thePlayer);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void UPPUtil_ProcessPerformanceData(auto_ptr<UPP::PerformanceData> data)
|
|
{
|
|
string theMessage("UPP Signal Returned: ");
|
|
theMessage += data->getSignalType() + " ";
|
|
theMessage += MakeStringFromInt(data->getTimeInQueue()) + "/";
|
|
theMessage += MakeStringFromInt(data->getTimeInProcessing()-data->getTimeInProcessingOnServer()) + "/";
|
|
theMessage += MakeStringFromInt(data->getTimeInProcessingOnServer()) + " ms; ";
|
|
theMessage += MakeStringFromInt(data->getRequestSize()) + "/";
|
|
theMessage += MakeStringFromInt(data->getResponseSize()) + " bytes; ";
|
|
theMessage += MakeStringFromInt(data->getErrorCode()) + " ";
|
|
theMessage += data->getErrorDescription() + " \n";
|
|
AvHSUPrintDevMessage(theMessage,true);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
TeamSet UPPUtil_BuildTeamInfoList(void)
|
|
{
|
|
TeamSet theTeamInfoList;
|
|
|
|
UPP::TeamInfo readyroom(TEAM_IND,"readyroom");
|
|
UPP::TeamInfo marines(TEAM_ONE,"marines");
|
|
UPP::TeamInfo aliens(TEAM_TWO,"aliens");
|
|
UPP::TeamInfo spectators(TEAM_SPECT,"spectators");
|
|
|
|
UPP::PlayerInfo player;
|
|
|
|
FOR_ALL_ENTITIES(kAvHPlayerClassName, AvHPlayer*)
|
|
player = UPPUtil_GetPlayerInfo(theEntity);
|
|
switch(player.getTeamIndex())
|
|
{
|
|
case TEAM_ONE:
|
|
marines.addPlayer(player);
|
|
break;
|
|
case TEAM_TWO:
|
|
aliens.addPlayer(player);
|
|
break;
|
|
case TEAM_IND:
|
|
readyroom.addPlayer(player);
|
|
break;
|
|
case TEAM_SPECT:
|
|
spectators.addPlayer(player);
|
|
break;
|
|
}
|
|
END_FOR_ALL_ENTITIES(kAvHPlayerClassName)
|
|
|
|
theTeamInfoList.insert(readyroom);
|
|
theTeamInfoList.insert(marines);
|
|
theTeamInfoList.insert(aliens);
|
|
theTeamInfoList.insert(spectators);
|
|
|
|
// Return them
|
|
return theTeamInfoList;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
StringMap UPPUtil_BuildServerVariableList(bool GameEndVariables)
|
|
{
|
|
StringMap theVariableList;
|
|
|
|
auto_ptr<const StringSet> varsToUse = GameEndVariables ? UPP::listGameEndVariables() : UPP::listGameStartVariables();
|
|
|
|
string theKey;
|
|
string theValue;
|
|
|
|
const char* theRawValue;
|
|
|
|
StringSet::const_iterator end = varsToUse->end();
|
|
for(StringSet::const_iterator i = varsToUse->begin(); i != end; ++i)
|
|
{
|
|
theKey.assign(*i);
|
|
theRawValue = CVAR_GET_STRING(theKey.c_str());
|
|
if(theRawValue)
|
|
{
|
|
theValue = theRawValue;
|
|
}
|
|
else
|
|
{
|
|
theValue.clear();
|
|
}
|
|
theVariableList.insert(StringMap::value_type(theKey,theValue));
|
|
}
|
|
|
|
return theVariableList;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
UPP::GameInfo UPPUtil_GetGameInfo(void)
|
|
{
|
|
string theGameType;
|
|
switch(GetGameRules()->GetMapMode())
|
|
{
|
|
case MAP_MODE_CO:
|
|
theGameType.assign("CO");
|
|
break;
|
|
case MAP_MODE_NS:
|
|
theGameType.assign("NS");
|
|
break;
|
|
}
|
|
|
|
UPP::GameInfo game(theGameType);
|
|
|
|
// Map name
|
|
string theMapName = STRING(gpGlobals->mapname);
|
|
game.setMapName(theMapName);
|
|
|
|
// Add team infos
|
|
TeamSet theTeamInfoList = UPPUtil_BuildTeamInfoList();
|
|
TeamSet::iterator end = theTeamInfoList.end();
|
|
for(TeamSet::iterator theTeamIter = theTeamInfoList.begin(); theTeamIter != end; ++theTeamIter)
|
|
{
|
|
game.addTeam(*theTeamIter);
|
|
}
|
|
|
|
StringMap theVariableValueList = UPPUtil_BuildServerVariableList(false);
|
|
StringMap::iterator SMend = theVariableValueList.end();
|
|
for(StringMap::iterator theIter = theVariableValueList.begin(); theIter != SMend; ++theIter)
|
|
{
|
|
game.addVariable(theIter->first, theIter->second);
|
|
}
|
|
|
|
return game;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
UPP::GameResultInfo UPPUtil_GetGameResultInfo(const int WinningTeam)
|
|
{
|
|
UPP::GameResultInfo result;
|
|
|
|
result.setWinningTeam(WinningTeam);
|
|
|
|
// Add team infos
|
|
TeamSet theTeamInfoList = UPPUtil_BuildTeamInfoList();
|
|
TeamSet::iterator end = theTeamInfoList.end();
|
|
for(TeamSet::iterator theTeamIter = theTeamInfoList.begin(); theTeamIter != end; ++theTeamIter)
|
|
{
|
|
result.addTeam(*theTeamIter);
|
|
}
|
|
|
|
StringMap theVariableValueList = UPPUtil_BuildServerVariableList(true);
|
|
StringMap::iterator SMend = theVariableValueList.end();
|
|
for(StringMap::iterator theIter = theVariableValueList.begin(); theIter != SMend; ++theIter)
|
|
{
|
|
result.addVariable(theIter->first, theIter->second);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
UPP::PlayerInfo UPPUtil_GetConnectingPlayerInfo(edict_t* edict, const char* name, const char* address)
|
|
{
|
|
UPP::PlayerInfo player;
|
|
|
|
player.setNetworkID(UPPUtil_GenerateNetworkID(edict,address));
|
|
player.setName(string(name));
|
|
player.setScore(0);
|
|
player.setKills(0);
|
|
player.setExperience(0.0f);
|
|
player.setDeaths(0);
|
|
player.setClass("none");
|
|
player.setTeamIndex(TEAM_IND);
|
|
|
|
return player;
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
UPP::PlayerInfo UPPUtil_GetPlayerInfo(const AvHPlayer* inPlayer)
|
|
{
|
|
UPP::PlayerInfo player;
|
|
|
|
string theName = STRING(inPlayer->pev->netname);
|
|
player.setName(theName);
|
|
player.setNetworkID(inPlayer->GetNetworkID());
|
|
|
|
player.setScore(inPlayer->GetScore());
|
|
player.setKills(inPlayer->pev->frags);
|
|
player.setExperience(inPlayer->GetExperience());
|
|
player.setDeaths(inPlayer->m_iDeaths);
|
|
|
|
switch(inPlayer->GetPlayMode())
|
|
{
|
|
case PLAYMODE_READYROOM:
|
|
player.setClass("none");
|
|
player.setTeamIndex(TEAM_IND);
|
|
break;
|
|
case PLAYMODE_OBSERVER:
|
|
player.setClass("spectator");
|
|
player.setTeamIndex(TEAM_SPECT);
|
|
break;
|
|
default:
|
|
const char* theUser3Name = AvHSHUGetClassNameFromUser3(inPlayer->GetUser3());
|
|
player.setClass(string(theUser3Name));
|
|
player.setTeamIndex(inPlayer->GetTeam());
|
|
break;
|
|
}
|
|
|
|
return player;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
UPP::ClientInfo UPPUtil_GetClientInfo(void)
|
|
{
|
|
UPP::ClientInfo client;
|
|
|
|
//Name
|
|
const char* theCStrServerName = CVAR_GET_STRING("hostname");
|
|
client.setName(theCStrServerName ? string(theCStrServerName) : "Unspecified Server Name");
|
|
|
|
//IP Address & Port
|
|
string theAddress("?.?.?.?");
|
|
int thePort = 0;
|
|
|
|
const char* theCStrServerAddress = CVAR_GET_STRING("net_address");
|
|
if(theCStrServerAddress)
|
|
{
|
|
theAddress.assign(theCStrServerAddress);
|
|
int theColonIndex = theAddress.find(':');
|
|
if(theColonIndex != string::npos)
|
|
{
|
|
thePort = MakeIntFromString(theAddress.substr(theColonIndex+1));
|
|
theAddress.resize(theColonIndex);
|
|
}
|
|
else
|
|
{
|
|
const char* theCStrPort = CVAR_GET_STRING("port");
|
|
if(theCStrPort)
|
|
{
|
|
thePort = MakeIntFromString(string(theCStrPort));
|
|
}
|
|
}
|
|
}
|
|
|
|
client.setAddress(theAddress);
|
|
client.setPort(thePort);
|
|
|
|
// TODO: Plug-ins
|
|
|
|
// Region
|
|
const char* theCStrRegion = CVAR_GET_STRING("sv_region");
|
|
client.setRegion(theCStrRegion ? MakeIntFromString(string(theCStrRegion)) : 255);
|
|
|
|
// TODO: Engine version
|
|
string theEngineVersion = "1.1.1.0"; // WON: 1.1.1.0, STEAM: 1.1.2.0
|
|
client.setEngineVersion(theEngineVersion);
|
|
|
|
// Game version
|
|
string theGameVersion = AvHSUGetGameVersionString();
|
|
client.setGameVersion(theGameVersion);
|
|
|
|
// Contact
|
|
const char* theCStrContact = CVAR_GET_STRING("sv_contact");
|
|
client.setContact(theCStrContact ? string(theCStrContact) : "");
|
|
|
|
return client;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void UPPUtil_ConnectPlayer(edict_t* inEntity, const char* inName, const char* inAddress)
|
|
{
|
|
UPP::PlayerInfo thePlayerInfo = UPPUtil_GetConnectingPlayerInfo(inEntity,inName,inAddress);
|
|
bool theResolved = UPPUtil_GetPlayerIsResolved(inEntity);
|
|
UPP::reportPlayerEntered(thePlayerInfo,theResolved);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void UPPUtil_ResetPlayer(AvHPlayer* inPlayer)
|
|
{
|
|
inPlayer->SetAuthenticationMask(UPPUtil_GetDefaultAuthMask());
|
|
inPlayer->SetAuthorized(UPPUtil_GetDefaultAuthorization());
|
|
inPlayer->SetScoreboardIconName(UPPUtil_GetDefaultScoreboardIcon());
|
|
inPlayer->EffectivePlayerClassChanged();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void UPPUtil_HandleUnauthorizedJoinTeamAttempt(AvHPlayer* inPlayer, AvHTeam inTeamNumber)
|
|
{
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void UPPUtil_InitializePlayer(CBasePlayer* inPlayer)
|
|
{
|
|
AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(inPlayer);
|
|
if(thePlayer)
|
|
{
|
|
thePlayer->SetNetworkAddress(UPPUtil_GetNetworkAddress(inPlayer->edict()));
|
|
thePlayer->SetNetworkID(UPPUtil_GetNetworkID(inPlayer->edict()));
|
|
UPPUtil_ResetPlayer(thePlayer);
|
|
if(UPP::isConnected())
|
|
{
|
|
UPP::ProfileInfo* theProfileInfo = UPPUtil_GetProfileInfo(thePlayer->GetNetworkID());
|
|
if(theProfileInfo)
|
|
{
|
|
thePlayer->SetAuthorized(theProfileInfo->getAuthorized());
|
|
thePlayer->SetAuthenticationMask(UPPUtil_GetAuthMask(theProfileInfo->getAuthGroups()));
|
|
thePlayer->SetScoreboardIconName(theProfileInfo->getIconName());
|
|
thePlayer->EffectivePlayerClassChanged();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void UPPUtil_ProcessResponses(void)
|
|
{
|
|
//process ProfileInfos
|
|
while(UPP::hasProfileInfo())
|
|
{
|
|
UPPUtil_ProcessProfileInfo(UPP::getProfileInfo());
|
|
}
|
|
|
|
//process PerformanceData
|
|
while(UPP::hasPerformanceData())
|
|
{
|
|
UPPUtil_ProcessPerformanceData(UPP::getPerformanceData());
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void UPPUtil_Disconnect(void) //actual function registered with atexit
|
|
{
|
|
UPP::disconnect();
|
|
FOR_ALL_ENTITIES(kAvHPlayerClassName, AvHPlayer*)
|
|
UPPUtil_ResetPlayer(theEntity);
|
|
END_FOR_ALL_ENTITIES(kAvHPlayerClassName)
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void UPPUtil_RegisterShutdown(void)
|
|
{
|
|
static bool registered = false;
|
|
if(!registered)
|
|
{
|
|
atexit(UPPUtil_Disconnect);
|
|
registered = true;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void UPPUtil_Connect(void)
|
|
{
|
|
UPP::setServerConnection("https://24.5.210.1/upp_server-dev/index.php","soap");
|
|
UPP::connect(UPPUtil_GetClientInfo());
|
|
UPP::requestAuthGroups();
|
|
UPP::requestVariables();
|
|
FOR_ALL_ENTITIES(kAvHPlayerClassName, AvHPlayer*)
|
|
UPP::reportPlayerEntered(UPPUtil_GetPlayerInfo(theEntity),UPPUtil_GetPlayerIsResolved(theEntity->edict()));
|
|
END_FOR_ALL_ENTITIES(kAvHPlayerClassName)
|
|
UPPUtil_RegisterShutdown();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Network ID management functions for use with UPP
|
|
// CONSIDER: this class isn't multithreading safe - do we need it to be?
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//CONSIDER: using hash_map instead
|
|
typedef map<const edict_t*,string> NetworkIDMap;
|
|
typedef map<const edict_t*,string> AddressMap; //key = edict, value = address
|
|
typedef map<string,UPP::ProfileInfo*> ProfileInfoMap;
|
|
typedef map<string,string> TemporaryIDMap; //key = address, value = id
|
|
|
|
class NetworkIDManager
|
|
{
|
|
public:
|
|
const static string STEAM_ID_PENDING;
|
|
const static string STEAM_ID_LAN;
|
|
const static string WON_ID_LAN;
|
|
const static string UNRESOLVED_PREFIX;
|
|
|
|
static NetworkIDManager* GetInstance(void);
|
|
~NetworkIDManager(void);
|
|
const string GenerateID(edict_t* inEntity, const char* inAddress);
|
|
const string RetrieveID(const edict_t* inEntity) const;
|
|
const string RetrieveAddress(const edict_t* inEntity) const;
|
|
UPP::ProfileInfo* GetProfileInfo(const string& inNetworkID) const;
|
|
void SetProfileInfo(const string& inNetworkID, UPP::ProfileInfo* info);
|
|
bool GetIsResolved(const edict_t* inEntity);
|
|
bool UpdateID(edict_t* inEntity);
|
|
bool ClearForLevelReset(void);
|
|
|
|
private:
|
|
auto_ptr<string> GenerateResolvedID(edict_t* inEntity);
|
|
NetworkIDManager(void);
|
|
NetworkIDMap mNetworkIDs;
|
|
AddressMap mAddresses;
|
|
ProfileInfoMap mProfiles;
|
|
TemporaryIDMap mUnresolvedIDs;
|
|
int mNextTempIDNumber;
|
|
};
|
|
|
|
const string NetworkIDManager::STEAM_ID_PENDING("STEAM_ID_PENDING");
|
|
const string NetworkIDManager::STEAM_ID_LAN("STEAM_ID_LAN");
|
|
const string NetworkIDManager::WON_ID_LAN("-1");
|
|
const string NetworkIDManager::UNRESOLVED_PREFIX("UNKNOWN_");
|
|
|
|
NetworkIDManager::NetworkIDManager(void) : mNextTempIDNumber(1000) {}
|
|
NetworkIDManager::~NetworkIDManager(void) {}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
NetworkIDManager* NetworkIDManager::GetInstance(void)
|
|
{
|
|
static auto_ptr<NetworkIDManager> ptr(new NetworkIDManager());
|
|
return ptr.get();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
bool NetworkIDManager::ClearForLevelReset(void)
|
|
{
|
|
this->mNetworkIDs.clear();
|
|
this->mAddresses.clear();
|
|
this->mProfiles.clear();
|
|
return true;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
auto_ptr<string> NetworkIDManager::GenerateResolvedID(edict_t* inEntity)
|
|
{
|
|
//(1) attempt to resolve it using STEAM
|
|
auto_ptr<string> theNetworkID(new string(g_engfuncs.pfnGetPlayerAuthId(inEntity)));
|
|
if(!theNetworkID->compare(STEAM_ID_PENDING) || !theNetworkID->compare(STEAM_ID_LAN))
|
|
{
|
|
//(2) attempt to resolve it using WON
|
|
theNetworkID->assign(MakeStringFromInt(g_engfuncs.pfnGetPlayerWONId(inEntity)));
|
|
if(!theNetworkID->compare(WON_ID_LAN))
|
|
{
|
|
//(3) couldn't resolve it, return NULL
|
|
theNetworkID.reset();
|
|
}
|
|
}
|
|
return theNetworkID;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
const string NetworkIDManager::GenerateID(edict_t* inEntity, const char* inAddress)
|
|
{
|
|
string theAddress(inAddress);
|
|
|
|
//(1) attempt to resolve it
|
|
auto_ptr<string> theNetworkID = this->GenerateResolvedID(inEntity);
|
|
if(theNetworkID.get() == NULL)
|
|
{
|
|
//(2) attempt to retrieve temporary id matching the address - it's probably
|
|
// a reconnection from the last map change and the same person...
|
|
TemporaryIDMap::iterator theEntry = this->mUnresolvedIDs.find(inAddress);
|
|
if(theEntry != this->mUnresolvedIDs.end())
|
|
{
|
|
theNetworkID.reset(new string(theEntry->second));
|
|
}
|
|
else
|
|
{
|
|
//(3) generate new temporary id and store in temporary id storage
|
|
string theTempID(UNRESOLVED_PREFIX + MakeStringFromInt(this->mNextTempIDNumber));
|
|
++this->mNextTempIDNumber;
|
|
this->mUnresolvedIDs.insert(TemporaryIDMap::value_type(inAddress,theTempID));
|
|
theNetworkID.reset(new string(theTempID));
|
|
}
|
|
}
|
|
this->mNetworkIDs.insert(NetworkIDMap::value_type(inEntity,*theNetworkID.get()));
|
|
this->mAddresses.insert(AddressMap::value_type(inEntity,theAddress));
|
|
return string(*theNetworkID.get());
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
const string NetworkIDManager::RetrieveID(const edict_t* inEntity) const
|
|
{
|
|
NetworkIDMap::const_iterator theEntry = this->mNetworkIDs.find(inEntity);
|
|
return theEntry->second;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
const string NetworkIDManager::RetrieveAddress(const edict_t* inEntity) const
|
|
{
|
|
AddressMap::const_iterator theEntry = this->mAddresses.find(inEntity);
|
|
return theEntry->second;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
bool NetworkIDManager::GetIsResolved(const edict_t* inEntity)
|
|
{
|
|
return this->RetrieveID(inEntity).compare(0,UNRESOLVED_PREFIX.size(),UNRESOLVED_PREFIX);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
bool NetworkIDManager::UpdateID(edict_t* inEntity)
|
|
{
|
|
auto_ptr<string> theNewID(NULL);
|
|
if(!this->GetIsResolved(inEntity))
|
|
{
|
|
theNewID = this->GenerateResolvedID(inEntity);
|
|
if(theNewID.get())
|
|
{
|
|
//remove this edict from the temporary list
|
|
AddressMap::iterator theEntry = this->mAddresses.find(inEntity);
|
|
this->mUnresolvedIDs.erase(theEntry->second);
|
|
}
|
|
}
|
|
return theNewID.get();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
UPP::ProfileInfo* NetworkIDManager::GetProfileInfo(const string& inNetworkID) const
|
|
{
|
|
UPP::ProfileInfo* theProfile = NULL;
|
|
ProfileInfoMap::const_iterator i = this->mProfiles.find(inNetworkID);
|
|
if(i != this->mProfiles.end())
|
|
{
|
|
theProfile = i->second;
|
|
}
|
|
return theProfile;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void NetworkIDManager::SetProfileInfo(const string& inNetworkID, UPP::ProfileInfo* info)
|
|
{
|
|
this->mProfiles.insert(ProfileInfoMap::value_type(inNetworkID,info));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
string UPPUtil_GenerateNetworkID(edict_t* inEntity, const char* inAddress)
|
|
{
|
|
return NetworkIDManager::GetInstance()->GenerateID(inEntity,inAddress);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
string UPPUtil_GetNetworkID(const edict_t* inEntity)
|
|
{
|
|
return NetworkIDManager::GetInstance()->RetrieveID(inEntity);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
string UPPUtil_GetNetworkAddress(const edict_t* inEntity)
|
|
{
|
|
return NetworkIDManager::GetInstance()->RetrieveAddress(inEntity);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
bool UPPUtil_GetPlayerIsResolved(edict_t* inEntity)
|
|
{
|
|
return NetworkIDManager::GetInstance()->GetIsResolved(inEntity);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
bool UPPUtil_GetPlayerIsResolved(const AvHPlayer* inPlayer)
|
|
{
|
|
return NetworkIDManager::GetInstance()->GetIsResolved(const_cast<AvHPlayer*>(inPlayer)->edict());
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
UPP::ProfileInfo* UPPUtil_GetProfileInfo(const string& inNetworkID)
|
|
{
|
|
return NetworkIDManager::GetInstance()->GetProfileInfo(inNetworkID);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
bool UPPUtil_ResolvePlayer(AvHPlayer* inPlayer)
|
|
{
|
|
bool theUpdated = NetworkIDManager::GetInstance()->UpdateID(inPlayer->edict());
|
|
if(theUpdated)
|
|
{
|
|
string theNewID = NetworkIDManager::GetInstance()->RetrieveID(inPlayer->edict());
|
|
UPP::reportPlayerChangingIDs(UPPUtil_GetPlayerInfo(inPlayer),theNewID,true);
|
|
inPlayer->SetNetworkID(theNewID);
|
|
}
|
|
return theUpdated;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void UPPUtil_StoreProfileInfo(UPP::ProfileInfo* info)
|
|
{
|
|
NetworkIDManager::GetInstance()->SetProfileInfo(info->getNetworkID(),info);
|
|
}
|
|
|
|
#endif
|