Skip to content

Commit

Permalink
#137 hide autokilled coaches
Browse files Browse the repository at this point in the history
  • Loading branch information
drweissbrot committed Feb 4, 2024
1 parent bcecde3 commit 84691c3
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 42 deletions.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
This project does not adhere to Semantic Versioning.

## [Unreleased]
### Added
* Added `teams.hiddenPlayers` (theme `raw`) to hide autokilled coaches in Faceit matches


## [2.3.1] - 2024-01-21
Expand Down
12 changes: 12 additions & 0 deletions docs/hiding-players.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Hiding Players

You can hide specific players if you don't want them to show up at all in the HUD.
This may be useful for coaches that are misrepresented as dead players.
Please note that if you hide a real player, you will run into issues.

To hide a player, use the `teams.hiddenPlayers` option on the HUD config page at http://127.0.0.1:31982/config.
Provide either a player's SteamID64, or a player's name.
Provide one player per line.

If you use a player's name, you'll need to exactly match the name that would otherwise be displayed by the HUD.
If you've changed their name using [Player Name Overrides](https://github.com/drweissbrot/cs-hud/blob/master/docs/player-name-overrides.md), use the name that you used for the override.
24 changes: 24 additions & 0 deletions src/themes/raw/gsi/helpers/hidden-players.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { options } from '/hud/core/state.js'

export const getHiddenPlayers = () => {
const hiddenPlayerNames = new Set()
const hiddenPlayerSteam64Ids = new Set()

const opt = options['teams.hiddenPlayers']?.trim()
if (! opt?.length) return { hiddenPlayerNames, hiddenPlayerSteam64Ids }

const lines = opt.split('\n')

for (const rawLine of lines) {
const line = rawLine.trim()
if (! line?.length) continue

if (/^7656\d+$/.test(line)) {
hiddenPlayerSteam64Ids.add(line)
} else {
hiddenPlayerNames.add(line)
}
}

return { hiddenPlayerNames, hiddenPlayerSteam64Ids }
}
97 changes: 55 additions & 42 deletions src/themes/raw/gsi/parse-players.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { additionalState, gsiState, options } from '/hud/core/state.js'
import { parsePosition } from '/hud/gsi/parse-position.js'
import { grenadeOrderIndices } from '/hud/gsi/helpers/grenade-order-indices.js'
import { getPlayerNameOverrides } from '/hud/gsi/helpers/player-name-overrides.js'
import { getHiddenPlayers } from '/hud/gsi/helpers/hidden-players.js'

// a CS2 update mid-November 2023 changed observer slots to be `0` for the player with the hotkey `1`, `1` for hotkey `2`, ..., `9` for hotkey `0`
const getObserverSlot = (player, steam64Id) => {
Expand All @@ -12,50 +13,60 @@ const getObserverSlot = (player, steam64Id) => {
return rawSlot + 1
}

const parsePlayerWeapons = (player) => Object.values(player.weapons).flatMap((weapon) => {
const parsed = {
ammoClip: weapon.ammo_clip,
ammoClipMax: weapon.ammo_clip_max,
ammoReserve: weapon.ammo_reserve,
isActive: weapon.state === 'active',
isBomb: weapon.type === 'C4',
isGrenade: weapon.type === 'Grenade',
isMelee: weapon.type === 'Knife',
isPistol: weapon.type === 'Pistol',
isPrimary: ['Machine Gun', 'Rifle', 'Shotgun', 'SniperRifle', 'Submachine Gun'].includes(weapon.type),
isTaser: weapon.name === 'weapon_taser', // weapon.type is undefined for taser
name: weapon.name,
paintkit: weapon.paintkit,
state: weapon.state,
type: weapon.type,
unprefixedName: weapon.name.replace(/^weapon_/, ''),
}

if (parsed.name === 'weapon_flashbang' && parsed.ammoReserve >= 2) return [parsed, { ...parsed, isActive: false }]

return [parsed]
}).sort((a, b) => {
if (a.isGrenade && b.isGrenade) {
return grenadeOrderIndices[a.name] - grenadeOrderIndices[b.name]
}

if (a.isGrenade) return 1
if (b.isGrenade) return -1

if (a.name > b.name) return 1
if (a.name < b.name) return -1

if (a.isActive !== b.isActive) return b.isActive - a.isActive

return 0
})

// TODO if we want an `isBot` or similar: bots appear to use steam ids, starting at 76561197960265729 and counting up from there (these are real steam64Ids though, belonging to real Steam users)
export const parsePlayers = () => {
const playerNameOverrides = getPlayerNameOverrides()
const { hiddenPlayerNames, hiddenPlayerSteam64Ids } = getHiddenPlayers()

return Object.entries(gsiState.allplayers).map(([steam64Id, player]) => {
const weapons = Object.values(player.weapons).flatMap((weapon) => {
const parsed = {
ammoClip: weapon.ammo_clip,
ammoClipMax: weapon.ammo_clip_max,
ammoReserve: weapon.ammo_reserve,
isActive: weapon.state === 'active',
isBomb: weapon.type === 'C4',
isGrenade: weapon.type === 'Grenade',
isMelee: weapon.type === 'Knife',
isPistol: weapon.type === 'Pistol',
isPrimary: ['Machine Gun', 'Rifle', 'Shotgun', 'SniperRifle', 'Submachine Gun'].includes(weapon.type),
isTaser: weapon.name === 'weapon_taser', // weapon.type is undefined for taser
name: weapon.name,
paintkit: weapon.paintkit,
state: weapon.state,
type: weapon.type,
unprefixedName: weapon.name.replace(/^weapon_/, ''),
}

if (parsed.name === 'weapon_flashbang' && parsed.ammoReserve >= 2) return [parsed, { ...parsed, isActive: false }]

return [parsed]
}).sort((a, b) => {
if (a.isGrenade && b.isGrenade) {
return grenadeOrderIndices[a.name] - grenadeOrderIndices[b.name]
}

if (a.isGrenade) return 1
if (b.isGrenade) return -1

if (a.name > b.name) return 1
if (a.name < b.name) return -1

if (a.isActive !== b.isActive) return b.isActive - a.isActive

return 0
})
const players = []

for (const [steam64Id, player] of Object.entries(gsiState.allplayers)) {
if (hiddenPlayerSteam64Ids.has(steam64Id)) continue

const name = playerNameOverrides.get(steam64Id) || player.name
if (hiddenPlayerNames.has(name)) continue

const weapons = parsePlayerWeapons(player)
const grenades = []

let bomb
let knife
let primary
Expand All @@ -73,11 +84,12 @@ export const parsePlayers = () => {

const kdRatio = player.match_stats?.kills / (player.match_stats?.deaths || 1)

return {
players.push({
bomb,
grenades,
kdRatio,
knife,
name,
primary,
secondary,
steam64Id,
Expand Down Expand Up @@ -110,7 +122,6 @@ export const parsePlayers = () => {
kills: player.match_stats?.kills,
money: player.state?.money,
mvps: player.match_stats?.mvps,
name: playerNameOverrides.get(steam64Id) || player.name,
observerSlot: getObserverSlot(player, steam64Id),
position: parsePosition(player.position),
roundDamage: player.state?.round_totaldmg,
Expand All @@ -121,8 +132,10 @@ export const parsePlayers = () => {
score: player.match_stats?.score,
side: player.team === 'CT' ? 3 : 2,
team: undefined,
}
}).sort((a, b) => {
})
}

return players.sort((a, b) => {
const x = a.observerSlot === 0 ? 10 : a.observerSlot
const y = b.observerSlot === 0 ? 10 : b.observerSlot
return x - y
Expand Down
6 changes: 6 additions & 0 deletions src/themes/raw/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
"type": "text",
"section": "Teams",
"label": "List of SteamID64s and their player name for overrides; see https://github.com/drweissbrot/cs-hud/blob/master/docs/player-name-overrides.md"
},

"teams.hiddenPlayers": {
"type": "text",
"section": "Teams",
"label": "List of names or SteamID64s of players that should not be shown in the HUD (e.g. coaches); see https://github.com/drweissbrot/cs-hud/blob/master/docs/hiding-players.md"
}
}
}

0 comments on commit 84691c3

Please sign in to comment.