Zum Inhalt springen
  • Dunkel
  • Hell
  • System

User-Globals: Werte pro Zuschauer speichern

Globale Variablen leben für die ganze Streamer.bot-Instanz. User-Globals binden einen Wert an einen einzelnen Zuschauer: wie oft jemand ein Duell gewonnen hat, wann er zuletzt da war, oder wie viele Punkte er in einem Spiel gesammelt hat. Das ist die Basis für jede Per-User-Mechanik, genau wie sie das bestehende !duel im Hintergrund nutzt.

In C# läuft das über zwei Methoden auf dem CPH-Objekt: SetTwitchUserVar zum Schreiben und GetTwitchUserVar zum Lesen.

Doku:

Schreiben und Lesen sehen so aus:

CPH.SetTwitchUserVar("azazelitv", "wins", 5, true);
int wins = CPH.GetTwitchUserVar<int>("azazelitv", "wins", true);

Der erste Parameter ist der User, der zweite der Name der Variable. Beim Lesen gibst du den Typ als generischen Parameter an, also GetTwitchUserVar<int> oder GetTwitchUserVar<int?> für einen nullable Wert.

ParameterBedeutung
userNameDer Zuschauer als Key. Üblich ist der userName (Login) aus den Argumenten
varNameName der Variable, OHNE % oder ~. Beispiel: wins
valueDer Wert (nur bei Set). Beliebiger Typ: int, string, bool
persistedtrue = überlebt den Streamer.bot-Restart. Für Counter und Punkte fast immer true

GetTwitchUserVar<T> liefert default(T) wenn die Variable für den User noch nicht existiert. Bei int ist das 0, bei Referenztypen und Nullable ist es null. Sichere neue User deshalb immer mit ?? 0 oder einer null-Prüfung ab.

Ein Command, der den Win-Counter eines Zuschauers um eins erhöht und das Ergebnis in den Chat schreibt. Genau dieses Muster steckt hinter dem Sieg-Zähler von !duel.

Core C# Code Execute C# Code
public class CPHInline {
public bool Execute() {
// Wer hat den Command ausgelöst?
if (!CPH.TryGetArg("userName", out string userName)) {
return false;
}
// Aktuellen Stand holen. ?? 0 fängt neue User ab,
// die noch keinen Wert haben.
int wins = CPH.GetTwitchUserVar<int?>(userName, "wins", true) ?? 0;
// Erhöhen und persistiert zurückschreiben.
wins += 1;
CPH.SetTwitchUserVar(userName, "wins", wins, true);
CPH.SendMessage($"🏆 @{userName} hat jetzt {wins} Siege.");
return true;
}
}

Wichtig ist GetTwitchUserVar<int?> mit dem Fragezeichen: so bekommst du bei einem neuen User null statt einer stillen 0, und das ?? 0 macht das explizit. Geschrieben wird wieder als reiner int, nicht als int?.

Manchmal willst du nicht einen einzelnen User, sondern alle Zuschauer, die einen bestimmten Key haben. Etwa für ein Leaderboard. Dafür gibt es GetUserGlobalsForVariable<T>. Es liefert eine Liste, in der jeder Eintrag .UserName, .UserId und .Value hat.

Das folgende Snippet baut eine Top-3-Liste der Sieger. Es ist eine Vorschau auf ein künftiges Leaderboard und nutzt dasselbe Enumerationsmuster wie !lurkers, das alle User mit gesetztem Key durchgeht.

using System.Linq;
public class CPHInline {
public bool Execute() {
var alle = CPH.GetUserGlobalsForVariable<int>("wins", true);
if (alle == null || !alle.Any()) {
CPH.SendMessage("Noch keine Siege gespeichert.");
return true;
}
var top = alle
.OrderByDescending(g => g.Value)
.Take(3)
.Select((g, i) => $"{i + 1}. {g.UserName} ({g.Value})");
CPH.SendMessage($"🥇 Top 3: {string.Join(" · ", top)}");
return true;
}
}

OrderByDescending sortiert nach dem Wert absteigend, Take(3) schneidet auf die ersten drei zu, und Select formatiert jede Zeile mit Rang. System.Linq ist standardmäßig verfügbar, du brauchst keine extra Reference.

  • SetUserVar statt SetTwitchUserVar: Die alte Methode ist deprecated. Lies und schreib immer mit den Twitch-Varianten, sonst landest du in zwei getrennten Speichern.
  • persisted vergessen: Lässt du den vierten Parameter auf false oder gibst ihn beim Restart-relevanten Set nicht als true an, ist der Counter nach dem nächsten Streamer.bot-Neustart wieder bei 0.
  • Null bei neuem User: GetTwitchUserVar<int?> liefert null für jemanden ohne gesetzten Wert. Ohne ?? 0 wirft das spätere Rechnen eine Exception. Immer absichern.
  • Key-Inkonsistenz zwischen Set und Get: Schreibst du mit "wins", liest aber mit "Wins" oder "win", findet Get nichts. Auch userName und userId nicht mischen. Bei Tippfehler-Verdacht hilft ein CPH.LogWarn($"Lese wins für {userName}") im Log.