Zum Inhalt springen
  • Dunkel
  • Hell
  • System

Actions aus C# auslösen: RunAction & RunActionById

Sobald du mehrere C#-Actions baust, willst du Logik nicht überall kopieren. Streamer.bot lässt dich aus dem Code heraus andere Actions aufrufen: einmal eine Helfer-Action bauen, von überall starten. Dafür gibt es CPH.RunAction und CPH.RunActionById.

Doku: docs.streamer.bot · RunAction und RunActionById

Die einfache Variante ruft eine Action über ihren Namen auf:

public class CPHInline {
public bool Execute() {
CPH.RunAction("Streamer.bot Docs Action");
return true;
}
}

Die Signatur ist:

public bool RunAction(string actionName, bool runImmediately = true)

Der Rückgabewert ist true, wenn die Action gefunden und gestartet wurde, sonst false. Prüf ihn, wenn der Aufruf optional ist:

if (!CPH.RunAction("Streamer.bot Docs Action")) {
CPH.LogWarn("Action nicht gefunden oder deaktiviert.");
}

Action-Namen kannst du im Editor umbenennen, die GUID bleibt stabil. Für robuste Aufrufe in produktiven Setups ist CPH.RunActionById deshalb die sicherere Wahl:

public class CPHInline {
public bool Execute() {
string actionId = "4fcc2d13-9bcf-4c18-9d91-821a15f4b6e5";
CPH.RunActionById(actionId);
return true;
}
}

Die GUID kopierst du im Streamer.bot-UI per Rechtsklick auf die Action (Copy Action Id). Die Signatur entspricht RunAction:

public bool RunActionById(string actionId, bool runImmediately = true)

Der zweite Parameter runImmediately entscheidet, wie die Ziel-Action läuft. Default ist true.

  • true (inline): Die Ziel-Action läuft als Teil der aktuellen Action, wie eine Sub-Action. Sie wird sofort im selben Thread ausgeführt, dein Code wartet, bis sie fertig ist, dann geht es weiter.
  • false (eigene Queue): Die Ziel-Action wird in ihre eigene Queue eingereiht. Dein Code läuft sofort weiter, ohne auf das Ende der Ziel-Action zu warten.
public class CPHInline {
public bool Execute() {
// Sofort, im selben Thread, dann geht es hier weiter
CPH.RunAction("[Helper] Post Stats", true);
// In eigene Queue, läuft nebenher, evtl. später
CPH.RunAction("[Helper] Post Stats", false);
return true;
}
}

Wann was? runImmediately: true (Default) ist richtig, wenn du auf das Ergebnis oder die Reihenfolge angewiesen bist, also etwa wenn die Ziel-Action ein Argument zurückschreibt, das du danach liest. runImmediately: false ist sinnvoll, wenn die Ziel-Action lange dauert (z. B. ein Sleep oder ein Netzwerk-Call) und du den auslösenden Thread nicht blockieren willst. Details zu Queues und Blockieren stehen unter Threading & Performance.

Eine aufgerufene Action sieht deine lokalen Variablen nicht. Du musst Werte vorher als Argumente setzen, dann kann die Ziel-Action sie als %arg% oder per CPH.TryGetArg lesen. Das machst du mit CPH.SetArgument vor dem Aufruf:

public class CPHInline {
public bool Execute() {
// Werte zusammenbauen
int viewers = CPH.Between(50, 200);
CPH.TryGetArg("user", out string user);
// Argumente für die Ziel-Action setzen
CPH.SetArgument("statsUser", user);
CPH.SetArgument("statsViewers", viewers);
// Helfer-Action inline starten, sie liest %statsUser% und %statsViewers%
CPH.RunAction("[Helper] Post Stats", true);
return true;
}
}

Die Helfer-Action [Helper] Post Stats greift dann auf die gesetzten Argumente zu:

public class CPHInline {
public bool Execute() {
CPH.TryGetArg("statsUser", out string user);
CPH.TryGetArg("statsViewers", out int viewers);
CPH.SendMessage($"📊 {user} hat aktuell {viewers} Zuschauer im Blick.");
return true;
}
}

So baust du eine Logik (Stats posten) genau einmal und rufst sie aus jeder beliebigen Action auf. Das ist der Kern des modularen Aufbaus: kleine, benannte Helfer-Actions wiederverwenden statt Code zu duplizieren. Mehr zum Rückgabeweg in Argumente zurückgeben.

Bei false läuft die Ziel-Action eventuell erst später, dein Code aber sofort weiter. Wenn du danach dieselben Argumente erneut setzt oder mehrere Aufrufe nebeneinander schickst, kann ein Race entstehen: Die Ziel-Action liest das Argument womöglich erst, nachdem dein Code es schon wieder verändert hat.

public class CPHInline {
public bool Execute() {
// Riskant: beide Aufrufe sind nicht inline und teilen sich denselben Argument-Namen
CPH.SetArgument("statsViewers", 100);
CPH.RunAction("[Helper] Post Stats", false);
CPH.SetArgument("statsViewers", 200); // überschreibt evtl. bevor der erste Call liest
CPH.RunAction("[Helper] Post Stats", false);
return true;
}
}

Wenn die Reihenfolge oder die exakten Argument-Werte zählen, nutze runImmediately: true. Inline-Aufrufe lesen ihre Argumente garantiert in dem Zustand, in dem du sie gesetzt hast.

  • Action-Name exakt schreiben (Groß-/Kleinschreibung): RunAction matcht den Namen genau. "[Helper] Post Stats" ist nicht dasselbe wie "[helper] post stats". Bei Tippfehlern oder umbenannten Actions gibt der Aufruf false zurück und es passiert stillschweigend nichts. Für stabile Aufrufe lieber RunActionById mit der GUID nehmen.
  • Endlosrekursion: Ruft sich eine Action direkt oder über eine Kette wieder selbst auf, hängst du dich in einer Endlosschleife auf. Besonders tückisch mit runImmediately: true, weil das inline im selben Thread passiert. Baue einen Abbruch (z. B. ein Argument oder eine Globale als Tiefenzähler) ein, bevor du rekursiv aufrufst.
  • Race auf Argumente bei false: runImmediately: false heißt, die Ziel-Action läuft evtl. später. Setzt du dazwischen dasselbe Argument neu, liest die Ziel-Action womöglich den falschen Wert. Für reihenfolgekritische Übergaben true verwenden.
  • Rückgabewert ignoriert: RunAction und RunActionById geben bool zurück. Wenn der Aufruf scheitert (Action fehlt, deaktiviert, falscher Name), merkst du das nur, wenn du den Rückgabewert prüfst und per CPH.LogWarn protokollierst.