#include #include "AvHNexusServer.h" #include "AvHNexusTunnelToClient.h" #include "NetworkMeter.h" extern int g_msgNexusBytes; byte_string BASE64Decode(const string& input); Nexus::ServerInfo createServerInfo(void); //note: we place this here so that we have the possibility of giving out AvHNetworkMessages.cpp bool AvHNexus::send(entvars_t* const pev, const unsigned char* data, const unsigned int length) { if( !pev ) { return false; } MESSAGE_BEGIN( MSG_ONE, g_msgNexusBytes, NULL, pev ); for( int counter = 0; counter < length; counter++ ) { WRITE_BYTE(data[counter]); } MESSAGE_END(); return true; } bool AvHNexus::recv(entvars_t* const pev, const char* data, const unsigned int length) { string base64_message(data,length); byte_string message = BASE64Decode(base64_message); Nexus::ClientID client = OFFSET(pev); TunnelToClient::getInstance()->insertMessage(client,message); return true; } inline CBaseEntity* getEntity(const edict_t* edict) { return edict == NULL ? NULL : (CBaseEntity*)edict->pvPrivateData; } string AvHNexus::getNetworkID(const edict_t* edict) { //TODO: resolve this! return ""; } void AvHNexus::handleUnauthorizedJoinTeamAttempt(const edict_t* edict, const unsigned char team_index) { //TODO: teleport ready room player to spawn to prevent blocked doorway } void AvHNexus::performSpeedTest(void) { //TODO: check permission to do this before allowing it Nexus::testConnectionSpeed(); } void AvHNexus::processResponses(void) { //TODO: do something with the responses as we consume them! Nexus::ClientID id; while((id = Nexus::hasHandleInfo()) != 0) { Nexus::getHandleInfo(id); } while((id = Nexus::hasHistoryInfo()) != 0) { Nexus::getHistoryInfo(id); } while(Nexus::hasErrorReport()) { Nexus::getErrorReport(); } while(Nexus::hasPerformanceData()) { Nexus::getPerformanceData(); } } void AvHNexus::setGeneratePerformanceData(const edict_t* edict, const bool generate) { //TODO: check permission to do this before allowing it Nexus::setGeneratePerformanceData(generate); CBaseEntity* player = getEntity(edict); if(player && AvHNexus::getGeneratePerformanceData()) { UTIL_SayText("Nexus Profiling is now ON", player); } else { UTIL_SayText("Nexus Profiling is now OFF", player); } } bool AvHNexus::getGeneratePerformanceData(void) { return Nexus::getGeneratePerformanceData(); } bool AvHNexus::isRecordingGame(void) { return Nexus::isRecordingEvent(); } void AvHNexus::cancelGame(void) { Nexus::reportEventCancelled(); } void AvHNexus::finishGame(void) { Nexus::EventResultInfo info; Nexus::reportEventFinished(info); } void AvHNexus::startGame(void) { Nexus::EventInfo info; Nexus::reportEventStarted(info); } void AvHNexus::startup(void) { Nexus::setTunnelToClient(TunnelToClient::getInstance()); Nexus::setProductName("Natural Selection-temp product"); Nexus::connect(createServerInfo()); } void AvHNexus::shutdown(void) { Nexus::disconnect(); } Nexus::ServerInfo(createServerInfo()) { Nexus::ServerInfo info; info.setName( string( CVAR_GET_STRING( "hostname" ) ) ); info.setProduct( Nexus::getProductName() ); return info; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Base 64 decoder //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ byte Base64DecodeTable[256] = { 0, 0, 0, 0, 0, 0, 0, 0, // 0- 7 0, 0, 0, 0, 0, 0, 0, 0, // 8- 15 0, 0, 0, 0, 0, 0, 0, 0, // 16- 23 0, 0, 0, 0, 0, 0, 0, 0, // 24- 31 0, 0, 0, 0, 0, 0, 0, 0, // 32- 39 0, 0, 0, 62, 0, 0, 0, 63, // 40- 47 ( 43 = '+', 47 = '/') 52, 53, 54, 55, 56, 57, 58, 59, // 48- 55 ( 48- 55 = 0-7) 60, 61, 0, 0, 0, 0, 0, 0, // 56- 63 ( 56- 57 = 8-9) 0, 0, 1, 2, 3, 4, 5, 6, // 64- 71 ( 65- 71 = A-G) 7, 8, 9, 10, 11, 12, 13, 14, // 72- 79 ( 72- 79 = H-O) 15, 16, 17, 18, 19, 20, 21, 22, // 80- 87 ( 80- 87 = P-W) 23, 24, 25, 0, 0, 0, 0, 0, // 88- 95 ( 88- 90 = X-Z) 0, 26, 27, 28, 29, 30, 31, 32, // 96 003 ( 97 003 = a-g) 33, 34, 35, 36, 37, 38, 39, 40, //104 011 (104-111 = h-o) 41, 42, 43, 44, 45, 46, 47, 48, //112 019 (112-119 = p-w) 49, 50, 51, 0, 0, 0, 0, 0, //120 027 (120-122 = x-z) 0, 0, 0, 0, 0, 0, 0, 0, //128 035 0, 0, 0, 0, 0, 0, 0, 0, //136 043 0, 0, 0, 0, 0, 0, 0, 0, //144 051 0, 0, 0, 0, 0, 0, 0, 0, //152 059 0, 0, 0, 0, 0, 0, 0, 0, //160 067 0, 0, 0, 0, 0, 0, 0, 0, //168 075 0, 0, 0, 0, 0, 0, 0, 0, //176 083 0, 0, 0, 0, 0, 0, 0, 0, //184 091 0, 0, 0, 0, 0, 0, 0, 0, //192 099 0, 0, 0, 0, 0, 0, 0, 0, //200-207 0, 0, 0, 0, 0, 0, 0, 0, //208-215 0, 0, 0, 0, 0, 0, 0, 0, //216-223 0, 0, 0, 0, 0, 0, 0, 0, //224-231 0, 0, 0, 0, 0, 0, 0, 0, //232-239 0, 0, 0, 0, 0, 0, 0, 0, //240-247 0, 0, 0, 0, 0, 0, 0, 0 //248-255 }; //debugged and working properly... do not disturb. byte_string BASE64Decode(const string& input) { byte_string output; const byte* data = (const byte*)input.c_str(); size_t length = input.length(); byte value, value2; while( length > 0 ) { value = Base64DecodeTable[data[0]]; value2 = Base64DecodeTable[data[1]]; value <<= 2; value2 &= 0x30; value2 >>= 4; value |= value2; output.push_back(value); if( data[2] != '=' ) { value = Base64DecodeTable[data[1]]; value2 = Base64DecodeTable[data[2]]; value &= 0x0F; value <<= 4; value2 &= 0x3C; value2 >>= 2; value |= value2; output.push_back(value); } if( data[3] != '=' ) { value = Base64DecodeTable[data[2]]; value &= 0x03; value <<= 6; value |= Base64DecodeTable[data[3]]; output.push_back(value); } data += 4; length -= 4; } return output; }