Hasan Alp Güngör

· Hasan Alp Güngör

Et overlay i Major-stil for direktesendinger i CS2 med Game State Integration

Hvordan jeg henter live kampdata ut av Counter-Strike 2 med Game State Integration, Python-serveren i midten, og hvordan jeg regner ut killfeeden som spillet ikke sender.

Når jeg så på Major-turneringer, la jeg alltid merke til overlayet i sendingen: HP, penger og våpen for hver spiller, killfeeden, bombetimeren. Jeg ville lage noe lignende til mine egne kamper.

Hente data ut av spillet

CS2 har en funksjon som heter Game State Integration (GSI). Du legger en fil i cfg-mappen til spillet, og under en kamp sender spillet dataene du ba om som JSON til adressen du har oppgitt. Min fil ber om oppdateringer hvert 0,1 sekund, sendt til en lokal server:

cfg"Manyaksisko35 GSI v1"
{
 "uri" "http://127.0.0.1:3000"
 "throttle" "0.1"
 "data"
 {
   "map"                    "1"
   "round"                  "1"
   "player_state"           "1"
   "allplayers_state"       "1"
   "allplayers_weapons"     "1"
   "allplayers_match_stats" "1"
   "phase_countdowns"       "1"
 }
}

En Python-server i midten

JSON-en spillet sender, er stor og rotete. En liten Flask-server jeg skrev i Python, tar imot den og koker den ned: stillingen, runden, bombestatus, tid igjen, og for hver spiller navn, HP, penger, hovedvåpen, granater og K/D. For å finne hovedvåpenet hopper jeg over kniven, C4-en og pistolen, og viser pistolen hvis det ikke er noe annet. Overlayet henter disse ryddige dataene fra en egen adresse.

Et overlay som ikke flimrer

Overlayet er HTML, CSS og JavaScript, og det henter fra serveren 10 ganger i sekundet. Den første versjonen min tegnet alle panelene på nytt hver gang, og det flimret på streamen. Nå oppdateres hvert felt bare når verdien faktisk endrer seg, og HP-barene glir jevnt med en CSS-transition.

Killfeeden spillet ikke sender

GSI sier ikke hvem som drepte hvem. Så ved hver oppdatering sammenligner jeg kills og deaths for hver spiller med forrige tilstand. De som har fått flere kills, er drapsmennene, og de som har fått flere deaths, er ofrene; jeg parer dem og legger dem inn i killfeeden med våpenikonet. Hver linje forsvinner etter fem sekunder.

jsplayers.forEach((p) => {
  const before = previous[p.name];
  if (before && p.kills > before.kills) killers.push(p);
  if (before && p.deaths > before.deaths) victims.push(p);
});
for (let i = 0; i < Math.max(killers.length, victims.length); i++) {
  addKillItem(killers[i], victims[i]);
}

Bombetimeren

Når bomben blir plantet, byttes rundetimeren ut med en rød bombelinje på 40 sekunder. Når noen begynner å defuse, blir linjen hvit. Spillet sier ikke hvor lang tid defusen tar, så jeg ser på tiden som er igjen: under 5,5 sekunder betyr at spilleren har kit, og da går linjen over 5 sekunder, ellers over 10.

Koden ligger åpent på GitHub, og jeg har også gått gjennom hvordan jeg bygde det på YouTube-kanalen min.

ProsjektsideCS2 Major HUDOverlay for spillsendinger

Flere innlegg