void MRecipientFilter::AddAllPlayers(int maxClients) { m_Recipients.RemoveAll(); int i; for ( i = 1; i <= maxClients; i++ ) { #if defined ( GAME_CSGO ) edict_t *pPlayer = PEntityOfEntIndex(i); #else edict_t *pPlayer = engine->PEntityOfEntIndex(i); #endif if ( !pPlayer || pPlayer->IsFree()) { continue; } IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo( pPlayer ); if (!playerinfo || !playerinfo->IsConnected()) { continue; } if (playerinfo->IsHLTV()) { continue; } if (strcmp(playerinfo->GetNetworkIDString(),"BOT") == 0) { continue; } m_Recipients.AddToTail(i); } }
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; }
//--------------------------------------------------------------------------------- // Purpose: called once per server frame, do recurring work here (like checking for timeouts) //--------------------------------------------------------------------------------- void WebSpecPlugin::GameFrame( bool simulating ) { if (gpGlobals->curtime - g_lastUpdateTime > WEBSPEC_UPDATE_RATE_IN_SECONDS && ws_spectators.Count() > 0) { char *buffer = (char *)malloc(MAX_BUFFER_SIZE); Vector playerOrigin; QAngle playerAngles; float playerUberCharge; int userid, health, playerClass; IPlayerInfo *playerInfo; CBaseEntity *playerEntity; int bufferLength; bufferLength = sprintf(buffer, "O"); for (int i = 1; i < gpGlobals->maxClients; i++) { playerInfo = playerInfoManager->GetPlayerInfo(engine->PEntityOfEntIndex(i)); if (playerInfo == NULL || !playerInfo->IsConnected() || playerInfo->IsDead()) continue; if (strlen(buffer) > 1) snprintf(buffer, MAX_BUFFER_SIZE, "%s|", buffer); userid = playerInfo->GetUserID(); health = playerInfo->GetHealth(); playerOrigin = playerInfo->GetAbsOrigin(); playerEntity = serverGameEnts->EdictToBaseEntity(engine->PEntityOfEntIndex(i)); playerClass = *MakePtr(int*, playerEntity, WSOffsets::pCTFPlayer__m_iClass); playerAngles = CBaseEntity_EyeAngles(playerEntity); if (playerClass == TFClass_Medic) { CBaseCombatCharacter *playerCombatCharacter = CBaseEntity_MyCombatCharacterPointer(playerEntity); CBaseCombatWeapon *slot1Weapon = CBaseCombatCharacter_Weapon_GetSlot(playerCombatCharacter, 1); playerUberCharge = *MakePtr(float*, slot1Weapon, WSOffsets::pCWeaponMedigun__m_flChargeLevel); } else {
//--------------------------------------------------------------------------------- // 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; }
//--------------------------------------------------------------------------------- // Purpose: Process Game Frame //--------------------------------------------------------------------------------- void ManiAutoMap::GameFrame(void) { if (war_mode || mani_automap.GetInt() == 0 || ignore_this_map || automap_list_size == 0) return; if (g_RealTime < trigger_time) return; trigger_time += 15; int players = 0; bool include_bots = mani_automap_include_bots.GetBool(); int threshold = mani_automap_player_threshold.GetInt(); // Count players for (int i = 1; i <= max_players; i++) { // Faster than FindPlayerByIndex() #if defined ( GAME_CSGO ) edict_t *pEntity = PEntityOfEntIndex(i); #else edict_t *pEntity = engine->PEntityOfEntIndex(i); #endif if(pEntity && !pEntity->IsFree() ) { IPlayerInfo *playerinfo = playerinfomanager->GetPlayerInfo( pEntity ); if (playerinfo && playerinfo->IsConnected()) { if (playerinfo->IsHLTV()) continue; if (!include_bots && strcmp(playerinfo->GetNetworkIDString(), "BOT") == 0) continue; players ++; if (players > threshold) { // Broken threshold so just ignore, but reset the timeout this->ResetTimeout(mani_automap_timer.GetInt()); return; } } } } // Need to change map if (mani_automap_set_nextmap.GetInt() != 0) { set_next_map = true; } else { set_next_map = false; } int map_choice = this->ChooseMap(); override_changelevel = 0; override_setnextmap = false; ignore_this_map = true; LogCommand (NULL, "Autochange to map %s while server idle\n", automap_list[map_choice].map_name); SetChangeLevelReason("Automap changed map"); char changelevel_command[128]; snprintf(changelevel_command, sizeof(changelevel_command), "changelevel %s\n", automap_list[map_choice].map_name); engine->ServerCommand(changelevel_command); }