void SizzlingStats::SS_PlayerDisconnect( CSizzPluginContext *pPluginContext, edict_t *pEdict ) { Msg( "SS_DeletePlayer\n" ); int ent_index = SCHelpers::EntIndexFromEdict(pEdict); if (ent_index != -1) { if (m_PlayerDataManager.IsValidPlayer(ent_index)) { playerAndExtra_t data = m_PlayerDataManager.GetPlayerData(ent_index); data.m_pPlayerData->UpdateRoundStatsData(m_aPropOffsets); data.m_pPlayerData->UpdateRoundExtraData(*data.m_pExtraData); IPlayerInfo *pInfo = pPluginContext->GetPlayerInfo(ent_index); if (m_bTournamentMatchRunning) { playerWebStats_t stats; stats.m_scoreData = data.m_pPlayerData->GetRoundStatsData(); V_strncpy(stats.m_playerInfo.m_name, pInfo->GetName(), sizeof(stats.m_playerInfo.m_name)); V_strncpy(stats.m_playerInfo.m_steamid, pInfo->GetNetworkIDString(), sizeof(stats.m_playerInfo.m_steamid)); V_strncpy(stats.m_playerInfo.m_ip, pPluginContext->GetPlayerIPPortString(ent_index), sizeof(stats.m_playerInfo.m_ip)); stats.m_playerInfo.m_teamid = pInfo->GetTeamIndex(); CPlayerClassTracker *pTracker = data.m_pPlayerData->GetClassTracker(); stats.m_playerInfo.m_mostPlayedClass = pTracker->GetMostPlayedClass(); stats.m_playerInfo.m_playedClasses = pTracker->GetPlayedClasses(); m_pWebStatsHandler->EnqueuePlayerStats(stats); } } m_vecMedics.FindAndRemove(ent_index); m_PlayerDataManager.RemovePlayer(ent_index); } }
const char *CClient :: getName () { IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo( m_pPlayer ); if ( playerinfo ) return playerinfo->GetName(); return NULL; }
//--------------------------------------------------------------------------------- // Purpose: called on level start //--------------------------------------------------------------------------------- void CEmptyServerPlugin::ClientSettingsChanged( edict_t *pEdict ) { if ( playerinfomanager ) { IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo( pEdict ); const char * name = engine->GetClientConVarValue( engine->IndexOfEdict(pEdict), "name" ); if ( playerinfo && name && playerinfo->GetName() && Q_stricmp( name, playerinfo->GetName()) ) // playerinfo may be NULL if the MOD doesn't support access to player data // OR if you are accessing the player before they are fully connected { ClientPrint( pEdict, "Your name changed to \"%s\" (from \"%s\"\n", name, playerinfo->GetName() ); // this is the bad way to check this, the better option it to listen for the "player_changename" event in FireGameEvent() // this is here to give a real example of how to use the playerinfo interface } } }
//--------------------------------------------------------------------------------- // Purpose: called when a client joins a server //--------------------------------------------------------------------------------- PLUGIN_RESULT CEmptyServerPlugin::ClientConnect( bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen ) { IPlayerInfo *pPlayerInfo = playerinfomanager->GetPlayerInfo( pEntity ); if (pPlayerInfo) Msg("player: %s connected\n", pPlayerInfo->GetName() ); else Msg("ClientConnect error\n"); return PLUGIN_CONTINUE; }
void PlayerManager::OnClientSettingsChanged(edict_t *pEntity) { cell_t res; int client = engine->IndexOfEdict(pEntity); CPlayer *pPlayer = &m_Players[client]; if (!pPlayer->IsConnected()) { return; } m_clinfochanged->PushCell(engine->IndexOfEdict(pEntity)); m_clinfochanged->Execute(&res, NULL); IPlayerInfo *info = pPlayer->GetPlayerInfo(); const char *new_name = info ? info->GetName() : engine->GetClientConVarValue(client, "name"); const char *old_name = pPlayer->m_Name.c_str(); if (strcmp(old_name, new_name) != 0) { AdminId id = g_Admins.FindAdminByIdentity("name", new_name); if (id != INVALID_ADMIN_ID && pPlayer->GetAdminId() != id) { if (!CheckSetAdminName(client, pPlayer, id)) { pPlayer->Kick("Your name is reserved by SourceMod; set your password to use it."); RETURN_META(MRES_IGNORED); } } else if ((id = g_Admins.FindAdminByIdentity("name", old_name)) != INVALID_ADMIN_ID) { if (id == pPlayer->GetAdminId()) { /* This player is changing their name; force them to drop admin privileges! */ pPlayer->SetAdminId(INVALID_ADMIN_ID, false); } } pPlayer->SetName(new_name); } if (m_PassInfoVar.size() > 0) { /* Try for a password change */ const char *old_pass = pPlayer->m_LastPassword.c_str(); const char *new_pass = engine->GetClientConVarValue(client, m_PassInfoVar.c_str()); if (strcmp(old_pass, new_pass) != 0) { pPlayer->m_LastPassword.assign(new_pass); if (pPlayer->IsInGame() && pPlayer->IsAuthorized()) { /* If there is already an admin id assigned, this will just bail out. */ pPlayer->DoBasicAdminChecks(); } } } }
//--------------------------------------------------------------------------------- // Purpose: called on //--------------------------------------------------------------------------------- void CEmptyServerPlugin::ClientPutInServer( edict_t *pEntity, char const *playername ) { if( !pEntity || pEntity->IsFree() ) return; IPlayerInfo *pPlayerInfo = playerinfomanager->GetPlayerInfo( pEntity ); if (pPlayerInfo) Msg("player: %s put in server\n", pPlayerInfo->GetName() ); else Msg("ClientPutInServer error\n"); }
void SamplePlugin::Hook_ClientSettingsChanged(edict_t *pEdict) { if (playerinfomanager) { IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo(pEdict); const char *name = engine->GetClientConVarValue(IndexOfEdict(pEdict), "name"); if (playerinfo != NULL && name != NULL && strcmp(engine->GetPlayerNetworkIDString(pEdict), "BOT") != 0 && playerinfo->GetName() != NULL && strcmp(name, playerinfo->GetName()) == 0) { char msg[128]; MM_Format(msg, sizeof(msg), "Your name changed to \"%s\" (from \"%s\")\n", name, playerinfo->GetName()); engine->ClientPrintf(pEdict, msg); } } }
int __thiscall RevivedByDefib::OnRevived(CBaseEntity *pInitiator, void *deathModel) { CBaseEntity* pTarget = reinterpret_cast<CBaseEntity*>(this); cell_t client = gamehelpers->EntityToBCompatRef(pTarget); IGamePlayer* pGamePlayer = playerhelpers->GetGamePlayer(client); if(pGamePlayer) { IPlayerInfo* pInfo = pGamePlayer->GetPlayerInfo(); if(pInfo) { r_nowAlive(pInfo->GetAbsOrigin(), g_dead_players, arraysize(g_dead_players)); L4D_DEBUG_LOG("RevivedByDefib called for: %s", pInfo->GetName()); } } return (this->*(GetTrampoline()))(pInitiator, deathModel); }
void SizzlingStats::SS_TournamentMatchStarted( CSizzPluginContext *pPluginContext ) { Msg( "tournament match started\n" ); m_bTournamentMatchRunning = true; m_flMatchDuration = Plat_FloatTime(); V_strncpy(m_pHostInfo->m_hostname, pPluginContext->GetHostName(), 64); V_strncpy(m_pHostInfo->m_mapname, pPluginContext->GetMapName(), 64); V_strncpy(m_pHostInfo->m_bluname, pPluginContext->GetBluTeamName(), 32); V_strncpy(m_pHostInfo->m_redname, pPluginContext->GetRedTeamName(), 32); m_pHostInfo->m_hostip = m_refHostIP.GetInt(); V_strncpy(m_pHostInfo->m_ip, m_refIP.GetString(), 32); m_pHostInfo->m_hostport = m_refHostPort.GetInt(); m_pHostInfo->m_roundduration = m_flRoundDuration; m_pWebStatsHandler->SetHostData(*m_pHostInfo); // record demos if the cvar is non-zero if (record_demos.GetBool()) { m_STVRecorder.StartRecording(pPluginContext, m_pHostInfo->m_mapname); } CTFPlayerWrapper player; for (int i = 1; i <= MAX_PLAYERS; ++i) { if (m_PlayerDataManager.IsValidPlayer(i)) { player.SetPlayer(pPluginContext->BaseEntityFromEntIndex(i)); IPlayerInfo *pInfo = pPluginContext->GetPlayerInfo(i); playerInfo_t info; V_strncpy(info.m_name, pInfo->GetName(), sizeof(info.m_name)); V_strncpy(info.m_steamid, pInfo->GetNetworkIDString(), sizeof(info.m_steamid)); V_strncpy(info.m_ip, pPluginContext->GetPlayerIPPortString(i), sizeof(info.m_ip)); info.m_teamid = pInfo->GetTeamIndex(); info.m_mostPlayedClass = player.GetClass(); m_pWebStatsHandler->EnqueuePlayerInfo(info); } } // set the api key m_pWebStatsHandler->SetApiKey(apikey.GetString()); // send the initial match info to the web m_pWebStatsHandler->SendGameStartEvent(); }
bool SizzlingStats::SS_PlayerConnect( CSizzPluginContext *pPluginContext, edict_t *pEdict ) { Msg( "SS_InsertPlayer\n" ); int ent_index = SCHelpers::EntIndexFromEdict(pEdict); if (ent_index != -1) { IPlayerInfo *pPlayerInfo = pPluginContext->GetPlayerInfo(ent_index); if (pPlayerInfo && pPlayerInfo->IsConnected()) { CBaseEntity *pEnt = SCHelpers::EdictToBaseEntity(pEdict); m_PlayerDataManager.InsertPlayer(ent_index, pEnt); int acc_id = pPluginContext->SteamIDFromEntIndex(ent_index); SS_Msg("Stats for player #%i: '%s' will be tracked\n", acc_id, pPlayerInfo->GetName()); return true; } } return false; }
void SizzlingStats::SS_EndOfRound( CSizzPluginContext *pPluginContext ) { for (int i = 1; i <= MAX_PLAYERS; ++i) { if (m_PlayerDataManager.IsValidPlayer(i)) { playerAndExtra_t data = m_PlayerDataManager.GetPlayerData(i); data.m_pPlayerData->UpdateRoundStatsData(m_aPropOffsets); data.m_pPlayerData->UpdateRoundExtraData(*data.m_pExtraData); IPlayerInfo *pInfo = pPluginContext->GetPlayerInfo(i); if (m_bTournamentMatchRunning) { playerWebStats_t stats; stats.m_scoreData = data.m_pPlayerData->GetRoundStatsData(); V_strncpy(stats.m_playerInfo.m_name, pInfo->GetName(), sizeof(stats.m_playerInfo.m_name)); V_strncpy(stats.m_playerInfo.m_steamid, pInfo->GetNetworkIDString(), sizeof(stats.m_playerInfo.m_steamid)); V_strncpy(stats.m_playerInfo.m_ip, pPluginContext->GetPlayerIPPortString(i), sizeof(stats.m_playerInfo.m_ip)); stats.m_playerInfo.m_teamid = pInfo->GetTeamIndex(); CPlayerClassTracker *pTracker = data.m_pPlayerData->GetClassTracker(); stats.m_playerInfo.m_mostPlayedClass = pTracker->GetMostPlayedClass(); stats.m_playerInfo.m_playedClasses = pTracker->GetPlayedClasses(); m_pWebStatsHandler->EnqueuePlayerStats(stats); } if (pInfo->GetTeamIndex() > 1) { SS_DisplayStats(pPluginContext, i); } } } if (m_bTournamentMatchRunning) { m_pHostInfo->m_roundduration = m_flRoundDuration; m_pWebStatsHandler->SetHostData(*m_pHostInfo); m_pWebStatsHandler->SendStatsToWeb(); } }
void XmlReport::writeJoueur(ticpp::Element * eJoueurs, ClanMember * player) { IPlayerInfo * pInfo = player->getPlayerInfo(); PlayerScore * stats = player->getCurrentScore(); if (isValidPlayerInfo(pInfo)) // excludes SourceTv { ticpp::Element * eJoueur = new ticpp::Element("joueur"); eJoueur->SetAttribute("steamid", pInfo->GetNetworkIDString()); ticpp::Element * ePseudo = new ticpp::Element("pseudo", pInfo->GetName()); eJoueur->LinkEndChild(ePseudo); ticpp::Element * eKills = new ticpp::Element("kills", stats->kills); eJoueur->LinkEndChild(eKills); ticpp::Element * eDeaths = new ticpp::Element("deaths", stats->deaths); eJoueur->LinkEndChild(eDeaths); eJoueurs->LinkEndChild(eJoueur); } }
void SizzlingStats::SS_DisplayStats( CSizzPluginContext *pPluginContext, int ent_index ) { char pText[64] = {}; SS_PlayerData &playerData = *m_PlayerDataManager.GetPlayerData(ent_index).m_pPlayerData; int kills = playerData.GetStat(Kills); int assists = playerData.GetStat(KillAssists); int deaths = playerData.GetStat(Deaths); int damagedone = playerData.GetStat(DamageDone); int amounthealed = playerData.GetStat(HealPoints); int points = playerData.GetStat(Points); int backstabs = playerData.GetStat(Backstabs); int headshots = playerData.GetStat(Headshots); int captures = playerData.GetStat(Captures); int defenses = playerData.GetStat(Defenses); int healsrecv = playerData.GetStat(HealsReceived); int ubers = playerData.GetStat(Invulns); int drops = playerData.GetStat(UbersDropped); int medpicks = playerData.GetStat(MedPicks); IPlayerInfo *pPlayerInfo = pPluginContext->GetPlayerInfo(ent_index); CTFPlayerWrapper player(pPluginContext->BaseEntityFromEntIndex(ent_index)); V_snprintf( pText, 64, "\x04[\x05SizzlingStats\x04]\x06: \x03%s\n", pPlayerInfo->GetName() ); SS_SingleUserChatMessage(pPluginContext, ent_index, pText); memset( pText, 0, sizeof(pText) ); if ( deaths != 0 ) V_snprintf( pText, 64, "K/D: %i:%i (%.2f), Assists: %i\n", kills, deaths, (double)kills/(double)deaths, assists ); else V_snprintf( pText, 64, "K/D: %i:%i, Assists: %i\n", kills, deaths, assists ); SS_SingleUserChatMessage(pPluginContext, ent_index, pText); memset( pText, 0, sizeof(pText) ); //Msg( "class: %i\n", *((int *)(((unsigned char *)playerData.GetBaseEntity()) + m_PlayerClassOffset)) ); if ( (player.GetClass() - 5) != 0 ) // if the player isn't a medic { V_snprintf( pText, 64, "Damage Done: %i, Heals Received (not incl. buffs): %i\n", damagedone, healsrecv ); } else { V_snprintf( pText, 64, "Ubers/Kritz Used: %i, Ubers/Kritz Dropped: %i", ubers, drops ); //SS_SingleUserChatMessage( pEntity, pText ); //memset( pText, 0, size ); //V_snprintf( pText, 64, "Avg Charge Time: %i seconds", chargetime ); //SS_SingleUserChatMessage( pEntity, pText ); } SS_SingleUserChatMessage(pPluginContext, ent_index, pText); if ( amounthealed != 0 ) { memset( pText, 0, sizeof(pText) ); V_snprintf( pText, 64, "Amount Healed: %i\n", amounthealed ); SS_SingleUserChatMessage(pPluginContext, ent_index, pText); } if ( medpicks != 0 ) { memset( pText, 0, sizeof(pText) ); V_snprintf( pText, 64, "Medic Picks: %i\n", medpicks ); SS_SingleUserChatMessage(pPluginContext, ent_index, pText); } if ( (backstabs != 0) && (headshots != 0) ) { memset( pText, 0, sizeof(pText) ); V_snprintf( pText, 64, "Backstabs: %i, Headshots: %i\n", backstabs, headshots ); SS_SingleUserChatMessage(pPluginContext, ent_index, pText); } else if ( (backstabs != 0) && (headshots == 0) ) { memset( pText, 0, sizeof(pText) ); V_snprintf( pText, 64, "Backstabs: %i\n", backstabs ); SS_SingleUserChatMessage(pPluginContext, ent_index, pText); } else if ( (backstabs == 0) && (headshots != 0) ) { memset( pText, 0, sizeof(pText) ); V_snprintf( pText, 64, "Headshots: %i\n", headshots ); SS_SingleUserChatMessage(pPluginContext, ent_index, pText); } memset( pText, 0, sizeof(pText) ); V_snprintf( pText, 64, "Captures: %i, Defenses: %i\n", captures, defenses ); SS_SingleUserChatMessage(pPluginContext, ent_index, pText); memset( pText, 0, sizeof(pText) ); V_snprintf( pText, 64, "Round Score: %i\n", points ); SS_SingleUserChatMessage(pPluginContext, ent_index, pText); }
//--------------------------------------------------------------------------------- // Purpose: Check Player on connect //--------------------------------------------------------------------------------- bool ManiReservedSlot::NetworkIDValidated(player_t *player_ptr) { bool is_reserve_player = false; player_t temp_player; int allowed_players; int total_players; m_iUnaccountedPlayers--; if ((war_mode) || (!mani_reserve_slots.GetBool()) || (mani_reserve_slots_number_of_slots.GetInt() == 0)) // with the other method ( zero slots ) { // other player is kicked BEFORE return true; // NetworkIDValidated } total_players = m_iUnaccountedPlayers + GetNumberOfActivePlayers(true); // DirectLogCommand("[DEBUG] Total players on server [%i]\n", total_players); if (total_players <= (max_players - mani_reserve_slots_number_of_slots.GetInt())) { // DirectLogCommand("[DEBUG] No reserve slot action required\n"); return true; } GetIPAddressFromPlayer(player_ptr); Q_strcpy (player_ptr->steam_id, engine->GetPlayerNetworkIDString(player_ptr->entity)); IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo(player_ptr->entity); if (playerinfo && playerinfo->IsConnected()) { Q_strcpy(player_ptr->name, playerinfo->GetName()); } else { Q_strcpy(player_ptr->name,""); } if (FStrEq("BOT", player_ptr->steam_id)) return true; player_ptr->is_bot = false; if (IsPlayerInReserveList(player_ptr)) is_reserve_player = true; else if (mani_reserve_slots_include_admin.GetBool() && gpManiClient->HasAccess(player_ptr->index, ADMIN, ADMIN_BASIC_ADMIN)) is_reserve_player = true; if (mani_reserve_slots_allow_slot_fill.GetInt() != 1) { // Keep reserve slots free at all times allowed_players = max_players - mani_reserve_slots_number_of_slots.GetInt(); if (total_players > allowed_players) { if (!is_reserve_player) { DisconnectPlayer(player_ptr); return false; } temp_player.index = FindPlayerToKick(); FindPlayerByIndex(&temp_player); DisconnectPlayer(&temp_player); } } return true; }
//--------------------------------------------------------------------------------- // Purpose: Builds up a list of players that are 'kickable' //--------------------------------------------------------------------------------- void ManiReservedSlot::BuildPlayerKickList( player_t *player_ptr, int *players_on_server ) { player_t temp_player; active_player_t active_player; FreeList((void **) &active_player_list, &active_player_list_size); for (int i = 1; i <= max_players; i ++) { #if defined ( GAME_CSGO ) edict_t *pEntity = PEntityOfEntIndex(i); #else edict_t *pEntity = engine->PEntityOfEntIndex(i); #endif if( pEntity && !pEntity->IsFree()) { if ( player_ptr && ( pEntity == player_ptr->entity ) ) continue; IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo( pEntity ); if (playerinfo && playerinfo->IsConnected()) { Q_strcpy(active_player.steam_id, playerinfo->GetNetworkIDString()); if (FStrEq("BOT", active_player.steam_id)) { continue; } INetChannelInfo *nci = engine->GetPlayerNetInfo(i); if (!nci) { continue; } active_player.entity = pEntity; active_player.ping = nci->GetAvgLatency(0); const char * szCmdRate = engine->GetClientConVarValue( i, "cl_cmdrate" ); int nCmdRate = (20 > Q_atoi( szCmdRate )) ? 20 : Q_atoi(szCmdRate); active_player.ping -= (0.5f/nCmdRate) + TICKS_TO_TIME( 1.0f ); // correct latency // in GoldSrc we had a different, not fixed tickrate. so we have to adjust // Source pings by half a tick to match the old GoldSrc pings. active_player.ping -= TICKS_TO_TIME( 0.5f ); active_player.ping = active_player.ping * 1000.0f; // as msecs active_player.ping = ((5 > active_player.ping) ? 5:active_player.ping); // set bounds, dont show pings under 5 msecs active_player.time_connected = nci->GetTimeConnected(); Q_strcpy(active_player.ip_address, nci->GetAddress()); if (gpManiGameType->IsSpectatorAllowed() && playerinfo->GetTeamIndex () == gpManiGameType->GetSpectatorIndex()) { active_player.is_spectator = true; } else { active_player.is_spectator = false; } active_player.user_id = playerinfo->GetUserID(); Q_strcpy(active_player.name, playerinfo->GetName()); if ( players_on_server ) *players_on_server = *players_on_server + 1; active_player.kills = playerinfo->GetFragCount(); active_player.deaths = playerinfo->GetDeathCount(); Q_strcpy(temp_player.steam_id, active_player.steam_id); Q_strcpy(temp_player.ip_address, active_player.ip_address); Q_strcpy(temp_player.name, active_player.name); temp_player.is_bot = false; if (IsPlayerInReserveList(&temp_player)) { continue; } active_player.index = i; if (mani_reserve_slots_include_admin.GetInt() == 1 && gpManiClient->HasAccess(active_player.index, ADMIN, ADMIN_BASIC_ADMIN)) { continue; } if (gpManiClient->HasAccess(active_player.index, IMMUNITY, IMMUNITY_RESERVE)) { continue; } AddToList((void **) &active_player_list, sizeof(active_player_t), &active_player_list_size); active_player_list[active_player_list_size - 1] = active_player; } } } }
//================================================================================= // Callback for the 'webspec' protocol // Manages spectator connections & sending Initial messages to new spectators //================================================================================= int webspec_callback(struct libwebsocket_context *ctx, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { switch (reason) { case LWS_CALLBACK_ESTABLISHED: { Msg("[WS] New connection\n"); // New connection ws_spectators.AddToTail(wsi); // Send basic game info to let client set up // MapName, Server name (may remove), current team names char *buffer = (char*)malloc(MAX_BUFFER_SIZE); char *mapName = (char*) STRING(gpGlobals->mapname); ConVarRef hostNameCVar = ConVarRef("hostname"); string_t hostname; if (hostNameCVar.IsValid()) hostname = MAKE_STRING(hostNameCVar.GetString()); else hostname = MAKE_STRING("WebSpec Demo Server"); //Can't imagine when hostname would be invalid, but this is Source int length = snprintf(buffer, MAX_BUFFER_SIZE, "%c%s:%s:%s:%s", WSPacket_Init, mapName, STRING(hostname), STRING(ws_teamName[1]), STRING(ws_teamName[0])); SendPacketToOne(buffer, length, wsi); free(buffer); //Send connected players IPlayerInfo *playerInfo; for (int i=1; i<=gpGlobals->maxClients; i++) { playerInfo = playerInfoManager->GetPlayerInfo(engine->PEntityOfEntIndex(i)); if (playerInfo != NULL && playerInfo->IsConnected()) { buffer = (char *)malloc(MAX_BUFFER_SIZE); int userid = playerInfo->GetUserID(); int teamid = playerInfo->GetTeamIndex(); int health = playerInfo->GetHealth(); int maxHealth = playerInfo->GetMaxHealth(); bool alive = !playerInfo->IsDead(); string_t playerName = MAKE_STRING(playerInfo->GetName()); //Pointer magic to get TF2 class CBaseEntity *playerEntity = serverGameEnts->EdictToBaseEntity(engine->PEntityOfEntIndex(i)); int playerClass = *MakePtr(int*, playerEntity, WSOffsets::pCTFPlayer__m_iClass); float uberCharge = 0.0f; if (playerClass == TFClass_Medic) { //Way more pointer magic to get ubercharge from medigun CBaseCombatCharacter *playerCombatCharacter = CBaseEntity_MyCombatCharacterPointer(playerEntity); CBaseCombatWeapon *slot1Weapon = CBaseCombatCharacter_Weapon_GetSlot(playerCombatCharacter, 1); uberCharge = *MakePtr(float*, slot1Weapon, WSOffsets::pCWeaponMedigun__m_flChargeLevel); } int length = snprintf(buffer, MAX_BUFFER_SIZE, "%c%d:%d:%d:%d:%d:%d:0:%d:%s", 'C', userid, teamid, playerClass, health, maxHealth, alive, Round(uberCharge*100.0f), STRING(playerName)); SendPacketToOne(buffer, length, wsi); free(buffer); } } break; }