Skip to content

DE UO Topic scripts runtime

Codex edited this page Oct 12, 2026 · 4 revisions

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

Skripte und Laufzeit

Home · C# · IDE · UO API · A–Z · Beispiele · Sprachen

Starten, Anhalten, Stoppen von Skripten und Prozeduren, Instanzinformationen, Ereignissen und Warten. Terminate und StopScript arbeiten auf unterschiedlichen Ausführungsebenen.

Abschnitte

Thema Befehle und Erklärungen
StartScript UO.StartScript
StopScript UO.StopScript
StopAllScripts UO.StopAllScripts
PauseResumeScript UO.PauseResumeScript
Script State UO.GetScriptState
Script List UO.GetScriptsList · UO.GetScriptsCount
Script Name UO.GetScriptName · UO.SetScriptName
Script Path UO.GetScriptPath
CallSub UO.CallSub
SubExists UO.SubExists
Events UO.SetEvent · UO.SetEventProc
Timers UO.Timer · UO.Wait
Disconnect Behaviour UO.GetPauseScriptOnDisconnectStatus · UO.SetPauseScriptOnDisconnectStatus

Alle Theme-Befehle

Skriptlebenszyklus

UO.StartScript · UO.StopScript · UO.StopAllScripts · UO.PauseResumeScript · UO.GetScriptName · UO.SetScriptName · UO.GetScriptPath · UO.GetScriptsCount · UO.GetScriptsList · UO.GetScriptState · UO.Exec · UO.Launch

Verfahren / Ereignisse

UO.CallSub · UO.SubExists · UO.FunRunning · UO.Terminate · UO.TerminateAll · UO.SetEvent · UO.SetEventProc

Timer / Waiting

UO.Wait · UO.Waiting · UO.Timer · UO.Time · UO.Date

Disconnect Verhalten

UO.GetPauseScriptOnDisconnectStatus · UO.SetPauseScriptOnDisconnectStatus

Beispiele zum Thema

Jede Befehlskarte verfügt über mehrere unabhängige Szenarien: Direktcode, Funktionen und Klassen. Nachfolgend finden Sie ausgewählte kurze Szenarien; Einschränkungen und eine vollständige Analyse sind geplant.

UO.GetScriptsList

Parameter, Ergebnis und alle Szenarien

var indices = UO.GetScriptsList();
foreach (var index in indices)
{
    UO.Print(Convert.ToString(index) + ": " + UO.GetScriptName(index));
}

UO.TerminateAll

Parameter, Ergebnis und alle Szenarien

for (int cycle = (int)(1); cycle <= 10; cycle += (int)(1))
{
    if (Truth(UO.Dead()))
    {
        UO.Print("Character is dead: stopping all C# scripts");
        UO.TerminateAll();
    }
    await Delay(250);
}

Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

Vollständige Befehlsreferenz


UO.CallSub

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.CallSub(object? subrutineName);

Startet den C#-Delegaten, der zuvor in der aktuellen Ausführung über RegisterRoutine(Name, Handler) registriert wurde. Der Aufruf gibt die Kontrolle zurück, bevor der Helfer fertig ist. Eine registrierte Aufgabe kann sich nicht selbst auferlegt werden.

Parameter

  • subrutineName ist der durch RegisterRoutine gegebene Stringname. Leerzeichen an den Rändern werden entfernt; Bei der Suche nach registrierten Namen wird die Groß-/Kleinschreibung nicht beachtet.

Rückgabewert

void – kein Ergebnis; Ein unbekannter Name CallSub verursacht einen Fehler und die erneute Ausführung eines bereits aktiven Namens wird übersprungen.

Verhalten

UO.FunRunning(name) == 0 kann auch unmittelbar nach einer Abbruchanforderung auftreten. Das bedeutet nicht, dass der vorherige Callback seinen finally-Block beendet hat. Ein weiterer CallSub oder Exec für denselben lokalen Namen wird übersprungen, bis der vorherige Worker tatsächlich beendet ist.

  • Anmeldung und Aufgaben gehören zur gleichen Ausführung. Ein anderer Charakter, ein anderes Profil oder ein nachfolgender Lauf verfügt über eine eigene Registrierung.
  • RegisterRoutine akzeptiert Action, Func<Task> oder einen Delegaten mit einem Array von Zeichenfolgenargumenten für Exec. Durch das Entfernen der Registrierung wird der Code nicht ausgeführt und weitere Suchen nach dem Namen werden verhindert.
  • Das Hauptskript muss aktiv bleiben, solange seine Helfer benötigt werden: Nach seiner Fertigstellung werden Aufgaben abgebrochen und Registrierungen und Abonnements freigegeben.
  • FunRunning ist kein Managerindex. GetScriptsList und GetScriptState beschreiben unabhängige Dateistarts; Der lokale Callback erhält keinen separaten Index.
  • Der Callback-Fehler wird bei der nächsten Prüfung an das Hauptskript übergeben. WaitAsync-, UO.Wait- und instrumentierte C#-Schleifen unterstützen Pause, Abbruch und Ereigniswarteschlangenverarbeitung.

Hochgeladene C#-Dateien

Zusätzlich zu lokalen Delegaten unterstützt der aktuelle Manager explizit geladene C#-Einträge mit einem Schlüssel wie Child.csx::Main. SubExists und FunRunning akzeptieren einen solchen Schlüssel; CallSub führt die Datei ohne Args aus und Exec("exec Child.csx::Main 'north gate' 42") übergibt Args. Der Schlüssel mit Leerzeichen ist in Anführungszeichen innerhalb von Exec eingeschlossen. Ein eindeutiger Kurzname ist akzeptabel, ein mehrdeutiger Name wählt keine zufällige Datei aus. Die örtliche Anmeldung hat Vorrang. Ein Dateistart erhält seinen eigenen Kontext und seine eigene Lebensdauer in der aktuellen Welt/im aktuellen Manager; Lokale Delegierte gehören zu der Ausführung, die sie registriert hat.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

RegisterRoutine("Hello", () => UO.Print("Hello from a routine"));
UO.CallSub("Hello");
while (UO.FunRunning("Hello") != 0) await WaitAsync(25);

1. Starten Sie den Observer und fahren Sie mit dem Main-Direktskript fort

Parameter und Ablauf:

  • WeightWatch ist der Name des folgenden Verfahrens. Main gibt 77 zurück, ohne auf drei Proben zu warten; 77 ist das Ergebnis von Main, nicht CallSub.
  • Speichern Sie das Beispiel als separate Datei, laden Sie es in IDE/manager und führen Sie Main aus, sodass die restlichen Prozeduren im Verzeichnis landen. WeightWatch/ManaWatch – hier vollständig definierte Trainingsprozeduren: drei Gewichts-/Manamessungen mit einem Intervall von UO.Wait(1000), also 1000 ms, Ausgabe nur beim Betreten der Welt. Hierbei handelt es sich nicht um eine kontinuierliche Überwachung; Eine Pause kann die Zeit verlängern. Für das Beispiel mit zwei Aufgaben muss der gleichzeitige Start von Prozeduren erlaubt sein.
var registrationWeightWatch = RegisterRoutine("WeightWatch", WeightWatch);
UO.CallSub("WeightWatch");
while (UO.FunRunning("WeightWatch") != 0) await WaitAsync(25);
return 77;

void WeightWatch()
{
    dynamic sample = 0;
    for (sample = (int)(1); sample <= 3; sample += (int)(1))
    {
        if (Truth(UO.Connected()))
        {
            UO.Print("Weight: " + Convert.ToString(UO.Weight()));
        }
        UO.Wait(1000);
    }
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Starten Sie eine aktive oder angehaltene Aufgabe nicht neu – Skriptfunktion

Parameter und Ablauf:

  • StartIfIdle prüft zuerst die Definition, dann die Aktivität. false bedeutet, dass die Anfrage nicht gesendet wurde. true bedeutet, dass nur die Anfrage CallSub gesendet wurde, keine Bestätigung des Starts oder Abschlusses.
  • Speichern Sie das Beispiel als separate Datei, laden Sie es in IDE/manager und führen Sie Main aus, sodass die restlichen Prozeduren im Verzeichnis landen. WeightWatch/ManaWatch – hier vollständig definierte Trainingsprozeduren: drei Gewichts-/Manamessungen mit einem Intervall von UO.Wait(1000), also 1000 ms, Ausgabe nur beim Betreten der Welt. Hierbei handelt es sich nicht um eine kontinuierliche Überwachung; Eine Pause kann die Zeit verlängern. Für das Beispiel mit zwei Aufgaben muss der gleichzeitige Start von Prozeduren erlaubt sein.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var registrationWeightWatch = RegisterRoutine("WeightWatch", WeightWatch);
    var launched = StartIfIdle("WeightWatch");
    while (UO.FunRunning("WeightWatch") != 0)
        await WaitAsync(25);
    return launched;
    return null;
}

dynamic StartIfIdle(dynamic name)
{
    if (!(Truth(UO.SubExists(name))))
    {
        return false;
    }

    if (Truth(UO.FunRunning(name)))
    {
        return false;
    }

    UO.CallSub(name);
    return true;
}

void WeightWatch()
{
    dynamic sample = 0;
    for (sample = (int)(1); sample <= 3; sample += (int)(1))
    {
        if (Truth(UO.Connected()))
        {
            UO.Print("Weight: " + Convert.ToString(UO.Weight()));
        }

        UO.Wait(1000);
    }
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Zwei unabhängige Beobachter – Szenarioklasse

Parameter und Ablauf:

  • Der erste CallSub startet WeightWatch, der zweite - ManaWatch. Die Läufe sind unabhängig und tauschen keine lokalen Variablen aus; Die Reihenfolge ihrer Ausgabe ist nicht garantiert.
  • Speichern Sie das Beispiel als separate Datei, laden Sie es in IDE/manager und führen Sie Main aus, sodass die restlichen Prozeduren im Verzeichnis landen. WeightWatch/ManaWatch – hier vollständig definierte Trainingsprozeduren: drei Gewichts-/Manamessungen mit einem Intervall von UO.Wait(1000), also 1000 ms, Ausgabe nur beim Betreten der Welt. Hierbei handelt es sich nicht um eine kontinuierliche Überwachung; Eine Pause kann die Zeit verlängern. Für das Beispiel mit zwei Aufgaben muss der gleichzeitige Start von Prozeduren erlaubt sein.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var registrationWeightWatch = RegisterRoutine("WeightWatch", WeightWatch);
        var registrationManaWatch = RegisterRoutine("ManaWatch", ManaWatch);
        UO.CallSub("WeightWatch");
        UO.CallSub("ManaWatch");
        while (UO.FunRunning("WeightWatch") != 0 || UO.FunRunning("ManaWatch") != 0)
            await WaitAsync(25);
        return null;
    }

    void WeightWatch()
    {
        dynamic sample = 0;
        for (sample = (int)(1); sample <= 3; sample += (int)(1))
        {
            if (Truth(UO.Connected()))
            {
                UO.Print("Weight: " + Convert.ToString(UO.Weight()));
            }

            UO.Wait(1000);
        }
    }

    void ManaWatch()
    {
        dynamic sample = 0;
        for (sample = (int)(1); sample <= 3; sample += (int)(1))
        {
            if (Truth(UO.Connected()))
            {
                UO.Print("Mana: " + Convert.ToString(UO.Mana()));
            }

            UO.Wait(1000);
        }
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
    private IDisposable RegisterRoutine(string name, Action handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Action<string[]> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<string[], Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.CallSub(subrutineName) — UO.CallSub(String)

Parameter: subrutineName (String)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "CallSub":
                string called = Convert.ToString(arguments[0]) ?? "";
                if (Exists(called)) Start(called);
                else if (events is ICSharpScriptHost host && host.HasCSharpScript(called)) host.ExecuteCSharpScript("exec \"" + called + "\"");
                else throw new ArgumentException($"Register the C# routine or load a C# script entry named '{called}' before calling it.");
                return true;

Interner Implementierungscode; kein eigenständiges Skript.

public void CallSub(string subrutineName) => bridge.Exec(subrutineName);

UO.Date

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

int UO.Date();

Liest das lokale Kalenderdatum des Computers mit der Nummer YYMMDD. Nützlich zum Benennen einer täglichen Aktivitätsreihe oder zum Erkennen von Datumsänderungen.

Parameter

Es gibt keine Parameter.

Rückgabewert

int YYMMDD: 2026-09-30 -> 260930. Es sind keine Trennzeichen oder führenden Nullen hinterlegt. Es ist keine Dauer, keine Unix-Zeit und nicht true/false.

Verhalten

  • Es gibt keine Parameter, keine Formulare mit Argumenten. Leere Klammern geben nur die Zeit an: Der Anruf wartet nicht, startet keinen Timer und sendet keine Pakete an das Spiel.
  • RealTimeSource.Jetzt lautet DateTime.Jetzt: das lokale Datum/die lokale Uhrzeit des Computers, nicht UTC, nicht die Shard-Zeit und nicht die Spieluhr. Zeitzone, Sommerzeit und manuelle Zeitumstellung beeinflussen die Ergebnisse. Jeder Anruf fängt einen anderen Moment ein.
  • Nur die letzten beiden Ziffern der Jahreszahl bleiben erhalten: Sowohl 2000-01-01 als auch 2100-01-01 ergeben 101. Verschiedene Jahrhunderte sind nicht unterschiedlich. Einzelne Rufe Date und Time können auf entgegengesetzten Seiten von Mitternacht landen.
  • Subtrahieren Sie keine Kalendercodes, um die Verzögerung zu berechnen. Verwenden Sie Timer() und zwei Markierungen eines Laufs. Die Kalenderuhr kann zurückgestellt werden.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

var result = UO.Date();
UO.Print("Date: " + Convert.ToString(result));

1. Nennen Sie die tägliche Ressourcensammlungsreihe – direktes Skript

Parameter und Ablauf:

  • Das Ergebnis des Aufrufs ohne Parameter wird einmalig gespeichert. sessionLabel ist eine Zeichenfolge wie Harvest-260930. Print zeigt nur den Namen: Die Datei wird nicht erstellt, die Ressourcensammlung startet nicht.
var dateStamp = UO.Date();
var sessionLabel = "harvest-" + Convert.ToString(dateStamp);
UO.Print(sessionLabel);

2. Serie beenden, wenn sich der lokale Tag ändert – Skriptfunktion

Parameter und Ablauf:

  • originalDate speichert das Originaldatum. Timer begrenzt die Beobachtung auf 60 Sekunden, UO.Wait(1000) prüft ungefähr einmal pro Sekunde. Die Änderung des Datums endet am Main. Das Beispiel wartet nicht endlos auf Mitternacht und behauptet nicht, dass sich der Tag auf dem Server geändert hat.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var originalDate = UO.Date();
    var started = Environment.TickCount;
    while (Truth(Environment.TickCount - started < 60.0))
    {
        if (Truth(UO.Date() != originalDate))
        {
            UO.Print("Local date changed; end this batch");
            return null;
        }

        await Delay(1000);
    }

    UO.Print("No date change observed within one minute");
    return null;
}

Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Jahr, Monat und Tag auswählen – Skriptklasse

Parameter und Ablauf:

  • MonthPart(Stempel) wird vollständig angezeigt: Division abgerundet und MOD 100 extrahiert den Monat. Tag – letzte zwei Ziffern; shortYear – unvollständiges Jahr. Für 260930 erhalten wir 26, 9, 30.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var stamp = UO.Date();
        var month = MonthPart(stamp);
        var day = stamp % 100;
        var shortYear = stamp / 10000;
        UO.Print(Convert.ToString(shortYear) + "/" + Convert.ToString(month) + "/" + Convert.ToString(day));
        return null;
    }

    dynamic MonthPart(dynamic stamp)
    {
        return stamp / 100 % 100;
    }
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.Date() — UO.Date()

Parameter: Keine Parameter.

Ergebnis: int / Integer.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

public int Date()

        {

            var now = timeSource.Now;

            return (now.Year % 100) * 10000 + now.Month * 100 + now.Day;

        }

UO.Exec

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.Exec(object? parameters);

Führt einen Textspielbefehl aus oder führt einen registrierten C#-Delegaten oder eine geladene C#-Datei aus.

Parameter

  • parameters – Befehlszeichenfolge: zum Beispiel „useskill Hiding“, „exec Worker 42“ oder „exec Child.csx::Main ‚North Gate‘ 42“. Ein Ausdruck C# wie 2+3 innerhalb einer Zeichenfolge wird nicht automatisch ausgewertet.

Rückgabewert

void: kein Ergebnis. Die Rückgabe der Kontrolle bedeutet nicht das Ende des Starts oder die Bestätigung der Spielaktion durch den Server.

Verhalten

UO.FunRunning(name) == 0 kann auch unmittelbar nach einer Abbruchanforderung auftreten. Das bedeutet nicht, dass der vorherige Callback seinen finally-Block beendet hat. Ein weiterer CallSub oder Exec für denselben lokalen Namen wird übersprungen, bis der vorherige Worker tatsächlich beendet ist.

  • Zuerst wird die lokale Registry RegisterRoutine überprüft. „Name args“, „exec Name args“ und „_exec Name args“ werden unterstützt. Der Delegat erhält string[]: Das Argument 42 bleibt die Zeichenfolge „42“ und „00123“ behält führende Nullen. Einfache oder doppelte Anführungszeichen verketten ein Argument mit Leerzeichen. '' gibt eine leere Zeichenfolge an. Ein nicht geschlossenes Angebot führt zu einem Fehler. In dieser Route wird der Backslash wörtlich beibehalten; Verwenden Sie die C#-Escape-Syntax nicht innerhalb vorab geschriebener Befehlstexte.
  • Der lokale Delegat wird asynchron ausgeführt. Um zu warten, bis der Vorgang abgeschlossen ist, verwenden Sie FunRunning und WaitAsync. Durch einen Neustart des aktiven Namens wird keine Kopie erstellt und die Pause wird nicht entfernt. Der Hilfsfehler wird am Prüfpunkt an das Hauptskript übergeben.
  • Explizit geladene Dateieinträge werden vom aktuellen Manager mit seinem eigenen Args und seiner eigenen Lebensdauer gestartet. Das bloße Akzeptieren der Startanfrage bedeutet nicht, dass die Datei nicht mehr funktioniert.
  • Regelmäßige Spielbefehle werden an den nativen Dispatcher weitergeleitet. Dort sind die Parameterverträge des entsprechenden UO-Befehls hinterlegt; Print/Msg/Say/ConsolePrint/TextPrint fassen den Rest der Zeile in Text zusammen. Für präzise C#-Typen und -Ausdrücke verwenden Sie einen direkten Aufruf wie UO.UseSkill("Hiding"). Ein unbekannter Befehl, ungültige Argumente oder Anführungszeichen können dazu führen, dass eine Ausnahme durch try/catch abgefangen wird.
  • Konsolen-Aliase: sayu → Say, closeuo → CloseHandle, CountOnGround → CountGround, clearignorelist → IgnoreReset, canceltarget → CancelTarget, cancelmove → MoveOff.

Hochgeladene C#-Dateien

Zusätzlich zu lokalen Delegaten unterstützt der aktuelle Manager explizit geladene C#-Einträge mit einem Schlüssel wie Child.csx::Main. SubExists und FunRunning akzeptieren einen solchen Schlüssel; CallSub führt die Datei ohne Args aus und Exec("exec Child.csx::Main 'north gate' 42") übergibt Args. Der Schlüssel mit Leerzeichen ist in Anführungszeichen innerhalb von Exec eingeschlossen. Ein eindeutiger Kurzname ist akzeptabel, ein mehrdeutiger Name wählt keine zufällige Datei aus. Die örtliche Anmeldung hat Vorrang. Ein Dateistart erhält seinen eigenen Kontext und seine eigene Lebensdauer in der aktuellen Welt/im aktuellen Manager; Lokale Delegierte gehören zu der Ausführung, die sie registriert hat.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

RegisterRoutine("Hello", () => UO.Print("Hello from a routine"));
UO.Exec("exec Hello");
while (UO.FunRunning("Hello") != 0) await WaitAsync(25);

1. Ausgewählte Fähigkeit verwenden – direktes Skript

Parameter und Ablauf:

  • Verstecken ist das einzige Argument für UseSkill. Beim Betreten der Welt sendet der Kunde eine Anfrage zur Nutzung der Fertigkeit; Der Erfolg des Versteckens wird vom Server bestimmt. Gleicher Vorgang durch Direktaufruf: UO.UseSkill("Hiding").
UO.Exec("useskill Hiding");

2. Übergeben Sie die Zeichenfolgenbezeichnung an die lokale Prozedur – Skriptfunktion

Parameter und Ablauf:

  • SelectSavedRoute wird unten definiert und zeichnet den Namen der ausgewählten Route auf. Die Anführungszeichen um 00123 bewahren führende Nullen. Exec führt den registrierten Delegaten asynchron aus. Die Schleife mit FunRunning und WaitAsync wartet explizit auf ihren Abschluss, dann gibt das Skript die Zeichenfolge 00123 zurück. Dies ist eine Trainingsnamenspeicherung, kein Bewegungsbefehl.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var registration = RegisterRoutine("SelectSavedRoute", (Action<string[]>)(arguments =>
    {
        if (arguments.Length == 1)
            SelectSavedRoute(arguments[0]);
    }));
    UO.Exec("SelectSavedRoute '00123'");
    while (UO.FunRunning("SelectSavedRoute") != 0)
        await WaitAsync(25);
    return UO.GetGlobal("manual", "savedRoute");
    return null;
}

void SelectSavedRoute(dynamic name)
{
    UO.SetGlobal("manual", "savedRoute", name);
}

3. Führen Sie einen separaten Beobachter aus – Skriptklasse

Parameter und Ablauf:

  • Führen Sie dieses C#-Skript aus: RegisterRoutine ordnet den Namen WeightWatch der deklarierten Funktion der aktuellen Ausführung zu. exec WeightWatch startet drei Gewichtsmessungen im Abstand von 1000 ms und wartet nicht auf deren Abschluss. Das Hauptskript bleibt aktiv, während der lokale Assistent ausgeführt wird. Der Assistent verfügt über keinen separaten Managerindex. Wenn die Aufgabe bereits angehalten ist, wird sie durch Exec erneut nicht fortgesetzt.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var registrationWeightWatch = RegisterRoutine("WeightWatch", WeightWatch);
        UO.Exec("exec WeightWatch");
        while (UO.FunRunning("WeightWatch") != 0)
            await WaitAsync(25);
        return null;
    }

    void WeightWatch()
    {
        dynamic sample = 0;
        for (sample = (int)(1); sample <= 3; sample += (int)(1))
        {
            if (Truth(UO.Connected()))
            {
                UO.Print("Weight: " + Convert.ToString(UO.Weight()));
            }

            UO.Wait(1000);
        }
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
    private IDisposable RegisterRoutine(string name, Action handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Action<string[]> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<string[], Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
}

4. Skript aus Ordner mit Leerzeichen laden – direktes Skript

Parameter und Ablauf:

  • Ersetzen Sie den Pfad durch die vorhandene C#-Datei mit Ihrer Main-Prozedur. startscript lädt die Datei und fordert Main zur Ausführung auf. Die Anführungszeichen gehören zum Textbefehl; Pfad-Backslashes bleiben erhalten. Siehe IDE für Startfehler, da Exec keine Bestätigung zurückgibt.
UO.Exec("startscript 'C:\\UO Scripts\\Gather.csx'");

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.Exec(parameters) — UO.Exec(String)

Parameter: parameters (String)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "Exec":
                var words = CommandWords(Convert.ToString(arguments[0]) ?? "");
                if (words.Length == 0) return false;
                int offset = words[0].Equals("exec", StringComparison.OrdinalIgnoreCase) || words[0].Equals("_exec", StringComparison.OrdinalIgnoreCase) ? 1 : 0;
                if (words.Length > offset && Exists(words[offset]))
                { Start(words[offset], words.Skip(offset + 1).ToArray()); return true; }
                if (words.Length > offset && events is ICSharpScriptHost scriptHost
                    && (offset == 1 || scriptHost.HasCSharpScript(words[offset])))
                {
                    string command = Convert.ToString(arguments[0]) ?? "";
                    if (words[0].Equals("_exec", StringComparison.OrdinalIgnoreCase)) command = "exec" + command.TrimStart()[5..];
                    scriptHost.ExecuteCSharpScript(command); return true;
                }
                return false;

Interner Implementierungscode; kein eigenständiges Skript.

public void Exec(string parameters)
        {
            ConsoleToken[] parts = Tokenize(parameters).ToArray();
            if (parts.Length == 0)
                return;

            string command = parts[0].Text;
            if (command.Equals("exec", StringComparison.OrdinalIgnoreCase))
            {
                if (parts.Length != 2 || string.IsNullOrWhiteSpace(parts[1].Text))
                    throw new NativeSubrutineException("Usage: exec script_function");
                bridge.Exec(parts[1].Text);
                return;
            }

            ConsoleToken[] arguments = parts.Skip(1).ToArray();
            string[] rawArguments = arguments.Select(token => token.Text).ToArray();
            if (TryHandleLegacyConsoleCommand(command, rawArguments))
                return;

            command = NormalizeConsoleAlias(command);
            if (IsRemainderTextCommand(command) && rawArguments.Length > 0)
                arguments = new[] { new ConsoleToken(string.Join(" ", rawArguments), true) };
            else if (command.Equals("ColorPrint", StringComparison.OrdinalIgnoreCase) && rawArguments.Length > 1)
                arguments = new[] { arguments[0], new ConsoleToken(string.Join(" ", rawArguments.Skip(1)), true) };
            else if (command.Equals("CharPrint", StringComparison.OrdinalIgnoreCase) && rawArguments.Length > 2)
                arguments = new[] { arguments[0], arguments[1], new ConsoleToken(string.Join(" ", rawArguments.Skip(2)), true) };

            InjectionValue[] args = arguments.Select(token => token.Quoted
                ? new InjectionValue(token.Text) : ToConsoleValue(token.Text)).ToArray();
            CallNativeSubrutine(command, args);
        }

UO.FunRunning

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

int UO.FunRunning(object? subrutineName);

Prüft, ob der registrierte C#-Callback mit dem angegebenen Namen ausgeführt wird. Ergebnis 1 ermöglicht manuelle Pause; Eine abgeschlossene oder abgebrochene Aufgabe ergibt 0.

Parameter

  • subrutineName ist der durch RegisterRoutine gegebene Stringname. Leerzeichen an den Rändern werden entfernt; Bei der Suche nach registrierten Namen wird die Groß-/Kleinschreibung nicht beachtet.

Rückgabewert

int: 1 – Bedingung ist erfüllt, 0 – nicht erfüllt. Speichern Sie das Ergebnis eines Aufrufs, wenn es für mehrere Prüfungen erforderlich ist.

Verhalten

UO.FunRunning(name) == 0 kann auch unmittelbar nach einer Abbruchanforderung auftreten. Das bedeutet nicht, dass der vorherige Callback seinen finally-Block beendet hat. Ein weiterer CallSub oder Exec für denselben lokalen Namen wird übersprungen, bis der vorherige Worker tatsächlich beendet ist.

  • Anmeldung und Aufgaben gehören zur gleichen Ausführung. Ein anderer Charakter, ein anderes Profil oder ein nachfolgender Lauf verfügt über eine eigene Registrierung.
  • RegisterRoutine akzeptiert Action, Func<Task> oder einen Delegaten mit einem Array von Zeichenfolgenargumenten für Exec. Durch das Entfernen der Registrierung wird der Code nicht ausgeführt und weitere Suchen nach dem Namen werden verhindert.
  • Das Hauptskript muss aktiv bleiben, solange seine Helfer benötigt werden: Nach seiner Fertigstellung werden Aufgaben abgebrochen und Registrierungen und Abonnements freigegeben.
  • FunRunning ist kein Managerindex. GetScriptsList und GetScriptState beschreiben unabhängige Dateistarts; Der lokale Callback erhält keinen separaten Index.
  • Der Callback-Fehler wird bei der nächsten Prüfung an das Hauptskript übergeben. WaitAsync-, UO.Wait- und instrumentierte C#-Schleifen unterstützen Pause, Abbruch und Ereigniswarteschlangenverarbeitung.

Hochgeladene C#-Dateien

Zusätzlich zu lokalen Delegaten unterstützt der aktuelle Manager explizit geladene C#-Einträge mit einem Schlüssel wie Child.csx::Main. SubExists und FunRunning akzeptieren einen solchen Schlüssel; CallSub führt die Datei ohne Args aus und Exec("exec Child.csx::Main 'north gate' 42") übergibt Args. Der Schlüssel mit Leerzeichen ist in Anführungszeichen innerhalb von Exec eingeschlossen. Ein eindeutiger Kurzname ist akzeptabel, ein mehrdeutiger Name wählt keine zufällige Datei aus. Die örtliche Anmeldung hat Vorrang. Ein Dateistart erhält seinen eigenen Kontext und seine eigene Lebensdauer in der aktuellen Welt/im aktuellen Manager; Lokale Delegierte gehören zu der Ausführung, die sie registriert hat.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

RegisterRoutine("Hello", async () => await WaitAsync(100));
UO.CallSub("Hello");
UO.Print("Running flag: " + UO.FunRunning("Hello"));
while (UO.FunRunning("Hello") != 0) await WaitAsync(25);

1. Registrierten Beobachter ohne Overlay ausführen – direktes Skript

Parameter und Ablauf:

  • Zunächst ordnet RegisterRoutine den Namen der Funktion C# zu. FunRunning prüft die Aufgabe dieser Ausführung, einschließlich der Pause. Das Hauptskript bleibt aktiv, bis das Hilfsskript abgeschlossen ist.
var registration = RegisterRoutine("WeightWatch", WatchWeight);
if (UO.FunRunning("WeightWatch") == 0) UO.CallSub("WeightWatch");
while (UO.FunRunning("WeightWatch") != 0) await WaitAsync(25);

async Task WatchWeight()
{
    for (int sample = 0; sample < 3; sample++)
    {
        UO.Print($"Weight: {UO.Weight()}");
        await WaitAsync(250);
    }
}

2. Warten Sie auf den Abschluss und lesen Sie das Ergebnis der Hintergrundarbeit – Skriptfunktion

Parameter und Ablauf:

  • Der asynchrone Delegat ändert den Shared Counter über Interlocked. Nach FunRunning=0 wird das Ergebnis bis Volatile gelesen. Dies ist ein lokaler Rückruf; es gibt keinen separaten Index GetScriptsList.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    int completed = 0;
    var registration = RegisterRoutine("Worker", async () =>
    {
        await WaitAsync(150);
        Interlocked.Exchange(ref completed, 1);
    });
    UO.CallSub("Worker");
    UO.Print($"Worker active: {UO.FunRunning("Worker") != 0}");
    while (UO.FunRunning("Worker") != 0)
        await WaitAsync(25);
    return Volatile.Read(ref completed) == 1;
    return null;
}

3. Stornieren Sie den registrierten asynchronen Helfer – Skriptklasse

Parameter und Ablauf:

  • Terminate wählt die registrierte Aufgabe der aktuellen Ausführung aus. Ich warte darauf, dass WaitAsync ihren Stornierungstoken verwendet. finally führt die Reinigung durch; Weitere Spielaktionen der abgebrochenen Aufgabe sind nicht zulässig.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        int cleanupDone = 0;
        var registration = RegisterRoutine("Worker", async () =>
        {
            try
            {
                await WaitAsync(5000);
            }
            finally
            {
                Interlocked.Exchange(ref cleanupDone, 1);
            }
        });
        UO.CallSub("Worker");
        await WaitAsync(100);
        if (UO.FunRunning("Worker") != 0)
            UO.Terminate("Worker");
        while (UO.FunRunning("Worker") != 0)
            await WaitAsync(25);
        while (Volatile.Read(ref cleanupDone) == 0)
            await WaitAsync(25);
        return true;
        return null;
    }

    private IDisposable RegisterRoutine(string name, Action handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Action<string[]> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<string[], Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.FunRunning(subrutineName) — UO.FunRunning(String)

Parameter: subrutineName (String)

Ergebnis: int / Integer.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "FunRunning":
                string runningName = Convert.ToString(arguments[0]) ?? "";
                result = IsRunning(runningName) || events is ICSharpScriptHost runningHost && runningHost.IsCSharpScriptRunning(runningName) ? 1 : 0;
                return true;

Interner Implementierungscode; kein eigenständiges Skript.

public int FunRunning(string subrutineName) => bridge.FunRunning(subrutineName) ? 1 : 0;

UO.GetPauseScriptOnDisconnectStatus

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

dynamic UO.GetPauseScriptOnDisconnectStatus();

Liest die Skriptpauseneinstellung, wenn der Manager deaktiviert ist.

Parameter

Es gibt keine Parameter.

Rückgabewert

int 1 — PauseScriptsOnDisconnect aktiviert; 0 – deaktiviert.

Verhalten

  • Liest das Manager-Flag, nicht die aktuelle Pause eines einzelnen Skripts. Der Anruf selbst wird weder pausiert noch fortgesetzt.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

object? result = UO.GetPauseScriptOnDisconnectStatus();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Leseeinstellung – Direktskript

Parameter und Ablauf:

  • Der Wert beschreibt die Managereinstellung.
var enabled = UO.GetPauseScriptOnDisconnectStatus();
UO.Print(Convert.ToString(enabled));

2. Überprüfen Sie separat die Verbindung - Skriptfunktion

Parameter und Ablauf:

  • Das Konfigurationsflag und die Verbindung werden unabhängig voneinander gelesen.
return  RunScenario();
 object? RunScenario()
{
    var pauseOnDisconnect = UO.GetPauseScriptOnDisconnectStatus();
    var online = UO.Connected();
    UO.Print(Convert.ToString(pauseOnDisconnect) + " " + Convert.ToString(online));
    return null;
}

3. Wert speichern – Skriptklasse

Parameter und Ablauf:

  • Die Variable enthält eine Momentaufnahme der Einstellung zum Zeitpunkt des Lesens.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var saved = UO.GetPauseScriptOnDisconnectStatus();
        await Delay(100);
        UO.Print(Convert.ToString(saved));
        return null;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.GetPauseScriptOnDisconnectStatus() — UO.GetPauseScriptOnDisconnectStatus()

Parameter: Keine Parameter.

Ergebnis: dynamic / Any.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "getpausescriptondisconnectstatus": return new InjectionValue(bridge.GetPauseScriptOnDisconnectStatus());

UO.GetScriptName

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

string UO.GetScriptName(object? scriptIndex);

Liest den Anzeigenamen des aktiven Laufs.

Parameter

  • scriptIndex – Obligatorisch ScriptIndex – Ganzzahl, Index von Null ab neu GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Betreffs, den Namen der Prozedur oder ID des Starts von IDE.

Rückgabewert

string: Anzeigename oder „“, wenn kein Index vorhanden ist. Der Name eines vorhandenen Starts kann auch explizit auf die leere Zeichenfolge festgelegt werden.

Verhalten

  • Berücksichtigt werden laufende und pausierte Starts; Ausgenommen sind diejenigen, die ausgefüllt wurden und bei denen eine Stornierungsanfrage eingegangen ist. Ein laufendes Skript berücksichtigt normalerweise sich selbst. Das einfache Laden der Registerkarte IDE gilt nicht als Start.
  • Indizes sind die aktuellen Positionen in der Startreihenfolge. Beim Starten/Stoppen von Skripten kann es zu Positionsverschiebungen kommen. Unterschiedliche Aufrufe bilden keinen gemeinsamen atomaren Schnappschuss; Lesen Sie die Liste vor dem nächsten Steuerbefehl erneut.
  • GetScriptsList gibt die Indizes an, GetScriptsCount die Menge, GetScriptState den Drei-Zustands-Code. Ersetzen Sie nicht das eine durch das andere und behandeln Sie kein Ergebnis ungleich Null als Wert von true.
  • ScriptIndex=0 – der erste aktuelle Start, nicht unbedingt Aufruf des Skripts. SetScriptName ändert den Anzeigenamen, ohne die Datei umzubenennen.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

var result = UO.GetScriptName(0);
UO.Print("GetScriptName: " + Convert.ToString(result));

1. Erster Aufruf und Ergebnis – direktes Drehbuch

Parameter und Ablauf:

  • Führen Sie das angegebene C#-Skript aus. Die Zahl 0 bezeichnet dort, wo sie übergeben wird, den Index; Leere Klammern bedeuten keine Argumente. Der Text Print ist nur eine Beispielnachricht.
  • ScriptIndex=0 – der erste aktuelle Start, nicht unbedingt Aufruf des Skripts. SetScriptName ändert den Anzeigenamen, ohne die Datei umzubenennen.
  • string: Anzeigename oder „“, wenn kein Index vorhanden ist. Der Name eines vorhandenen Starts kann auch explizit auf die leere Zeichenfolge festgelegt werden.
  • Obligatorisch ScriptIndex ist eine Ganzzahl, Index von Null ab dem neuen GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Elements, den Namen der Prozedur oder ID des Starts von IDE.
var index = 0;
var name = UO.GetScriptName(index);
UO.Print(name);

2. Verwendung in einer Schleife oder Bedingung – Skriptfunktion

Parameter und Ablauf:

  • Dies ist ein konkretes Beispiel für die gemeinsame Nutzung von Befehlen. Die Array-Indizierung beginnt bei Null; Bitte überprüfen Sie die Länge vor der Handhabung. UO.Wait(250) wartet dort, wo es verwendet wird, 250 Millisekunden.
  • ScriptIndex=0 – der erste aktuelle Start, nicht unbedingt Aufruf des Skripts. SetScriptName ändert den Anzeigenamen, ohne die Datei umzubenennen.
  • string: Anzeigename oder „“, wenn kein Index vorhanden ist. Der Name eines vorhandenen Starts kann auch explizit auf die leere Zeichenfolge festgelegt werden.
  • Obligatorisch ScriptIndex ist eine Ganzzahl, Index von Null ab dem neuen GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Elements, den Namen der Prozedur oder ID des Starts von IDE.
return  RunScenario();
 object? RunScenario()
{
    var indices = UO.GetScriptsList();
    foreach (var index in indices)
    {
        var name = UO.GetScriptName(index);
        UO.Print(Convert.ToString(index) + " = " + name);
    }

    return null;
}

3. Vollständige Hilfsfunktion – Skriptklasse

Parameter und Ablauf:

  • Unter Main befindet sich die gesamte Funktion. Seine Parameter und sein Ergebnis werden getrennt vom aufgerufenen API-Befehl erläutert.
  • DescribeScript prüft den Status und verkettet den Namen mit dem Pfad. Pausen zwischen Anrufen sind möglich; „fehlt“ ist der Wert unserer Funktion, nicht das Ergebnis von GetScriptName.
  • string: Anzeigename oder „“, wenn kein Index vorhanden ist. Der Name eines vorhandenen Starts kann auch explizit auf die leere Zeichenfolge festgelegt werden.
  • Obligatorisch ScriptIndex ist eine Ganzzahl, Index von Null ab dem neuen GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Elements, den Namen der Prozedur oder ID des Starts von IDE.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        UO.Print(DescribeScript(0));
        return null;
    }

    dynamic DescribeScript(dynamic index)
    {
        if (Truth(UO.GetScriptState(index) == 0))
        {
            return "missing";
        }

        return UO.GetScriptName(index) + " | " + UO.GetScriptPath(index);
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.GetScriptName(scriptIndex) — UO.GetScriptName(Any)

Parameter: scriptIndex (Any)

Ergebnis: string / String.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "getscriptname": return new InjectionValue(bridge.GetScriptName(Arg(0)));

UO.GetScriptPath

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

string UO.GetScriptPath(object? scriptIndex);

Liest den Pfad der aktiven Startquelldatei.

Parameter

  • scriptIndex – Obligatorisch ScriptIndex – Ganzzahl, Index von Null ab neu GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Betreffs, den Namen der Prozedur oder ID des Starts von IDE.

Rückgabewert

string: gespeicherter Pfad der Quelldatei oder „“, wenn kein Index vorhanden ist. Beim Ausführen der Datei ist dies normalerweise der vollständige Pfad. Der Befehl oder die Quelle verfügt möglicherweise nicht über eine reguläre Datei im Speicher.

Verhalten

  • Berücksichtigt werden laufende und pausierte Starts; Ausgenommen sind diejenigen, die ausgefüllt wurden und bei denen eine Stornierungsanfrage eingegangen ist. Ein laufendes Skript berücksichtigt normalerweise sich selbst. Das einfache Laden der Registerkarte IDE gilt nicht als Start.
  • Indizes sind die aktuellen Positionen in der Startreihenfolge. Beim Starten/Stoppen von Skripten kann es zu Positionsverschiebungen kommen. Unterschiedliche Aufrufe bilden keinen gemeinsamen atomaren Schnappschuss; Lesen Sie die Liste vor dem nächsten Steuerbefehl erneut.
  • GetScriptsList gibt die Indizes an, GetScriptsCount die Menge, GetScriptState den Drei-Zustands-Code. Ersetzen Sie nicht das eine durch das andere und behandeln Sie kein Ergebnis ungleich Null als Wert von true.
  • ScriptIndex=0 wählt den ersten aktuellen Lauf aus. Das Ergebnis gibt seine Quelle an; Der Befehl öffnet, speichert oder führt diese Datei nicht aus.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

var result = UO.GetScriptPath(0);
UO.Print("GetScriptPath: " + Convert.ToString(result));

1. Erster Aufruf und Ergebnis – direktes Drehbuch

Parameter und Ablauf:

  • Führen Sie das angegebene C#-Skript aus. Die Zahl 0 bezeichnet dort, wo sie übergeben wird, den Index; Leere Klammern bedeuten keine Argumente. Der Text Print ist nur eine Beispielnachricht.
  • ScriptIndex=0 wählt den ersten aktuellen Lauf aus. Das Ergebnis gibt seine Quelle an; Der Befehl öffnet, speichert oder führt diese Datei nicht aus.
  • string: gespeicherter Pfad der Quelldatei oder „“, wenn kein Index vorhanden ist. Beim Ausführen der Datei ist dies normalerweise der vollständige Pfad. Der Befehl oder die Quelle verfügt möglicherweise nicht über eine reguläre Datei im Speicher.
  • Obligatorisch ScriptIndex ist eine Ganzzahl, Index von Null ab dem neuen GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Elements, den Namen der Prozedur oder ID des Starts von IDE.
var index = 0;
var path = UO.GetScriptPath(index);
if (Truth(path!=""))
{
    UO.Print(path);
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Verwendung in einer Schleife oder Bedingung – Skriptfunktion

Parameter und Ablauf:

  • Dies ist ein konkretes Beispiel für die gemeinsame Nutzung von Befehlen. Die Array-Indizierung beginnt bei Null; Bitte überprüfen Sie die Länge vor der Handhabung. UO.Wait(250) wartet dort, wo es verwendet wird, 250 Millisekunden.
  • ScriptIndex=0 wählt den ersten aktuellen Lauf aus. Das Ergebnis gibt seine Quelle an; Der Befehl öffnet, speichert oder führt diese Datei nicht aus.
  • string: gespeicherter Pfad der Quelldatei oder „“, wenn kein Index vorhanden ist. Beim Ausführen der Datei ist dies normalerweise der vollständige Pfad. Der Befehl oder die Quelle verfügt möglicherweise nicht über eine reguläre Datei im Speicher.
  • Obligatorisch ScriptIndex ist eine Ganzzahl, Index von Null ab dem neuen GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Elements, den Namen der Prozedur oder ID des Starts von IDE.
return  RunScenario();
 object? RunScenario()
{
    var indices = UO.GetScriptsList();
    foreach (var index in indices)
    {
        UO.Print(UO.GetScriptName(index) + " -> " + UO.GetScriptPath(index));
    }

    return null;
}

3. Vollständige Hilfsfunktion – Skriptklasse

Parameter und Ablauf:

  • Unter Main befindet sich die gesamte Funktion. Seine Parameter und sein Ergebnis werden getrennt vom aufgerufenen API-Befehl erläutert.
  • ReadScriptPath ersetzt den Fallback-Parameter nur, wenn der Pfad leer ist. Dies ist eine separate Funktion und keine neue GetScriptPath-Überladung.
  • string: gespeicherter Pfad der Quelldatei oder „“, wenn kein Index vorhanden ist. Beim Ausführen der Datei ist dies normalerweise der vollständige Pfad. Der Befehl oder die Quelle verfügt möglicherweise nicht über eine reguläre Datei im Speicher.
  • Obligatorisch ScriptIndex ist eine Ganzzahl, Index von Null ab dem neuen GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Elements, den Namen der Prozedur oder ID des Starts von IDE.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        UO.Print(ReadScriptPath(0, "path unavailable"));
        return null;
    }

    dynamic ReadScriptPath(dynamic index, dynamic fallback)
    {
        var path = UO.GetScriptPath(index);
        if (Truth(path == ""))
        {
            return fallback;
        }

        return path;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.GetScriptPath(scriptIndex) — UO.GetScriptPath(Any)

Parameter: scriptIndex (Any)

Ergebnis: string / String.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "getscriptpath": return new InjectionValue(bridge.GetScriptPath(Arg(0)));

UO.GetScriptState

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

int UO.GetScriptState(object? scriptIndex);

Liest den Ausführungsstatus nach Index.

Parameter

  • scriptIndex – Obligatorisch ScriptIndex – Ganzzahl, Index von Null ab neu GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Betreffs, den Namen der Prozedur oder ID des Starts von IDE.

Rückgabewert

int – Statuscode: 0 = nein/unbekannt, 1 = läuft, 2 = Pause. Dies ist nicht bool: explizit mit 1 oder 2 vergleichen.

Verhalten

  • Berücksichtigt werden laufende und pausierte Starts; Ausgenommen sind diejenigen, die ausgefüllt wurden und bei denen eine Stornierungsanfrage eingegangen ist. Ein laufendes Skript berücksichtigt normalerweise sich selbst. Das einfache Laden der Registerkarte IDE gilt nicht als Start.
  • Indizes sind die aktuellen Positionen in der Startreihenfolge. Beim Starten/Stoppen von Skripten kann es zu Positionsverschiebungen kommen. Unterschiedliche Aufrufe bilden keinen gemeinsamen atomaren Schnappschuss; Lesen Sie die Liste vor dem nächsten Steuerbefehl erneut.
  • GetScriptsList gibt die Indizes an, GetScriptsCount die Menge, GetScriptState den Drei-Zustands-Code. Ersetzen Sie nicht das eine durch das andere und behandeln Sie kein Ergebnis ungleich Null als Wert von true.
  • Dabei werden die manuelle/Debug-Pause und die konfigurierte Shutdown-Pause berücksichtigt. Der Status 1 garantiert nicht, dass das Skript derzeit CPU verbraucht oder Serverdaten empfängt.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

var result = UO.GetScriptState(0);
UO.Print("GetScriptState: " + Convert.ToString(result));

1. Erster Aufruf und Ergebnis – direktes Drehbuch

Parameter und Ablauf:

  • Führen Sie das angegebene C#-Skript aus. Die Zahl 0 bezeichnet dort, wo sie übergeben wird, den Index; Leere Klammern bedeuten keine Argumente. Der Text Print ist nur eine Beispielnachricht.
  • Dabei werden die manuelle/Debug-Pause und die konfigurierte Shutdown-Pause berücksichtigt. Der Status 1 garantiert nicht, dass das Skript derzeit CPU verbraucht oder Serverdaten empfängt.
  • int – Statuscode: 0 = nein/unbekannt, 1 = läuft, 2 = Pause. Dies ist nicht bool: explizit mit 1 oder 2 vergleichen.
  • Obligatorisch ScriptIndex ist eine Ganzzahl, Index von Null ab dem neuen GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Elements, den Namen der Prozedur oder ID des Starts von IDE.
int state = UO.GetScriptState(0);
string text = state switch
{
    1 => "running",
    2 => "paused",
    _ => "unknown"
};
UO.Print(text);

2. Verwendung in einer Schleife oder Bedingung – Skriptfunktion

Parameter und Ablauf:

  • Dies ist ein konkretes Beispiel für die gemeinsame Nutzung von Befehlen. Die Array-Indizierung beginnt bei Null; Bitte überprüfen Sie die Länge vor der Handhabung. UO.Wait(250) wartet dort, wo es verwendet wird, 250 Millisekunden.
  • Dabei werden die manuelle/Debug-Pause und die konfigurierte Shutdown-Pause berücksichtigt. Der Status 1 garantiert nicht, dass das Skript derzeit CPU verbraucht oder Serverdaten empfängt.
  • int – Statuscode: 0 = nein/unbekannt, 1 = läuft, 2 = Pause. Dies ist nicht bool: explizit mit 1 oder 2 vergleichen.
  • Obligatorisch ScriptIndex ist eine Ganzzahl, Index von Null ab dem neuen GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Elements, den Namen der Prozedur oder ID des Starts von IDE.
return  RunScenario();
 object? RunScenario()
{
    var paused = 0;
    var indices = UO.GetScriptsList();
    foreach (var index in indices)
    {
        if (Truth(UO.GetScriptState(index) == 2))
        {
            paused += 1;
        }
    }

    UO.Print(Convert.ToString(paused));
    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Vollständige Hilfsfunktion – Skriptklasse

Parameter und Ablauf:

  • Unter Main befindet sich die gesamte Funktion. Seine Parameter und sein Ergebnis werden getrennt vom aufgerufenen API-Befehl erläutert.
  • IsScriptActive wandelt 1 und 2 in true und 0 in false um. GetScriptState selbst gibt weiterhin einen numerischen Statuscode zurück.
  • int – Statuscode: 0 = nein/unbekannt, 1 = läuft, 2 = Pause. Dies ist nicht bool: explizit mit 1 oder 2 vergleichen.
  • Obligatorisch ScriptIndex ist eine Ganzzahl, Index von Null ab dem neuen GetScriptsList. Bei einem negativen oder fehlenden Index wird das beschriebene leere/unbekannte Ergebnis zurückgegeben. Übergeben Sie nicht serial des Elements, den Namen der Prozedur oder ID des Starts von IDE.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        if (Truth(Truth(IsScriptActive(0)) == true))
        {
            UO.Print("running or paused");
        }
        else
        {
            UO.Print("not active");
        }

        return null;
    }

    dynamic IsScriptActive(dynamic index)
    {
        var state = UO.GetScriptState(index);
        return Truth(state == 1) || Truth(state == 2);
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.GetScriptState(scriptIndex) — UO.GetScriptState(Any)

Parameter: scriptIndex (Any)

Ergebnis: int / Integer.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "getscriptstate": return new InjectionValue(bridge.GetScriptState(Arg(0)));

UO.GetScriptsCount

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

int UO.GetScriptsCount();

Zählt aktive Ausführungen in diesem Client.

Parameter

Es gibt keine Parameter.

Rückgabewert

int >= 0: Anzahl der aktiven Läufe, einschließlich der pausierten. Dies ist eine Menge, nicht bool oder ein Skriptindex.

Verhalten

  • Berücksichtigt werden laufende und pausierte Starts; Ausgenommen sind diejenigen, die ausgefüllt wurden und bei denen eine Stornierungsanfrage eingegangen ist. Ein laufendes Skript berücksichtigt normalerweise sich selbst. Das einfache Laden der Registerkarte IDE gilt nicht als Start.
  • Indizes sind die aktuellen Positionen in der Startreihenfolge. Beim Starten/Stoppen von Skripten kann es zu Positionsverschiebungen kommen. Unterschiedliche Aufrufe bilden keinen gemeinsamen atomaren Schnappschuss; Lesen Sie die Liste vor dem nächsten Steuerbefehl erneut.
  • GetScriptsList gibt die Indizes an, GetScriptsCount die Menge, GetScriptState den Drei-Zustands-Code. Ersetzen Sie nicht das eine durch das andere und behandeln Sie kein Ergebnis ungleich Null als Wert von true.
  • Es gibt keine Argumente. Durch das Zählen wird die Liste nicht sortiert und der Status der Läufe wird nicht geändert.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

var result = UO.GetScriptsCount();
UO.Print("GetScriptsCount: " + Convert.ToString(result));

1. Erster Aufruf und Ergebnis – direktes Drehbuch

Parameter und Ablauf:

  • Führen Sie das angegebene C#-Skript aus. Die Zahl 0 bezeichnet dort, wo sie übergeben wird, den Index; Leere Klammern bedeuten keine Argumente. Der Text Print ist nur eine Beispielnachricht.
  • Es gibt keine Argumente. Durch das Zählen wird die Liste nicht sortiert und der Status der Läufe wird nicht geändert.
  • int >= 0: Anzahl der aktiven Läufe, einschließlich der pausierten. Dies ist eine Menge, nicht bool oder ein Skriptindex.
var count = UO.GetScriptsCount();
UO.Print(Convert.ToString(count));

2. Verwendung in einer Schleife oder Bedingung – Skriptfunktion

Parameter und Ablauf:

  • Dies ist ein konkretes Beispiel für die gemeinsame Nutzung von Befehlen. Die Array-Indizierung beginnt bei Null; Bitte überprüfen Sie die Länge vor der Handhabung. UO.Wait(250) wartet dort, wo es verwendet wird, 250 Millisekunden.
  • Es gibt keine Argumente. Durch das Zählen wird die Liste nicht sortiert und der Status der Läufe wird nicht geändert.
  • int >= 0: Anzahl der aktiven Läufe, einschließlich der pausierten. Dies ist eine Menge, nicht bool oder ein Skriptindex.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var before = UO.GetScriptsCount();
    await Delay(250);
    var after = UO.GetScriptsCount();
    UO.Print(Convert.ToString(after - before));
    return null;
}

Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));

3. Vollständige Hilfsfunktion – Skriptklasse

Parameter und Ablauf:

  • Unter Main befindet sich die gesamte Funktion. Seine Parameter und sein Ergebnis werden getrennt vom aufgerufenen API-Befehl erläutert.
  • HasOtherScripts vergleicht die Zählung mit 1: Das aufrufende Skript belegt typischerweise einen Eintrag. Im Gegensatz zu GetScriptsCount gibt die Hilfsfunktion true/false zurück.
  • int >= 0: Anzahl der aktiven Läufe, einschließlich der pausierten. Dies ist eine Menge, nicht bool oder ein Skriptindex.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        if (Truth(HasOtherScripts()))
        {
            UO.Print("Other executions are active");
        }
        else
        {
            UO.Print("No other active executions");
        }

        return null;
    }

    dynamic HasOtherScripts()
    {
        var count = UO.GetScriptsCount();
        return count > 1;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.GetScriptsCount() — UO.GetScriptsCount()

Parameter: Keine Parameter.

Ergebnis: int / Integer.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "getscriptscount": return new InjectionValue(bridge.GetScriptsCount());

UO.GetScriptsList

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

dynamic UO.GetScriptsList();

Gibt die aktuellen numerischen Skriptindizes zurück.

Parameter

Es gibt keine Parameter.

Rückgabewert

Array von int: Indizes 0..N-1 oder ein leeres Array. Bei den Elementen handelt es sich um Zahlen, nicht um Namen oder Texteinträge.

Verhalten

  • Berücksichtigt werden laufende und pausierte Starts; Ausgenommen sind diejenigen, die ausgefüllt wurden und bei denen eine Stornierungsanfrage eingegangen ist. Ein laufendes Skript berücksichtigt normalerweise sich selbst. Das einfache Laden der Registerkarte IDE gilt nicht als Start.
  • Indizes sind die aktuellen Positionen in der Startreihenfolge. Beim Starten/Stoppen von Skripten kann es zu Positionsverschiebungen kommen. Unterschiedliche Aufrufe bilden keinen gemeinsamen atomaren Schnappschuss; Lesen Sie die Liste vor dem nächsten Steuerbefehl erneut.
  • GetScriptsList gibt die Indizes an, GetScriptsCount die Menge, GetScriptState den Drei-Zustands-Code. Ersetzen Sie nicht das eine durch das andere und behandeln Sie kein Ergebnis ungleich Null als Wert von true.
  • Es gibt keine Argumente. Übergeben Sie jede Zahl an den entsprechenden Getter des Namens, Pfads oder Status. Das resultierende Array ist ein separater Snapshot; Eine Änderung hat keine Auswirkungen auf Skripte.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

object? result = UO.GetScriptsList();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1. Erster Aufruf und Ergebnis – direktes Drehbuch

Parameter und Ablauf:

  • Führen Sie das angegebene C#-Skript aus. Die Zahl 0 bezeichnet dort, wo sie übergeben wird, den Index; Leere Klammern bedeuten keine Argumente. Der Text Print ist nur eine Beispielnachricht.
  • Es gibt keine Argumente. Übergeben Sie jede Zahl an den entsprechenden Getter des Namens, Pfads oder Status. Das resultierende Array ist ein separater Snapshot; Eine Änderung hat keine Auswirkungen auf Skripte.
  • Array von int: Indizes 0..N-1 oder ein leeres Array. Bei den Elementen handelt es sich um Zahlen, nicht um Namen oder Texteinträge.
var indices = UO.GetScriptsList();
foreach (var index in indices)
{
    UO.Print(Convert.ToString(index) + ": " + UO.GetScriptName(index));
}

2. Verwendung in einer Schleife oder Bedingung – Skriptfunktion

Parameter und Ablauf:

  • Dies ist ein konkretes Beispiel für die gemeinsame Nutzung von Befehlen. Die Array-Indizierung beginnt bei Null; Bitte überprüfen Sie die Länge vor der Handhabung. UO.Wait(250) wartet dort, wo es verwendet wird, 250 Millisekunden.
  • Es gibt keine Argumente. Übergeben Sie jede Zahl an den entsprechenden Getter des Namens, Pfads oder Status. Das resultierende Array ist ein separater Snapshot; Eine Änderung hat keine Auswirkungen auf Skripte.
  • Array von int: Indizes 0..N-1 oder ein leeres Array. Bei den Elementen handelt es sich um Zahlen, nicht um Namen oder Texteinträge.
return  RunScenario();
 object? RunScenario()
{
    var indices = UO.GetScriptsList();
    if (Truth(ArrayLength(indices) > 0))
    {
        var firstIndex = indices[0];
        UO.Print(UO.GetScriptPath(firstIndex));
    }

    return null;
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Vollständige Hilfsfunktion – Skriptklasse

Parameter und Ablauf:

  • Unter Main befindet sich die gesamte Funktion. Seine Parameter und sein Ergebnis werden getrennt vom aufgerufenen API-Befehl erläutert.
  • FindNamedScript durchläuft die aktuellen Indizes und gibt die erste genaue Übereinstimmung mit dem Anzeigenamen oder -1 zurück. Namen können wiederholt werden, Indizes können später verschoben werden.
  • Array von int: Indizes 0..N-1 oder ein leeres Array. Bei den Elementen handelt es sich um Zahlen, nicht um Namen oder Texteinträge.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var index = FindNamedScript("Mining");
        if (Truth(index >= 0))
        {
            UO.Print(Convert.ToString(index));
        }
        else
        {
            UO.Print("Name not found");
        }

        return null;
    }

    dynamic FindNamedScript(dynamic wanted)
    {
        var indices = UO.GetScriptsList();
        foreach (var index in indices)
        {
            if (Truth(UO.GetScriptName(index) == wanted))
            {
                return index;
            }
        }

        return -1;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.GetScriptsList() — UO.GetScriptsList()

Parameter: Keine Parameter.

Ergebnis: dynamic / Array.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "getscriptslist": return new InjectionValue(bridge.GetScriptsList().Select(value => new InjectionValue(value)).ToArray());

UO.Launch

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

int UO.Launch(object? file);
int UO.Launch(object? file, object? parameters);
int UO.Launch(object? file, object? parameters, object? workingDirectory);
int UO.Launch(object? file, object? parameters, object? workingDirectory, object? hidden);

Parameter

  • file – Obligatorischer Pfad/Name des Programms oder Dokuments; in Text umgewandelt, Leerzeichen werden entfernt. Ein leerer Wert ergibt 0 und eine Fehlermeldung. Um das genaue Programm auszuwählen, verwenden Sie den vollständigen Pfad. Es ist nicht erforderlich, der Datei selbst äußere Anführungszeichen hinzuzufügen.
  • workingDirectory – Optionaler Arbeitsordner des Prozesses. Bei einer Auslassung oder Leerzeile wird der Ordner des aktuellen Skripts übernommen. Wenn die Laufzeit keinen solchen Ordner hat, verwendet Bridge den aktuellen Arbeitsordner des Clients. Dies ist nicht immer der Spielordner oder der EXE-Client-Ordner.
  • hidden – Optionaler boolescher Wert, Standard false. true deaktiviert das Öffnen über die Betriebssystem-Shell und fordert den Start ohne Konsolenfenster an; Sie benötigen eine ausführbare Datei. false ermöglicht Dokumentzuordnungen. Das GUI-Programm selbst kann weiterhin sein Fenster anzeigen.

Rückgabewert

int: 1 (true) wenn Process.Start ein Prozessobjekt zurückgegeben hat; andernfalls 0 (false). In C# Ergebnis == 1 oder Ergebnis != 0 prüfen; int kann nicht direkt mit true verglichen werden. Dies ist kein PID, kein Exit-Code oder keine Bestätigung des Abschlusses der Arbeit. Tritt eine Ausnahme auf, wird ein Fehler ausgegeben und 0 zurückgegeben. Beim Öffnen eines Dokuments über ein bereits laufendes Programm gibt das Betriebssystem manchmal keinen neuen Prozess zurück: 0 beweist in diesem Fall nicht, dass das Dokument nicht geöffnet wurde.

Verhalten

  • Es sind nur Überladungen von ein bis vier Argumenten in der angegebenen Reihenfolge zulässig. Um „hidden“ anzugeben und den Standardarbeitsordner beizubehalten, übergeben Sie eine leere Zeichenfolge als drittes Argument. Bei Konvertierungen von file/parameters/workingDirectory in Text wird nicht vorab geprüft, ob die Datei vorhanden ist.
  • Der Standardordner wird durch das aktuell ausgeführte Skript bestimmt. Bei versteckt=true wird zunächst der relative Programmpfad gegen workingDirectory geprüft. Die teilweise Suche nach Betriebssystemnamen und deren Zuordnungen sind systemspezifisch. Der vollständige Pfad beseitigt Mehrdeutigkeiten. Wenn der Arbeitsordner oder das Programm nicht verfügbar ist, schlägt der Start möglicherweise fehl.
  • Der externe Prozess läuft unabhängig ab. Launch wartet nicht auf den Abschluss, liest stdout/stderr nicht und beendet es nicht, wenn das Skript gestoppt wird. true für „versteckt“ ist eine Anforderung für eine Startmethode und keine Garantie für die Unsichtbarkeit von Fenstern. Das Process-Objekt wird nach der Anfrage freigegeben; das laufende Programm selbst läuft weiter.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

var result = UO.Launch("loot-report.txt");
UO.Print("Launch: " + Convert.ToString(result));

1. Öffnen Sie einen vorgefertigten Mining-Bericht – direktes Skript

Parameter und Ablauf:

  • Platzieren Sie die vorhandene loot-report.txt neben dem Skript. Das Betriebssystem öffnet es mit der der TXT-Datei zugewiesenen Anwendung. Main gibt das Ergebnis der Launch-Anfrage zurück, nicht den Inhalt des Berichts und keine Bestätigung, dass er gelesen wurde.
var started = UO.Launch("loot-report.txt");
return started;

2. Übergeben Sie den Pfad mit Leerzeichen an den Editor – Skriptfunktion

Parameter und Ablauf:

  • Der Ordner und der Bericht müssen vorhanden sein; Ersetzen Sie sie durch Ihre eigenen. Chr(34) schließt den vollständigen Pfad des Berichts in doppelte Anführungszeichen innerhalb von Argumenten ein. notepad.exe muss für das System zugänglich sein. false aktiviert das normale Editorfenster.
return  RunScenario();
 object? RunScenario()
{
    var report = "C:\\UO Scripts\\loot report.txt";
    var arguments = Chr(34) + report + Chr(34);
    return UO.Launch("notepad.exe", arguments, "C:\\UO Scripts", false);
    return null;
}

string Chr(object? value) => ((char)Convert.ToInt32(value)).ToString();

3. Bereiten Sie eine Liste lokaler Protokolle ohne Konsolenfenster vor – Skriptklasse

Parameter und Ablauf:

  • Im Windows-Beispiel wird die integrierte cmd.exe ausgeführt. Im Skriptordner wird log-files.txt mit einer Liste von *.logs erstellt oder überschrieben. Ein leeres drittes Argument speichert den Skriptordner, true versteckt die Konsole. true von Main bedeutet nur Start: Die Datei ist möglicherweise noch nicht fertig, und das Fehlen von *.log oder ein Dienstprogrammfehler ändert nichts am bereits erhaltenen Ergebnis Launch.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var started = UO.Launch("cmd.exe", "/d /c dir /b *.log > log-files.txt", "", true);
        if (Truth(started == 0))
        {
            return false;
        }

        return true;
        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.Launch(file) — UO.Launch(Any)

Parameter: file (Any)

Ergebnis: int / Integer.

Beim Aufruf:

Der Aufruf führt den gespeicherten Handler-Delegate aus. Die Registrierungsmethode erzeugt ihn beim Aufbau der API.

Interner Implementierungscode; kein eigenständiges Skript.

values => new InjectionValue(CompactLaunch(values))

UO.Launch(file, parameters) — UO.Launch(Any,Any)

Parameter: file (Any), parameters (Any)

Ergebnis: int / Integer.

Beim Aufruf:

Der Aufruf führt den gespeicherten Handler-Delegate aus. Die Registrierungsmethode erzeugt ihn beim Aufbau der API.

Interner Implementierungscode; kein eigenständiges Skript.

values => new InjectionValue(CompactLaunch(values))

UO.Launch(file, parameters, workingDirectory) — UO.Launch(Any,Any,Any)

Parameter: file (Any), parameters (Any), workingDirectory (Any)

Ergebnis: int / Integer.

Beim Aufruf:

Der Aufruf führt den gespeicherten Handler-Delegate aus. Die Registrierungsmethode erzeugt ihn beim Aufbau der API.

Interner Implementierungscode; kein eigenständiges Skript.

values => new InjectionValue(CompactLaunch(values))

UO.Launch(file, parameters, workingDirectory, hidden) — UO.Launch(Any,Any,Any,Any)

Parameter: file (Any), parameters (Any), workingDirectory (Any), hidden (Any)

Ergebnis: int / Integer.

Beim Aufruf:

Der Aufruf führt den gespeicherten Handler-Delegate aus. Die Registrierungsmethode erzeugt ihn beim Aufbau der API.

Interner Implementierungscode; kein eigenständiges Skript.

values => new InjectionValue(CompactLaunch(values))

UO.PauseResumeScript

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.PauseResumeScript(object? scriptIndex);

Schaltet die manuelle Pause eines aktiven Laufs um. Verwenden Sie diese Option, um das Mining oder einen anderen Vorgang vorübergehend anzuhalten, ohne den aktuellen Fortschritt zu verlieren.

Parameter

  • scriptIndex – Obligatorisch ScriptIndex – aktueller Startindex: 0 bedeutet den ersten, dann 1, 2... Holen Sie es durch GetScriptsList; es ist nicht serial, der Dateiname, und nicht das Ergebnis von StartScript. Ein negativer/fehlender Index ändert nichts.

Rückgabewert

void – kein Rückgabewert. Vergleichen Sie den Anruf nicht mit true/1. Überprüfen Sie den Zustand, indem Sie GetScriptState separat ablesen. Das Ergebnis einer solchen Ablesung ist 0 (kein Start), 1 (läuft), 2 (Pause).

Verhalten

  • Funktioniert nur mit Läufen der aktuellen Sitzung. Ein geöffneter Tab ohne Ausführung ist kein aktiver Start. Durch das Anhalten wird weder die Originaldatei gelöscht noch die Verbindung zum Server getrennt.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
  • Dies ist ein Schalter, kein „Immer fortfahren“-Befehl. Manuelle und automatische Pausen sind unabhängig voneinander: Beim Umschalten auf manuell wird die Verbindungsunterbrechungspause nicht entfernt. Der Code 2 erklärt nicht den Grund für die Pause. Wenn Sie Ihren eigenen Start auf diese Weise stoppen, ist er nicht in der Lage, den nächsten Aufruf zur Fortsetzung durchzuführen; Fortsetzen von IDE/manager oder einem anderen Skript.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

for (int index = 0; index < UO.GetScriptsCount(); index++)
    if (UO.GetScriptName(index) == "Worker")
    { UO.PauseResumeScript(index); break; }

1. Pause nach Namen umschalten – direktes Skript

Parameter und Ablauf:

  • MineOre ist ein Beispiel für den Anzeigenamen einer bereits laufenden Prozedur. FindNamedRun gibt den ersten übereinstimmenden Index zurück oder -1. Anruf von einem anderen Controller; Ein erneuter Aufruf ändert die manuelle Pause wieder.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
var index = FindNamedRun("MineOre");
if (Truth(index >= 0))
{
    UO.PauseResumeScript(index);
}

dynamic FindNamedRun(dynamic wanted)
{
    var indices = UO.GetScriptsList();
    foreach (var index in indices)
    {
        if (Truth(UO.GetScriptName(index) == wanted))
        {
            return index;
        }
    }
    return -1;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Unterbrechen Sie einen laufenden Start – Skriptfunktion

Parameter und Ablauf:

  • Check == 1 beschränkt die Aktion auf einen laufenden Trigger. Der Wert 2 wird nicht als Anzeige für „manuelle Pause löschen“ verwendet, da er möglicherweise auf keine Kommunikation hinweist.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
return  RunScenario();
 object? RunScenario()
{
    var index = FindNamedRun("MineOre");
    if (Truth(index >= 0))
    {
        if (Truth(UO.GetScriptState(index) == 1))
        {
            UO.PauseResumeScript(index);
        }
    }

    return null;
}

dynamic FindNamedRun(dynamic wanted)
{
    var indices = UO.GetScriptsList();
    foreach (var index in indices)
    {
        if (Truth(UO.GetScriptName(index) == wanted))
        {
            return index;
        }
    }

    return -1;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Wählen Sie „Durch Datei ausführen – Skriptklasse“ aus

Parameter und Ablauf:

  • Ersetzen Sie den absoluten Pfad durch Ihren. FindFileRun vergleicht Pfade ohne Berücksichtigung der Groß-/Kleinschreibung und gibt den ersten Lauf dieser Datei zurück; In einer Datei können mehrere Prozeduren ausgeführt werden.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var wantedPath = "D:/Game/AutoLoad/Scripts/Worker.csx";
        var index = FindFileRun(wantedPath);
        if (Truth(index >= 0))
        {
            UO.PauseResumeScript(index);
        }

        return null;
    }

    dynamic FindFileRun(dynamic wantedPath)
    {
        var indices = UO.GetScriptsList();
        foreach (var index in indices)
        {
            if (Truth(Convert.ToString(ReplaceText(UO.GetScriptPath(index), Chr(92), "/")) == Convert.ToString(ReplaceText(wantedPath, Chr(92), "/"))))
            {
                return index;
            }
        }

        return -1;
    }

    string Chr(object? value) => ((char)Convert.ToInt32(value)).ToString();
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
    string ReplaceText(object? value, object? oldValue, object? newValue) => (Convert.ToString(value) ?? "").Replace(Convert.ToString(oldValue) ?? "", Convert.ToString(newValue) ?? "");
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.PauseResumeScript(scriptIndex) — UO.PauseResumeScript(Any)

Parameter: scriptIndex (Any)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "pauseresumescript": bridge.PauseResumeScript(Arg(0)); return InjectionValue.Unit;

UO.SetEvent

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.SetEvent(object? name, object? stateValue);
void UO.SetEvent(object? name, object? stateValue, object? repeatOrHandler);
void UO.SetEvent(object? nameValue, object? stateValue, object? repeatValue, object? subNameValue);

Aktiviert oder deaktiviert die Überwachung von Änderungen im Zustand des Charakters und ermöglicht Ihnen die Auswahl einer einmaligen oder sich wiederholenden Reaktion. Sie können beispielsweise das verbleibende Ziel einmalig nach dem Tod abbrechen oder Warnungen vor geringer Ausdauer erhalten. Der Handler wird getrennt von der Bedingung angegeben; Das Hauptskript sollte weiterhin UO.Wait ausführen.

Parameter

  • name – Eine Zeichenfolge mit einem von fünf Namen: ChangeHitPoints, ChangeMana, ChangeStamina, Death, SeeNewPlayer. Der Fall ist nicht wichtig; das Präfix ev ist akzeptabel, zum Beispiel evChangeMana. Leerzeichen an den Rändern werden entfernt. Es gibt keinen numerischen Veranstaltungskatalog; Ein beliebiger Name erstellt kein neues Ereignis.
  • nameValue – Gleicher Ereignisname wie Name; Dies ist der Name des ersten Parameters in einer Form mit vier Argumenten, kein optionaler Wert.
  • stateValue - true/1 schaltet die Überwachung ein, false/0 meldet sich ab. Übergeben Sie boolesche Werte ohne Anführungszeichen. Bei einer numerischen Konvertierung enthält jede Ganzzahl ungleich Null eine Beobachtung. Beim Deaktivieren wird nicht gewartet oder ein bereits ausgeführter Handler gestoppt.
  • repeatOrHandler – Das dritte Argument hat zwei Zwecke. Eine nicht numerische, nicht leere Zeichenfolge, z. B. „OnManaChanged“, gibt einen Handler für die automatische Wiederholung an. Zahl/bool setzt nur Wiederholung: false/0 – ein Vorgang, true/1 – Wiederholung; In diesem Formular ist kein Handler zugewiesen. Die Zeichenfolge „1“ ist ebenfalls numerisch und kein Prozedurname. Verwenden Sie für einen einmaligen Handler vier Argumente.
  • repeatValue – In der Form mit vier Argumenten: false/0 – löscht das Abonnement nach dem ersten erkannten Übergang, true/1 – belässt es für die nächsten Änderungen. Ein einmaliges Abonnement wird auch gekündigt, wenn der Handler nicht gefunden wird oder der Manager den Start ablehnt; Verwechseln Sie die Erkennung eines Ereignisses nicht mit dem erfolgreichen Abschluss eines Verfahrens.

Rückgabewert

void – kein Wert. Aufruf auf separater Leitung, ohne var-Ergebnis = und ohne Vergleich mit true/1. Durch den Abschluss der Registrierung wird nicht bestätigt, dass der Handler gefunden oder gestartet wurde oder dass der Server eine Aktion ausgeführt hat. Wenn der Prozedurname im Ereignis nicht gefunden wird, erfolgt der Aufruf nicht.

Verhalten

  • Zwei Argumente: false deaktiviert das Ereignis; true beinhaltet wiederholte Beobachtungen ohne Hundeführer. Eine Prozedur mit einem übereinstimmenden Namen wird nicht automatisch ersetzt. Dieses Formular gibt keinen Befund zurück und ersetzt nicht den HP/Mana/Dead-Test.
  • Die vier Argumente geben explizit den Ereignisnamen, die Aktivierung, die Wiederholung und den Handler an. Beide booleschen Parameter werden ohne Anführungszeichen geschrieben. false/0 = One-Shot: Das Abonnement wird nach dem ersten erkannten Übergang abgemeldet, nicht nach dem Ende des Handlers.
  • Durch die erneute Registrierung eines Ereignisses werden dessen vorherige Einstellungen ersetzt und der aktuelle Status als neuer Referenzpunkt gespeichert. Abonnements SetEvent und SetEventProc für einen normalisierten Namen innerhalb eines Skripts verwenden einen Datensatz und werden nicht akkumuliert.
  • ChangeHitPoints vergleicht den aktuellen HP self mit dem vorherigen Schnappschuss; Löst sowohl beim Verlust als auch bei der Wiederherstellung der Gesundheit aus. ChangeMana und ChangeStamina reagieren in beide Richtungen ähnlich. Es geht nicht nur um Schaden, Manaverbrauch oder Erschöpfung.
  • Der Tod wird durch den Übergang lebendig → tot ausgelöst. Das Registrieren eines bereits toten Zeichens ruft nicht sofort den Handler auf; Ein erneutes Sterben nach der Auferstehung kann es erneut auslösen.
  • SeeNewPlayer vergleicht die Menge der heruntergeladenen Mobiltelefone mit Ausnahme von 0 und self. Der Name bedeutet nicht, dass der tatsächliche Spieler getestet wird: Dazu gehören NPC und Kreaturen. Ein oder mehrere neue serial pro Prüfung verursachen einen Startversuch. Auch die Rückkehr des verstorbenen mobile aus dem geladenen Satz kann als Neuauftritt gewertet werden. ID wird nicht an den Handler übergeben – die notwendigen Objekte müssen separat gefunden werden.
  • UO.Wait und WaitAsync unterteilen die Wartezeit in Intervalle bis zu 25 ms und prüfen nach jedem Ereignis auf Ereignisse; UO.Wait(0) führt auch die Prüfung durch. Hierbei wird der verfügbare Status abgefragt, anstatt jedes Netzwerkpaket abzufangen: Schnelle Änderungen und Rückgaben zwischen Überprüfungen können übersehen werden. In einem Rechenzyklus ohne UO.Wait oder nach Abschluss des Hauptskripts erfolgt keine ständige Überwachung.
  • Der Handlername ist über RegisterRoutine dem C#-Delegierten vorab zugeordnet. Der Rückruf wird in dieser Sitzung asynchron ausgeführt. Eine Aufgabe überlagert sich nicht. Nach dem Ende des Hauptskripts sind ihr weitere Aktionen untersagt.
  • Ein Abonnement bezieht sich auf eine Instanz eines laufenden Skripts. Entfernen Sie es in Main, das es erstellt hat: Der gleichnamige Befehl in einem separat gestarteten Handler ändert seine eigenen Abonnements. Durch das Aufheben der Registrierung wird ein bereits ausgeführter Handler nicht gestoppt. Verwenden Sie try/finally für einen normalen Exit oder einen behandelbaren Fehler. Force Stop stoppt auch die weitere Abfrage dieses Skripts.
  • Ein unbekannter, nicht leerer Ereignisname wird bei der Registrierung mit einer Systemmeldung abgewiesen. Ein leerer Name bringt nichts. Das Vorhandensein eines Handlers wird nur bei Auslösung überprüft. Es ist besser, einen Fehler im Namen im Voraus über SubExists zu erkennen und das Skript in IDE zu überprüfen.

In C# muss der Handler explizit registriert werden: RegisterRoutine("Handler", Handler). Änderungen an HP, Mana und Ausdauer erfolgen über die native Ereigniswarteschlange; Tod und SeeNewPlayer werden anhand von Schnappschüssen der lokalen Welt überprüft. Direkte Abonnements mit Argumenten sind über SubscribeEvent("UO.JournalEntry", Handler) und ähnliche native Namen verfügbar. Alle Abonnements werden freigegeben, wenn diese Ausführung abgeschlossen oder storniert ist.

Hochgeladene C#-Dateien

Zusätzlich zu lokalen Delegaten unterstützt der aktuelle Manager explizit geladene C#-Einträge mit einem Schlüssel wie Child.csx::Main. SubExists und FunRunning akzeptieren einen solchen Schlüssel; CallSub führt die Datei ohne Args aus und Exec("exec Child.csx::Main 'north gate' 42") übergibt Args. Der Schlüssel mit Leerzeichen ist in Anführungszeichen innerhalb von Exec eingeschlossen. Ein eindeutiger Kurzname ist akzeptabel, ein mehrdeutiger Name wählt keine zufällige Datei aus. Die örtliche Anmeldung hat Vorrang. Ein Dateistart erhält seinen eigenen Kontext und seine eigene Lebensdauer in der aktuellen Welt/im aktuellen Manager; Lokale Delegierte gehören zu der Ausführung, die sie registriert hat.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

RegisterRoutine("HealthChanged", () => UO.Print("HP changed"));
UO.SetEvent("ChangeHitPoints", true, false, "HealthChanged");
await WaitAsync(5000);

1. Ein unvollständiges Ziel einmal nach dem Tod abbrechen – direktes Skript

Parameter und Ablauf:

  • Die Beobachtung dauert acht Sekunden. Der Tod eines bereits toten Charakters ruft den Handler nicht sofort auf. Das zweite Todesereignis nach der Auferstehung wird in diesem Beispiel nicht mehr verarbeitet.
  • Der Handler überprüft den aktiven Cursor des Ziels zur Ausführungszeit und ruft erst dann CancelTarget auf. Die vorbereitete Warteschlange ohne aktiven Cursor wird in diesem Beispiel nicht abgebrochen. Das Skript lässt den Charakter nicht wieder auferstehen, stoppt nicht alle Skripte und beendet Main nicht. Führen Sie das Beispiel nicht aus, wenn Sie das Ziel aktiv halten möchten.
var registrationOnFirstDeath = RegisterRoutine("OnFirstDeath", OnFirstDeath);
UO.SetEvent("Death", true, false, "OnFirstDeath");
try
{
    UO.Wait(8000);
}
finally
{
    UO.SetEvent("Death", false);
}

void OnFirstDeath()
{
    if (Truth(UO.Targeting()))
    {
        UO.CancelTarget();
        UO.Print("Death detected: active targeting cancelled");
    }
    else
    {
        UO.Print("Death detected: no active target");
    }
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Wiederholte Ausdauerwarnung: Kurzform – Skriptfunktion

Parameter und Ablauf:

  • 24 × 250 ms – sechs Sekunden. 10 ist unser Schwellenwert im Handler, nicht das zusätzliche Argument SetEvent. Der Ausdaueranstieg wird ebenfalls durch den Hundeführer verursacht, allerdings wird bei einem Wert ab 10 die Meldung nicht angezeigt.
  • true, „OnFatigue“ unterscheidet sich von true, true: Die letztere Option spezifiziert eine Wiederholung ohne Prozedur. Das Skript erhöht weder die Ausdauer noch verändert es die Servergeschwindigkeit.
return  RunScenario();
 object? RunScenario()
{
    var registrationOnFatigue = RegisterRoutine("OnFatigue", OnFatigue);
    UO.SetEvent("evChangeStamina", true, "OnFatigue");
    try
    {
        for (int tick = (int)(1); tick <= 24; tick += (int)(1))
        {
            UO.Wait(250);
        }
    }
    finally
    {
        UO.SetEvent("ChangeStamina", false);
    }

    return null;
}

void OnFatigue()
{
    var staminaNow = UO.Stamina();
    if (Truth(staminaNow < 10))
    {
        UO.Print("Stamina is " + Convert.ToString(staminaNow) + ": consider resting");
    }
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Mana-Handler umschalten, ohne Abonnements anzusammeln – Skriptklasse

Parameter und Ablauf:

  • In den ersten zwei Sekunden löst jede erkannte Änderung OnManaLog aus. Für die nächsten drei Sekunden wird OnLowMana verwendet. Durch die Registrierung eines zweiten Handlers wird dieser nicht selbst ausgelöst.
  • Durch den Austausch wird der bereits laufende alte Vorgang nicht unterbrochen. Diese kurzen Handler verwenden keine lokalen Main-Variablen. Wenn die Auferlegung von Verfahren verboten ist, kann der Manager den Start ablehnen – für diesen Modus überprüfen Sie Mana direkt im Main.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var registrationOnManaLog = RegisterRoutine("OnManaLog", OnManaLog);
        var registrationOnLowMana = RegisterRoutine("OnLowMana", OnLowMana);
        UO.SetEvent("ChangeMana", true, true, "OnManaLog");
        try
        {
            UO.Wait(2000);
            UO.SetEvent("ChangeMana", true, true, "OnLowMana");
            UO.Wait(3000);
        }
        finally
        {
            UO.SetEvent("ChangeMana", false);
        }

        return null;
    }

    void OnManaLog()
    {
        UO.Print("Mana now: " + Convert.ToString(UO.Mana()));
    }

    void OnLowMana()
    {
        if (Truth(UO.Mana() < 20))
        {
            UO.Print("Mana below 20: check the cost before casting");
        }
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
    private IDisposable RegisterRoutine(string name, Action handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Action<string[]> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<string[], Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.SetEvent(name, stateValue) — UO.SetEvent(Any,Any)

Parameter: name (Any), stateValue (Any)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "SetEvent": SetStateEvent(arguments); return true;

Interner Implementierungscode; kein eigenständiges Skript.

public void SetEvent(InjectionValue name, InjectionValue stateValue)

            => SetEvent(name, stateValue, InjectionValue.True, new InjectionValue(string.Empty));

UO.SetEvent(name, stateValue, repeatOrHandler) — UO.SetEvent(Any,Any,Any)

Parameter: name (Any), stateValue (Any), repeatOrHandler (Any)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "SetEvent": SetStateEvent(arguments); return true;

Interner Implementierungscode; kein eigenständiges Skript.

public void SetEvent(InjectionValue name, InjectionValue stateValue, InjectionValue repeatOrHandler)

        {

            string raw = repeatOrHandler.ToString() ?? string.Empty;

            if (!string.IsNullOrWhiteSpace(raw) && !NumberConversions.TryStr2Int(raw, out _))

                SetEvent(name, stateValue, InjectionValue.True, repeatOrHandler);

            else

                SetEvent(name, stateValue, repeatOrHandler, new InjectionValue(string.Empty));

        }

UO.SetEvent(nameValue, stateValue, repeatValue, subNameValue) — UO.SetEvent(Any,Any,Any,Any)

Parameter: nameValue (Any), stateValue (Any), repeatValue (Any), subNameValue (Any)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "SetEvent": SetStateEvent(arguments); return true;

Interner Implementierungscode; kein eigenständiges Skript.

public void SetEvent(InjectionValue nameValue, InjectionValue stateValue, InjectionValue repeatValue, InjectionValue subNameValue)

        {

            string name = NormalizeLegacyEventName(nameValue.ToString());

            if (string.IsNullOrEmpty(name))

                return;



            bool enabled = NumberConversions.ToInt(stateValue) != 0;

            eventStates[name] = enabled ? 1 : 0;

            if (!enabled)

            {

                legacyEvents.Remove(name);

                return;

            }



            if (!IsSupportedLegacyEventName(name))

            {

                eventStates[name] = 0;

                legacyEvents.Remove(name);

                SystemMessage($"SetEvent: unsupported event '{name}'. Supported: SeeNewPlayer, Death, ChangeHitPoints, ChangeMana, ChangeStamina.");

                return;

            }



            var subscription = new LegacyEventSubscription

            {

                Name = name,

                Repeat = NumberConversions.ToInt(repeatValue) != 0,

                Handler = NormalizeLegacyEventHandler(subNameValue.ToString())

            };

            CaptureLegacyEventSnapshot(subscription);

            legacyEvents[name] = subscription;

        }

UO.SetEventProc

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.SetEventProc(object? eventname, object? procname);

Bezeichnet eine Prozedur, die der Client ausführt, wenn sich ein beobachteter Zustand ändert: zum Beispiel wenn Gesundheit verloren geht, Mana sich ändert oder ein neues mobile erscheint. Ermöglicht die Trennung der Reaktion vom Hauptzyklus. Die Registrierung selbst führt nichts aus: Das Hauptskript muss aktiv bleiben; C#-Kontrollpunkte, WaitAsync und UO.Wait verarbeiten Ereignisse.

Parameter

  • eventname – Eine Zeichenfolge mit einem von fünf Namen: ChangeHitPoints, ChangeMana, ChangeStamina, Death, SeeNewPlayer. Der Fall ist nicht wichtig; das Präfix ev ist akzeptabel, zum Beispiel evChangeMana. Leerzeichen an den Rändern werden entfernt. Es gibt keinen numerischen Veranstaltungskatalog; Ein beliebiger Name erstellt kein neues Ereignis.

Rückgabewert

void – kein Wert. Aufruf auf separater Leitung, ohne var-Ergebnis = und ohne Vergleich mit true/1. Durch den Abschluss der Registrierung wird nicht bestätigt, dass der Handler gefunden oder gestartet wurde oder dass der Server eine Aktion ausgeführt hat. Wenn der Prozedurname im Ereignis nicht gefunden wird, erfolgt der Aufruf nicht.

Verhalten

  • Beide Argumente sind erforderlich. Das Abonnement ist wiederkehrend: Neu erkannte Änderungen führen zu neuen Startversuchen. In einem laufenden Skript wird ein Handler einem normalisierten Ereignisnamen zugewiesen; Durch die erneute Registrierung wird dieser ersetzt und der ursprüngliche Snapshot aktualisiert. SetEventProc(event, "") meldet sich im selben Skript ab. Für eine einmalige Reaktion verwenden Sie SetEvent(Ereignis, true, false, „Handler“).
  • ChangeHitPoints vergleicht den aktuellen HP self mit dem vorherigen Schnappschuss; Löst sowohl beim Verlust als auch bei der Wiederherstellung der Gesundheit aus. ChangeMana und ChangeStamina reagieren in beide Richtungen ähnlich. Es geht nicht nur um Schaden, Manaverbrauch oder Erschöpfung.
  • Der Tod wird durch den Übergang lebendig → tot ausgelöst. Das Registrieren eines bereits toten Zeichens ruft nicht sofort den Handler auf; Ein erneutes Sterben nach der Auferstehung kann es erneut auslösen.
  • SeeNewPlayer vergleicht die Menge der heruntergeladenen Mobiltelefone mit Ausnahme von 0 und self. Der Name bedeutet nicht, dass der tatsächliche Spieler getestet wird: Dazu gehören NPC und Kreaturen. Ein oder mehrere neue serial pro Prüfung verursachen einen Startversuch. Auch die Rückkehr des verstorbenen mobile aus dem geladenen Satz kann als Neuauftritt gewertet werden. ID wird nicht an den Handler übergeben – die notwendigen Objekte müssen separat gefunden werden.
  • UO.Wait und WaitAsync unterteilen die Wartezeit in Intervalle bis zu 25 ms und prüfen nach jedem Ereignis auf Ereignisse; UO.Wait(0) führt auch die Prüfung durch. Hierbei wird der verfügbare Status abgefragt, anstatt jedes Netzwerkpaket abzufangen: Schnelle Änderungen und Rückgaben zwischen Überprüfungen können übersehen werden. In einem Rechenzyklus ohne UO.Wait oder nach Abschluss des Hauptskripts erfolgt keine ständige Überwachung.
  • Der Handlername ist über RegisterRoutine dem C#-Delegierten vorab zugeordnet. Der Rückruf wird in dieser Sitzung asynchron ausgeführt. Eine Aufgabe überlagert sich nicht. Nach dem Ende des Hauptskripts sind ihr weitere Aktionen untersagt.
  • Ein Abonnement bezieht sich auf eine Instanz eines laufenden Skripts. Entfernen Sie es in Main, das es erstellt hat: Der gleichnamige Befehl in einem separat gestarteten Handler ändert seine eigenen Abonnements. Durch das Aufheben der Registrierung wird ein bereits ausgeführter Handler nicht gestoppt. Verwenden Sie try/finally für einen normalen Exit oder einen behandelbaren Fehler. Force Stop stoppt auch die weitere Abfrage dieses Skripts.
  • Ein unbekannter, nicht leerer Ereignisname wird bei der Registrierung mit einer Systemmeldung abgewiesen. Ein leerer Name bringt nichts. Das Vorhandensein eines Handlers wird nur bei Auslösung überprüft. Es ist besser, einen Fehler im Namen im Voraus über SubExists zu erkennen und das Skript in IDE zu überprüfen.

In C# muss der Handler explizit registriert werden: RegisterRoutine("Handler", Handler). Änderungen an HP, Mana und Ausdauer erfolgen über die native Ereigniswarteschlange; Tod und SeeNewPlayer werden anhand von Schnappschüssen der lokalen Welt überprüft. Direkte Abonnements mit Argumenten sind über SubscribeEvent("UO.JournalEntry", Handler) und ähnliche native Namen verfügbar. Alle Abonnements werden freigegeben, wenn diese Ausführung abgeschlossen oder storniert ist.

Hochgeladene C#-Dateien

Zusätzlich zu lokalen Delegaten unterstützt der aktuelle Manager explizit geladene C#-Einträge mit einem Schlüssel wie Child.csx::Main. SubExists und FunRunning akzeptieren einen solchen Schlüssel; CallSub führt die Datei ohne Args aus und Exec("exec Child.csx::Main 'north gate' 42") übergibt Args. Der Schlüssel mit Leerzeichen ist in Anführungszeichen innerhalb von Exec eingeschlossen. Ein eindeutiger Kurzname ist akzeptabel, ein mehrdeutiger Name wählt keine zufällige Datei aus. Die örtliche Anmeldung hat Vorrang. Ein Dateistart erhält seinen eigenen Kontext und seine eigene Lebensdauer in der aktuellen Welt/im aktuellen Manager; Lokale Delegierte gehören zu der Ausführung, die sie registriert hat.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

RegisterRoutine("HealthChanged", () => UO.Print("HP changed"));
UO.SetEventProc("ChangeHitPoints", "HealthChanged");
await WaitAsync(5000);

1. Überwachen Sie Gesundheitsänderungen 10 Sekunden lang – direktes Skript

Parameter und Ablauf:

  • ChangeHitPoints beobachtet HP seines Charakters. OnHealthChanged – Name der Methode unter/über Main in derselben geladenen Datei. UO.Wait verarbeitet Ereignisse; Ein leeres zweites Argument verhindert die Wiederholung.
  • Der Hundeführer warnt nur und wählt die Behandlung nicht automatisch aus. Beim Wechsel von HP 60 → 50 → 70 werden zwei Reaktionen durchgeführt; Dies ist kein Trefferzähler.
var registrationOnHealthChanged = RegisterRoutine("OnHealthChanged", OnHealthChanged);
UO.SetEventProc("ChangeHitPoints", "OnHealthChanged");
try
{
    for (int tick = (int)(1); tick <= 40; tick += (int)(1))
    {
        UO.Wait(250);
    }
}
finally
{
    UO.SetEventProc("ChangeHitPoints", "");
}

void OnHealthChanged()
{
    var hp = UO.HP();
    if (Truth(hp < 40))
    {
        UO.Print("Low health: " + Convert.ToString(hp) + ". Check healing or retreat.");
    }
    else
    {
        UO.Print("Health changed: " + Convert.ToString(hp));
    }
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Die Überwachung von Mana und Ausdauer während der Vorbereitung ist eine Skriptfunktion

Parameter und Ablauf:

  • evChangeMana und ChangeMana sind ein Ereignis. Es gibt zwei unabhängige Abonnements und zwei verschiedene Handler, nicht zwei Handler mit demselben Namen. Die Schwellenwerte 20 und 10 können geändert werden.
  • Die Wartezeit beträgt 5 Sekunden. Die Ressourcenwiederherstellung wird ebenfalls erkannt, es wird jedoch keine Warnung ausgegeben, wenn der Wert bereits über dem Schwellenwert liegt.
return  RunScenario();
 object? RunScenario()
{
    var registrationOnManaChanged = RegisterRoutine("OnManaChanged", OnManaChanged);
    var registrationOnStaminaChanged = RegisterRoutine("OnStaminaChanged", OnStaminaChanged);
    UO.SetEventProc("evChangeMana", "OnManaChanged");
    UO.SetEventProc("ChangeStamina", "OnStaminaChanged");
    try
    {
        for (int tick = (int)(1); tick <= 20; tick += (int)(1))
        {
            UO.Wait(250);
        }
    }
    finally
    {
        UO.SetEventProc("ChangeMana", "");
        UO.SetEventProc("ChangeStamina", "");
    }

    return null;
}

void OnManaChanged()
{
    if (Truth(UO.Mana() < 20))
    {
        UO.Print("Mana below 20: postpone expensive spells");
    }
}

void OnStaminaChanged()
{
    if (Truth(UO.Stamina() < 10))
    {
        UO.Print("Stamina below 10: consider a movement break");
    }
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Beachten Sie neue Mobiltelefone und deaktivieren Sie dann die Überwachung – Skriptklasse

Parameter und Ablauf:

  • SeeNewPlayer erkennt das Vorkommen von serial in der geladenen Gruppe von Mobiltelefonen, einschließlich NPC. Das gleichzeitige Laden von fünf Kreaturen garantiert nicht fünf Beschwörungen.
  • GetMobiles() – separates Lesen des tatsächlichen Satzes, nicht ID vom Ereignis. Um einen Feind auszuwählen, sind explizite Bedingungen erforderlich. Das Beispiel greift niemanden absichtlich an.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var registrationOnMobileAppeared = RegisterRoutine("OnMobileAppeared", OnMobileAppeared);
        UO.SetEventProc("SeeNewPlayer", "OnMobileAppeared");
        try
        {
            UO.Wait(5000);
        }
        finally
        {
            UO.SetEventProc("SeeNewPlayer", "");
        }

        UO.Wait(1000);
        return null;
    }

    void OnMobileAppeared()
    {
        var mobiles = UO.GetMobiles();
        UO.Print("Loaded mobiles now: " + Convert.ToString(ArrayLength(mobiles)));
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
    private IDisposable RegisterRoutine(string name, Action handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Action<string[]> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<string[], Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.SetEventProc(eventname, procname) — UO.SetEventProc(Any,Any)

Parameter: eventname (Any), procname (Any)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "SetEventProc":
                SetStateEvent([arguments[0], !string.IsNullOrWhiteSpace(Convert.ToString(arguments[1])), true, arguments[1]]);
                return true;

Interner Implementierungscode; kein eigenständiges Skript.

case "seteventproc":

                {

                    if (string.IsNullOrWhiteSpace(Text(1)))

                        SetEvent(arguments[0], InjectionValue.False);

                    else

                        SetEvent(arguments[0], InjectionValue.True, InjectionValue.True, arguments[1]);

                    return InjectionValue.Unit;

                }

UO.SetPauseScriptOnDisconnectStatus

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.SetPauseScriptOnDisconnectStatus(object? value);

Ändert die Regel für Skripte, anzuhalten, wenn die Verbindung unterbrochen wird.

Parameter

  • value - 0 schaltet sich aus; Jede Ganzzahl ungleich Null enthält.

Rückgabewert

void – kein Wert. Rufen Sie eine separate Leitung an; Der Abschluss bestätigt nicht die Aktion des Servers.

Verhalten

  • SetPauseScriptOnDisconnectStatus setzt _manager.PauseScriptsOnDisconnect = aktiviert != 0. Bereits laufende Skripte erhalten hier nicht den Befehl PauseResumeScript.
  • Ändert die Client-Einstellung. Der Wert ist nicht das Ergebnis eines Verbindungstests und bestätigt nicht die Verarbeitung durch den Server.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Der Befehl steht in einer eigenen Anweisung. Die Meldung davor zeigt den Beginn des Aufrufs und bestätigt keine Serveraktion.

UO.Print("Calling UO.SetPauseScriptOnDisconnectStatus");
UO.SetPauseScriptOnDisconnectStatus(1);

1. Direkter Aufruf – direktes Skript

Parameter und Ablauf:

  • Ändert die Regel für Skripte, anzuhalten, wenn die Verbindung unterbrochen wird.
UO.SetPauseScriptOnDisconnectStatus(1);

2. Explizite Option – Skriptfunktion

Parameter und Ablauf:

  • SetPauseScriptOnDisconnectStatus setzt _manager.PauseScriptsOnDisconnect = aktiviert != 0. Bereits laufende Skripte erhalten hier nicht den Befehl PauseResumeScript.
return  RunScenario();
 object? RunScenario()
{
    UO.SetPauseScriptOnDisconnectStatus(0);
    return null;
}

3. Vollständige Hilfsfunktion – Skriptklasse

Parameter und Ablauf:

  • Ändert die Client-Einstellung. Der Wert ist nicht das Ergebnis eines Verbindungstests und bestätigt nicht die Verarbeitung durch den Server.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        ApplyMode(1);
        return null;
    }

    void ApplyMode(dynamic mode)
    {
        UO.SetPauseScriptOnDisconnectStatus(mode);
    }
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.SetPauseScriptOnDisconnectStatus(value) — UO.SetPauseScriptOnDisconnectStatus(Any)

Parameter: value (Any)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "setpausescriptondisconnectstatus": bridge.SetPauseScriptOnDisconnectStatus(Arg(0)); return InjectionValue.Unit;

UO.SetScriptName

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.SetScriptName(object? scriptIndex, object? value);

Ändert den Anzeigenamen eines aktiven Laufs. Hilft bei der Unterscheidung zwischen laufenden Aufgaben in der Liste und über GetScriptName.

Parameter

  • scriptIndex – Obligatorisch ScriptIndex – aktueller Startindex: 0 bedeutet den ersten, dann 1, 2... Holen Sie es durch GetScriptsList; es ist nicht serial, der Dateiname, und nicht das Ergebnis von StartScript. Ein negativer/fehlender Index ändert nichts.
  • value – Erforderlicher Wert – neuer Name, konvertiert in eine Zeichenfolge. Leerzeichen sind erlaubt; Eine leere Zeichenfolge ist ebenfalls akzeptabel. Dies ist die Signatur der aktuellen Ausführung und nicht der neue Name der Datei oder Prozedur in der Quelle.

Rückgabewert

void – kein Rückgabewert. Vergleichen Sie den Anruf nicht mit true/1. Überprüfen Sie den Zustand, indem Sie GetScriptState separat ablesen. Das Ergebnis einer solchen Ablesung ist 0 (kein Start), 1 (läuft), 2 (Pause).

Verhalten

  • Funktioniert nur mit Läufen der aktuellen Sitzung. Ein geöffneter Tab ohne Ausführung ist kein aktiver Start. Durch das Anhalten wird weder die Originaldatei gelöscht noch die Verbindung zum Server getrennt.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

for (int index = 0; index < UO.GetScriptsCount(); index++)
    if (UO.GetScriptName(index) == "Worker")
    { UO.SetScriptName(index, "Worker renamed"); break; }

1. Geben Sie der Aufgabe einen klaren Namen – direktes Skript

Parameter und Ablauf:

  • MineOre wird in aktiven Läufen gesucht, Mining ist die neue Signatur. Die Namen in den Anführungszeichen werden vom Benutzer erstellt und können ersetzt werden.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
var index = FindNamedRun("MineOre");
if (Truth(index >= 0))
{
    UO.SetScriptName(index, "Mining");
}

dynamic FindNamedRun(dynamic wanted)
{
    var indices = UO.GetScriptsList();
    foreach (var index in indices)
    {
        if (Truth(UO.GetScriptName(index) == wanted))
        {
            return index;
        }
    }
    return -1;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Unterscheiden Sie zwischen Aufgaben aus verschiedenen Dateien – Skriptfunktion

Parameter und Ablauf:

  • Ersetzen Sie wantedPath durch Ihren absoluten Pfad. Die Signatur des ersten aktiven Starts dieser Datei ändert sich, aber die Datei auf der Festplatte bleibt an derselben Stelle.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
return  RunScenario();
 object? RunScenario()
{
    var wantedPath = "D:/Game/AutoLoad/Scripts/Worker.csx";
    var index = FindFileRun(wantedPath);
    if (Truth(index >= 0))
    {
        UO.SetScriptName(index, "Worker A");
    }

    return null;
}

dynamic FindFileRun(dynamic wantedPath)
{
    var indices = UO.GetScriptsList();
    foreach (var index in indices)
    {
        if (Truth(Convert.ToString(ReplaceText(UO.GetScriptPath(index), Chr(92), "/")) == Convert.ToString(ReplaceText(wantedPath, Chr(92), "/"))))
        {
            return index;
        }
    }

    return -1;
}

string Chr(object? value) => ((char)Convert.ToInt32(value)).ToString();
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
string ReplaceText(object? value, object? oldValue, object? newValue) => (Convert.ToString(value) ?? "").Replace(Convert.ToString(oldValue) ?? "", Convert.ToString(newValue) ?? "");

3. Status zur Signatur hinzufügen – Skriptklasse

Parameter und Ablauf:

  • GetScriptState = 2 fügt den pausierten Text zum Namen hinzu. Hierbei handelt es sich um eine einmalige Signatur: Sie wird nach dem Fortfahren nicht automatisch aktualisiert und steuert nicht die Pause selbst.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var index = FindNamedRun("Mining");
        if (Truth(index >= 0))
        {
            var newName = "Mining";
            if (Truth(UO.GetScriptState(index) == 2))
            {
                newName = "Mining (paused)";
            }

            UO.SetScriptName(index, newName);
        }

        return null;
    }

    dynamic FindNamedRun(dynamic wanted)
    {
        var indices = UO.GetScriptsList();
        foreach (var index in indices)
        {
            if (Truth(UO.GetScriptName(index) == wanted))
            {
                return index;
            }
        }

        return -1;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.SetScriptName(scriptIndex, value) — UO.SetScriptName(Any,Any)

Parameter: scriptIndex (Any), value (Any)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "setscriptname": bridge.SetScriptName(Arg(0), Text(1)); return InjectionValue.Unit;

UO.StartScript

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

int UO.StartScript(object? scriptPath);

Parameter

Rückgabewert

int: Anzahl der aktiven Läufe nach einem akzeptierten Lauf; 65535 (0xFFFF) = Startfehler. Dies ist weder der Index des neuen Skripts noch bool noch das Ergebnis der Vervollständigung.

Verhalten

  • Berücksichtigt werden laufende und pausierte Starts; Ausgenommen sind diejenigen, die ausgefüllt wurden und bei denen eine Stornierungsanfrage eingegangen ist. Ein laufendes Skript berücksichtigt normalerweise sich selbst. Das einfache Laden der Registerkarte IDE gilt nicht als Start.
  • Indizes sind die aktuellen Positionen in der Startreihenfolge. Beim Starten/Stoppen von Skripten kann es zu Positionsverschiebungen kommen. Unterschiedliche Aufrufe bilden keinen gemeinsamen atomaren Schnappschuss; Lesen Sie die Liste vor dem nächsten Steuerbefehl erneut.
  • GetScriptsList gibt die Indizes an, GetScriptsCount die Menge, GetScriptState den Drei-Zustands-Code. Ersetzen Sie nicht das eine durch das andere und behandeln Sie kein Ergebnis ungleich Null als Wert von true.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

var result = UO.StartScript("Scripts/Worker.csx");
UO.Print("StartScript: " + Convert.ToString(result));

1. Erster Aufruf und Ergebnis – direktes Drehbuch

Parameter und Ablauf:

  • Führen Sie das angegebene C#-Skript aus. Die Zahl 0 bezeichnet dort, wo sie übergeben wird, den Index; Leere Klammern bedeuten keine Argumente. Der Text Print ist nur eine Beispielnachricht.
  • Erstellen Sie vor den Beispielen separat die angegebenen Worker.csx-Dateien. Ein ungültiger/unzugänglicher Pfad, ein ungeeigneter Hauptpfad, ein deaktivierter C# oder ein deaktivierter Parallellauf führen zu einem Fehler. Wenn der vorherige Lauf immer noch gestoppt ist, ist ein verzögerter Wiederholungsversuch möglich; Das Akzeptieren des Anfangs bedeutet nicht die Vollendung. Ein kurzes Skript kann beendet werden, bevor die zurückgegebene Menge gelesen wird.
  • int: Anzahl der aktiven Läufe nach einem akzeptierten Lauf; 65535 (0xFFFF) = Startfehler. Dies ist weder der Index des neuen Skripts noch bool noch das Ergebnis der Vervollständigung.
  • Obligatorisch ScriptPath ist eine Zeichenfolge. Der relative Pfad beginnt im Ordner AutoLoad dieses Clients; Der absolute Pfad ist akzeptabel. Schließen Sie Pfade mit Leerzeichen in Anführungszeichen ein. Sie benötigen .csx mit einem Top-Level-Code oder einen regulären .cs/.csproj mit einem unterstützten Einstiegspunkt C#.
var count = UO.StartScript("Scripts/Worker.csx");
if (Truth(count==65535))
{
    UO.Print("launch failed");
}
else
{
    UO.Print("Active executions: " + Convert.ToString(count));
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Verwendung in einer Schleife oder Bedingung – Skriptfunktion

Parameter und Ablauf:

  • Dies ist ein konkretes Beispiel für die gemeinsame Nutzung von Befehlen. Die Array-Indizierung beginnt bei Null; Bitte überprüfen Sie die Länge vor der Handhabung. UO.Wait(250) wartet dort, wo es verwendet wird, 250 Millisekunden.
  • Erstellen Sie vor den Beispielen separat die angegebenen Worker.csx-Dateien. Ein ungültiger/unzugänglicher Pfad, ein ungeeigneter Hauptpfad, ein deaktivierter C# oder ein deaktivierter Parallellauf führen zu einem Fehler. Wenn der vorherige Lauf immer noch gestoppt ist, ist ein verzögerter Wiederholungsversuch möglich; Das Akzeptieren des Anfangs bedeutet nicht die Vollendung. Ein kurzes Skript kann beendet werden, bevor die zurückgegebene Menge gelesen wird.
  • int: Anzahl der aktiven Läufe nach einem akzeptierten Lauf; 65535 (0xFFFF) = Startfehler. Dies ist weder der Index des neuen Skripts noch bool noch das Ergebnis der Vervollständigung.
  • Obligatorisch ScriptPath ist eine Zeichenfolge. Der relative Pfad beginnt im Ordner AutoLoad dieses Clients; Der absolute Pfad ist akzeptabel. Schließen Sie Pfade mit Leerzeichen in Anführungszeichen ein. Sie benötigen .csx mit einem Top-Level-Code oder einen regulären .cs/.csproj mit einem unterstützten Einstiegspunkt C#.
return  RunScenario();
 object? RunScenario()
{
    var count = UO.StartScript("Scripts/My Worker.csx");
    if (Truth(count != 65535))
    {
        var indices = UO.GetScriptsList();
        foreach (var index in indices)
        {
            UO.Print(Convert.ToString(index) + ": " + UO.GetScriptPath(index));
        }
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Vollständige Hilfsfunktion – Skriptklasse

Parameter und Ablauf:

  • Unter Main befindet sich die gesamte Funktion. Seine Parameter und sein Ergebnis werden getrennt vom aufgerufenen API-Befehl erläutert.
  • TryStartCSharp vergleicht das Ergebnis mit 65535 und gibt true/false zurück. Es wartet nicht auf den Abschluss und wandelt die Menge nicht in einen Index um.
  • int: Anzahl der aktiven Läufe nach einem akzeptierten Lauf; 65535 (0xFFFF) = Startfehler. Dies ist weder der Index des neuen Skripts noch bool noch das Ergebnis der Vervollständigung.
  • Obligatorisch ScriptPath ist eine Zeichenfolge. Der relative Pfad beginnt im Ordner AutoLoad dieses Clients; Der absolute Pfad ist akzeptabel. Schließen Sie Pfade mit Leerzeichen in Anführungszeichen ein. Sie benötigen .csx mit einem Top-Level-Code oder einen regulären .cs/.csproj mit einem unterstützten Einstiegspunkt C#.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        if (Truth(TryStartCSharp("Scripts/Worker.csx")))
        {
            UO.Print("launch accepted");
        }
        else
        {
            UO.Print("check file, Main and execution settings");
        }

        return null;
    }

    dynamic TryStartCSharp(dynamic fileName)
    {
        var count = UO.StartScript(fileName);
        return Truth(count != 65535);
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.StartScript(scriptPath) — UO.StartScript(Any)

Parameter: scriptPath (Any)

Ergebnis: int / Integer.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "startscript": return new InjectionValue(bridge.StartScript(Text(0)));

UO.StopAllScripts

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.StopAllScripts();

Parameter

Es gibt keine Parameter.

Rückgabewert

void – kein Rückgabewert. Vergleichen Sie den Anruf nicht mit true/1. Überprüfen Sie den Zustand, indem Sie GetScriptState separat ablesen. Das Ergebnis einer solchen Ablesung ist 0 (kein Start), 1 (läuft), 2 (Pause).

Verhalten

  • Funktioniert nur mit Läufen der aktuellen Sitzung. Ein geöffneter Tab ohne Ausführung ist kein aktiver Start. Durch das Anhalten wird weder die Originaldatei gelöscht noch die Verbindung zum Server getrennt.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
  • Es gibt keine Argumente. Laufende und angehaltene Prozeduren, ausstehende Abfragen und die Wiederholungswarteschlange werden abgebrochen. Auch das aufrufende Skript erhält eine Absage: Fügen Sie nach diesem Befehl nicht die erforderliche Speicherung/den Bericht ein. Andere Profile und Prozesse sind nicht betroffen.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Der Befehl steht in einer eigenen Anweisung. Die Meldung davor zeigt den Beginn des Aufrufs und bestätigt keine Serveraktion.

UO.Print("Calling UO.StopAllScripts");
UO.StopAllScripts();

1. Unbedingter allgemeiner Stopp – direktes Skript

Parameter und Ablauf:

  • Der Befehl enthält leere Klammern. Führen Sie vor dem Aufruf die gewünschte Speicherung durch. Auch der Controller selbst wird gestoppt.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
UO.StopAllScripts();

2. Stoppen Sie beim Tod des Charakters – Skriptfunktion

Parameter und Ablauf:

  • Connected prüft den Zugang zur Welt, Dead prüft den Tod. StopAllScripts wird nur aufgerufen, wenn beide Bedingungen erfüllt sind; Das Beispiel überprüft sie einmal.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Connected()))
    {
        if (Truth(UO.Dead()))
        {
            UO.StopAllScripts();
        }
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Allgemeiner Stopp nach fünf Sekunden – Skriptklasse

Parameter und Ablauf:

  • 5000 ist die Millisekunden in UO.Wait, nicht der StopAllScripts-Parameter. Eine manuelle oder automatische Pause des Controllers kann die Ausführung verzögern; Dies ist kein unabhängiger Timer.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var delayMs = 5000;
        UO.Wait(delayMs);
        UO.StopAllScripts();
        return null;
    }
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.StopAllScripts() — UO.StopAllScripts()

Parameter: Keine Parameter.

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "stopallscripts": bridge.StopAllScripts(); return InjectionValue.Unit;

UO.StopScript

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.StopScript(object? scriptIndex);

Fordert die Stornierung eines aktiven Starts an, einschließlich eines pausierten Starts. Verwenden Sie diese Option, wenn dieser Lauf abgeschlossen werden muss und nicht später fortgesetzt werden muss.

Parameter

  • scriptIndex – Obligatorisch ScriptIndex – aktueller Startindex: 0 bedeutet den ersten, dann 1, 2... Holen Sie es durch GetScriptsList; es ist nicht serial, der Dateiname, und nicht das Ergebnis von StartScript. Ein negativer/fehlender Index ändert nichts.

Rückgabewert

void – kein Rückgabewert. Vergleichen Sie den Anruf nicht mit true/1. Überprüfen Sie den Zustand, indem Sie GetScriptState separat ablesen. Das Ergebnis einer solchen Ablesung ist 0 (kein Start), 1 (läuft), 2 (Pause).

Verhalten

  • Funktioniert nur mit Läufen der aktuellen Sitzung. Ein geöffneter Tab ohne Ausführung ist kein aktiver Start. Durch das Anhalten wird weder die Originaldatei gelöscht noch die Verbindung zum Server getrennt.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
  • Der Abbruch ist kooperativ: wartet auf eine Pause und wird von der Engine überprüft; Bereits an den Server gesendete Aktionen werden nicht abgebrochen. Ein abgebrochener Start wird sofort aus der aktiven Liste entfernt, die Ressourcenfreigabe kann jedoch weiterhin fortgesetzt werden. Überprüfen Sie die Fertigstellung nicht anhand des vorherigen Index: Möglicherweise befindet sich darunter bereits ein weiterer Lauf.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

for (int index = 0; index < UO.GetScriptsCount(); index++)
    if (UO.GetScriptName(index) == "Worker")
    { UO.StopScript(index); break; }

1. Stoppen Sie eine Prozedur – direktes Skript

Parameter und Ablauf:

  • MineOre – Startname. -1 wird nicht auf StopScript übertragen. Nach dem Stoppen wird der gespeicherte Index nicht mehr verwendet.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
var index = FindNamedRun("MineOre");
if (Truth(index >= 0))
{
    UO.StopScript(index);
}

dynamic FindNamedRun(dynamic wanted)
{
    var indices = UO.GetScriptsList();
    foreach (var index in indices)
    {
        if (Truth(UO.GetScriptName(index) == wanted))
        {
            return index;
        }
    }
    return -1;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Stoppen Sie einen angehaltenen Start – Skriptfunktion

Parameter und Ablauf:

  • Code 2 wählt einen pausierten Lauf aus. StopScript beendet es, anstatt es wieder anzuhalten; Andere Aufgaben werden fortgesetzt.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
return  RunScenario();
 object? RunScenario()
{
    var index = FindNamedRun("MineOre");
    if (Truth(index >= 0))
    {
        if (Truth(UO.GetScriptState(index) == 2))
        {
            UO.StopScript(index);
        }
    }

    return null;
}

dynamic FindNamedRun(dynamic wanted)
{
    var indices = UO.GetScriptsList();
    foreach (var index in indices)
    {
        if (Truth(UO.GetScriptName(index) == wanted))
        {
            return index;
        }
    }

    return -1;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Stoppen Sie die Ausführung einer bestimmten Datei – Skriptklasse

Parameter und Ablauf:

  • Der absolute Pfad wählt den ersten aktiven Lauf der Datei aus. Dadurch wird weder eine Datei gelöscht noch werden alle Vorgänge dieser Datei gestoppt.
  • Indizes sind dynamisch: Positionen können sich verschieben, nachdem ein weiterer Lauf abgeschlossen ist. Mehrere API-Aufrufe sind keine atomare Operation. Die Beispiele sind auf das Fehlen paralleler Änderungen an der Liste ausgelegt; Suchen Sie vor der Aktion erneut nach dem gewünschten Lauf und speichern Sie den Index nicht über UO.Wait.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var wantedPath = "D:/Game/AutoLoad/Scripts/Worker.csx";
        var index = FindFileRun(wantedPath);
        if (Truth(index >= 0))
        {
            UO.StopScript(index);
        }

        return null;
    }

    dynamic FindFileRun(dynamic wantedPath)
    {
        var indices = UO.GetScriptsList();
        foreach (var index in indices)
        {
            if (Truth(Convert.ToString(ReplaceText(UO.GetScriptPath(index), Chr(92), "/")) == Convert.ToString(ReplaceText(wantedPath, Chr(92), "/"))))
            {
                return index;
            }
        }

        return -1;
    }

    string Chr(object? value) => ((char)Convert.ToInt32(value)).ToString();
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
    string ReplaceText(object? value, object? oldValue, object? newValue) => (Convert.ToString(value) ?? "").Replace(Convert.ToString(oldValue) ?? "", Convert.ToString(newValue) ?? "");
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.StopScript(scriptIndex) — UO.StopScript(Any)

Parameter: scriptIndex (Any)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "stopscript": bridge.StopScript(Arg(0)); return InjectionValue.Unit;

UO.SubExists

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

int UO.SubExists(object? subrutineName);

Überprüft, ob der C#-Delegierte mit dem angegebenen Namen bei der aktuellen Ausführung registriert ist. Dabei handelt es sich um eine Registrierung von Rückruffunktionen für eine bestimmte Sitzung, ohne dass durch Reflektion automatisch nach beliebigen Methoden gesucht wird. Auf explizit geladene Dateieingaben kann auch per Schlüssel zugegriffen werden.

Parameter

  • subrutineName ist der durch RegisterRoutine gegebene Stringname. Leerzeichen an den Rändern werden entfernt; Bei der Suche nach registrierten Namen wird die Groß-/Kleinschreibung nicht beachtet.

Rückgabewert

int: 1 – Bedingung ist erfüllt, 0 – nicht erfüllt. Speichern Sie das Ergebnis eines Aufrufs, wenn es für mehrere Prüfungen erforderlich ist.

Verhalten

  • Anmeldung und Aufgaben gehören zur gleichen Ausführung. Ein anderer Charakter, ein anderes Profil oder ein nachfolgender Lauf verfügt über eine eigene Registrierung.
  • RegisterRoutine akzeptiert Action, Func<Task> oder einen Delegaten mit einem Array von Zeichenfolgenargumenten für Exec. Durch das Entfernen der Registrierung wird der Code nicht ausgeführt und weitere Suchen nach dem Namen werden verhindert.
  • Das Hauptskript muss aktiv bleiben, solange seine Helfer benötigt werden: Nach seiner Fertigstellung werden Aufgaben abgebrochen und Registrierungen und Abonnements freigegeben.
  • FunRunning ist kein Managerindex. GetScriptsList und GetScriptState beschreiben unabhängige Dateistarts; Der lokale Callback erhält keinen separaten Index.
  • Der Callback-Fehler wird bei der nächsten Prüfung an das Hauptskript übergeben. WaitAsync-, UO.Wait- und instrumentierte C#-Schleifen unterstützen Pause, Abbruch und Ereigniswarteschlangenverarbeitung.

Hochgeladene C#-Dateien

Zusätzlich zu lokalen Delegaten unterstützt der aktuelle Manager explizit geladene C#-Einträge mit einem Schlüssel wie Child.csx::Main. SubExists und FunRunning akzeptieren einen solchen Schlüssel; CallSub führt die Datei ohne Args aus und Exec("exec Child.csx::Main 'north gate' 42") übergibt Args. Der Schlüssel mit Leerzeichen ist in Anführungszeichen innerhalb von Exec eingeschlossen. Ein eindeutiger Kurzname ist akzeptabel, ein mehrdeutiger Name wählt keine zufällige Datei aus. Die örtliche Anmeldung hat Vorrang. Ein Dateistart erhält seinen eigenen Kontext und seine eigene Lebensdauer in der aktuellen Welt/im aktuellen Manager; Lokale Delegierte gehören zu der Ausführung, die sie registriert hat.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

RegisterRoutine("Hello", () => UO.Print("Hello"));
UO.Print("Registered flag: " + UO.SubExists("Hello"));

1. Führen Sie die verfügbare optionale Prozedur aus – direktes Skript

Parameter und Ablauf:

  • Der Befehl gibt int zurück: in C# check result != 0 or result == 1; Ein direkter Vergleich mit true ist nicht akzeptabel. Die Definition von WeightWatch ist unten angegeben und wird über RegisterRoutine registriert, bevor der Befehl aufgerufen wird.
  • Speichern Sie das Beispiel als separate Datei, laden Sie es in IDE/manager und führen Sie Main aus, sodass die restlichen Prozeduren im Verzeichnis landen. WeightWatch/ManaWatch – hier vollständig definierte Trainingsprozeduren: drei Gewichts-/Manamessungen mit einem Intervall von UO.Wait(1000), also 1000 ms, Ausgabe nur beim Betreten der Welt. Hierbei handelt es sich nicht um eine kontinuierliche Überwachung; Eine Pause kann die Zeit verlängern. Für das Beispiel mit zwei Aufgaben muss der gleichzeitige Start von Prozeduren erlaubt sein.
var registrationWeightWatch = RegisterRoutine("WeightWatch", WeightWatch);
if (Truth(Truth(UO.SubExists("WeightWatch")) == true))
{
    UO.CallSub("WeightWatch");
}

while (UO.FunRunning("WeightWatch") != 0) await WaitAsync(25);

void WeightWatch()
{
    dynamic sample = 0;
    for (sample = (int)(1); sample <= 3; sample += (int)(1))
    {
        if (Truth(UO.Connected()))
        {
            UO.Print("Weight: " + Convert.ToString(UO.Weight()));
        }
        UO.Wait(1000);
    }
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Wählen Sie den Fallback-Handler – Skriptfunktion

Parameter und Ablauf:

  • WeightWatch kann aus einer anderen Datei geladen werden. Wenn es nicht vorhanden ist, wird das hier deklarierte ManaWatch ausgewählt. Wenn der Primärserver gefunden wird, aber nicht gestartet werden kann, findet kein automatischer Übergang zum Sekundärserver statt.
  • Speichern Sie das Beispiel als separate Datei, laden Sie es in IDE/manager und führen Sie Main aus, sodass die restlichen Prozeduren im Verzeichnis landen. WeightWatch/ManaWatch – hier vollständig definierte Trainingsprozeduren: drei Gewichts-/Manamessungen mit einem Intervall von UO.Wait(1000), also 1000 ms, Ausgabe nur beim Betreten der Welt. Hierbei handelt es sich nicht um eine kontinuierliche Überwachung; Eine Pause kann die Zeit verlängern. Für das Beispiel mit zwei Aufgaben muss der gleichzeitige Start von Prozeduren erlaubt sein.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var registrationManaWatch = RegisterRoutine("ManaWatch", ManaWatch);
    if (Truth(UO.SubExists("WeightWatch") == 1))
    {
        UO.CallSub("WeightWatch");
    }
    else if (Truth(UO.SubExists("ManaWatch")))
    {
        UO.CallSub("ManaWatch");
    }

    while (UO.FunRunning("ManaWatch") != 0)
        await WaitAsync(25);
    return null;
}

void ManaWatch()
{
    dynamic sample = 0;
    for (sample = (int)(1); sample <= 3; sample += (int)(1))
    {
        if (Truth(UO.Connected()))
        {
            UO.Print("Mana: " + Convert.ToString(UO.Mana()));
        }

        UO.Wait(1000);
    }
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Überprüfen Sie beide Definitionen, bevor Sie die Skriptklasse ausführen

Parameter und Ablauf:

  • HaveMonitors testet zwei Namen mit &&. Fehlt mindestens einer, ruft Main keine Task auf. Es wird eine Reihe von Definitionen getestet. Dies ist keine Garantie für eine erfolgreiche gleichzeitige Ausführung.
  • Speichern Sie das Beispiel als separate Datei, laden Sie es in IDE/manager und führen Sie Main aus, sodass die restlichen Prozeduren im Verzeichnis landen. WeightWatch/ManaWatch – hier vollständig definierte Trainingsprozeduren: drei Gewichts-/Manamessungen mit einem Intervall von UO.Wait(1000), also 1000 ms, Ausgabe nur beim Betreten der Welt. Hierbei handelt es sich nicht um eine kontinuierliche Überwachung; Eine Pause kann die Zeit verlängern. Für das Beispiel mit zwei Aufgaben muss der gleichzeitige Start von Prozeduren erlaubt sein.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var registrationWeightWatch = RegisterRoutine("WeightWatch", WeightWatch);
        var registrationManaWatch = RegisterRoutine("ManaWatch", ManaWatch);
        if (Truth(HaveMonitors()))
        {
            UO.CallSub("WeightWatch");
            UO.CallSub("ManaWatch");
        }

        while (UO.FunRunning("WeightWatch") != 0 || UO.FunRunning("ManaWatch") != 0)
            await WaitAsync(25);
        return null;
    }

    dynamic HaveMonitors()
    {
        return UO.SubExists("WeightWatch") != 0 && UO.SubExists("ManaWatch") != 0;
    }

    void WeightWatch()
    {
        dynamic sample = 0;
        for (sample = (int)(1); sample <= 3; sample += (int)(1))
        {
            if (Truth(UO.Connected()))
            {
                UO.Print("Weight: " + Convert.ToString(UO.Weight()));
            }

            UO.Wait(1000);
        }
    }

    void ManaWatch()
    {
        dynamic sample = 0;
        for (sample = (int)(1); sample <= 3; sample += (int)(1))
        {
            if (Truth(UO.Connected()))
            {
                UO.Print("Mana: " + Convert.ToString(UO.Mana()));
            }

            UO.Wait(1000);
        }
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
    private IDisposable RegisterRoutine(string name, Action handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Action<string[]> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
    private IDisposable RegisterRoutine(string name, Func<string[], Task> handler) => global::ClassicUO.CSharp.CSharpScriptContext.Current.RegisterRoutine(name, handler);
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.SubExists(subrutineName) — UO.SubExists(String)

Parameter: subrutineName (String)

Ergebnis: int / Integer.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "SubExists":
                string requested = Convert.ToString(arguments[0]) ?? "";
                result = Exists(requested) || events is ICSharpScriptHost known && known.HasCSharpScript(requested) ? 1 : 0;
                return true;

Interner Implementierungscode; kein eigenständiges Skript.

public int SubExists(string subrutineName) => bridge.SubExists(subrutineName) ? 1 : 0;

UO.Terminate

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.Terminate();
void UO.Terminate(object? subrutineName);

Parameter

  • subrutineName — Optionale Zeichenfolge. Ohne Argument oder mit einer leeren Zeichenfolge wird die zuletzt gestartete Datei gewählt; "all" fordert den Abbruch aller Ausführungen an. Verwende für C#-Dateien einen exakten Katalogschlüssel wie harvest.csx::Main. Ein lokaler Callback-Name wie Harvest funktioniert erst nach einer ausdrücklichen Registrierung mit RegisterRoutine. Eine Datei besitzt einen Main-Einstieg; einzelne Klassenmethoden werden nicht automatisch separat startbare Prozeduren.

Rückgabewert

void: Der Befehl gibt keine Zahl zurück und wartet nicht auf die Beendigung des Arbeitsthreads. Sie beantragt umgehend eine Stornierung. Die Ausführung stoppt bei der nächsten Stornierungsprüfung; Pausen, Haltepunkte und integrierte Wartezeiten werden unterbrochen. Serveraktionen, die bereits vor dem Abbruch ausgelöst wurden, werden nicht rückgängig gemacht.

Verhalten

UO.FunRunning(name) == 0 kann auch unmittelbar nach einer Abbruchanforderung auftreten. Das bedeutet nicht, dass der vorherige Callback seinen finally-Block beendet hat. Ein weiterer CallSub oder Exec für denselben lokalen Namen wird übersprungen, bis der vorherige Worker tatsächlich beendet ist.

  • UO.Terminate() wählt Prozeduren nach Ausführungsreihenfolge und nicht nach Name, Editorzeile, Zeitpunkt der letzten Aktion oder Anzeigereihenfolge aus. Ein angehaltener Vorgang gilt ebenfalls als ausgeführt.
  • Das zu diesem Lauf gehörende lokale Ziel wird gelöscht und die verbleibende automatische Route wird abgebrochen. Die Bewegungsunterdrückung wird im Spielthread durchgeführt. Wenn die Route bereits durch einen anderen Lauf oder Benutzer ersetzt wurde, wird sie vom Vorbesitzer nicht gestoppt. An den Server gesendete Schritte werden nicht zurückgerufen.
  • Der Befehl bleibt verfügbar, wenn die Einstellung für einen gleichzeitigen Start aktiviert ist. Eine abgebrochene Prozedur gibt erst dann Speicherplatz frei, nachdem ihr Arbeitsthread gelöscht wurde. Zuvor wird der Neustart übersprungen.
  • Das Stoppen nach Namen storniert auch die entsprechenden ausstehenden Starts. Abgeschlossene Prozeduren werden nicht verändert. Der Kunde meldet das Fehlen eines geeigneten Starts im Status. Ein hängengebliebener Aufruf eines nativen Plugins eines Drittanbieters, das den Abbruch nicht unterstützt, kann nicht sicher unterbrochen werden, indem der Thread gewaltsam beendet wird.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Verwende für C#-Dateien einen exakten Katalogschlüssel wie harvest.csx::Main. Ein lokaler Callback-Name wie Harvest funktioniert erst nach einer ausdrücklichen Registrierung mit RegisterRoutine. Eine Datei besitzt einen Main-Einstieg; einzelne Klassenmethoden werden nicht automatisch separat startbare Prozeduren.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

UO.Terminate("harvest.csx::Main");
UO.Print("Cancellation requested for harvest.csx::Main");

1. Hören Sie auf, nach Namen zu sammeln und andere Verfahren zu verlassen – direktes Skript

Hier wird der Abbruch des bereits laufenden harvest.csx::Main angefordert. Die Meldung bestätigt weder den Abschluss seines finally-Blocks noch ein Zurücksetzen von Spielaktionen.

var procedureName = "harvest.csx::Main";
UO.Terminate(procedureName);
UO.Print("Cancellation requested for harvest.csx::Main");

2. Wählen Sie Main nur aus einer bestimmten Datei aus – Skriptfunktion

Der exakte Schlüssel harvest.csx::Main unterscheidet sich von heal.csx::Main. Ersetze ihn durch den Schlüssel deiner geladenen Datei. Beliebige Suffixe wie #2 erzeugen keinen weiteren Einstieg.

return  RunScenario();
 object? RunScenario()
{
    var procedureKey = "harvest.csx::Main";
    UO.Terminate(procedureKey);
    UO.Print("Cancellation requested: " + procedureKey);
    return null;
}

3. Kompatibles Konsolenformular über Exec – Skriptklasse

Die Zeichenfolge terminate harvest.csx::Main übergibt denselben Schlüssel über UO.Exec. Schlüssel mit Leerzeichen müssen innerhalb der Befehlszeichenfolge in Anführungszeichen stehen.

return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var command = "terminate harvest.csx::Main";
        UO.Exec(command);
        UO.Print("Stop command sent");
        return null;
    }
}

4. Stoppen Sie die letzte Ausführung, wenn der Zustand niedrig ist – direktes Skript

Parameter und Ablauf:

  • Das Formular ohne Argumente wählt das zuletzt laufende Skript aus, einschließlich des angehaltenen. Dabei handelt es sich um eine beispielhafte Politik und nicht um eine zwingende Reaktion auf einen schlechten Gesundheitszustand; Vor der Stornierungsanfrage wird eine Meldung angezeigt.
if (UO.GetHP() <= 30)
{
    UO.Print("Low health: requesting cancellation of the most recent run");
    UO.Terminate();
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.Terminate() — UO.Terminate()

Parameter: Keine Parameter.

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

public void Terminate() => bridge.Terminate(string.Empty);

UO.Terminate(subrutineName) — UO.Terminate(String)

Parameter: subrutineName (String)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

case "Terminate" when arguments.Length == 1:
                string routine = Convert.ToString(arguments[0]) ?? "";
                if (Exists(routine)) { Cancel(routine); return true; }
                if (Cancel(routine)) return true;
                return false;

Interner Implementierungscode; kein eigenständiges Skript.

public void Terminate(string subrutineName) => bridge.Terminate(subrutineName);

UO.TerminateAll

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.TerminateAll();

Parameter

Es gibt keine Parameter.

Rückgabewert

void: kein Ergebnis. Der Befehl fordert den Abbruch aller aktuellen Ausführungen an und gibt die Kontrolle an den aufrufenden Code zurück, wenn er nicht selbst abgebrochen wurde. Arbeitsthreads werden bereinigt, nachdem ihre Abbruchprüfungen ausgelöst wurden.

Verhalten

  • Die genaue Syntax ist UO.TerminateAll(), ohne Leerzeichen im Namen und ohne Argumente. UO.Terminate("all") wird als kompatible alternative Notation unterstützt.
  • Stoppt laufende Prozeduren, manuell angehaltene und mit Haltepunkten versehene Prozeduren, integrierte Wartezeiten und registrierte verzögerte Ausführungen. Es ist sicher, zurückzurufen, wenn es keine Arbeit gibt.
  • Das Entfernen lokaler Sehenswürdigkeiten und automatischer Routen berücksichtigt deren Eigentümer. Die verbleibende Route des gestoppten Skripts wird im Spielthread abgebrochen. Die neue Route des Benutzers, die sie ersetzt hat, wird gespeichert. Bereits versendete Antragspakete werden nicht storniert.
  • Durch „Abbrechen“ werden Aktionen, die bereits an den Server gesendet wurden, nicht rückgängig gemacht. Nativer Plugin-Code von Drittanbietern ohne Stornierungsunterstützung kann nicht sicher zusammen mit dem Stream zerstört werden. Neue explizite Starts nach der Befehlsausführung sind zulässig; Wenn das Kontrollkästchen aktiviert ist, warten sie darauf, dass Speicherplatz frei wird, d. h. der Versuch wird übersprungen und nicht in die Warteschlange gestellt, bis die Bereinigung abgeschlossen ist.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Der Befehl steht in einer eigenen Anweisung. Die Meldung davor zeigt den Beginn des Aufrufs und bestätigt keine Serveraktion.

UO.Print("Calling UO.TerminateAll");
UO.TerminateAll();

1. Verhindern Sie, dass alle Skripte innerhalb eines funktionierenden Skripts nachsehen – direktes Skript

Parameter und Ablauf:

  • TerminateAll hat keine Parameter. Bedingung UO.Dead() prüft, ob der Charakter vor der nächsten Iteration gestorben ist.
  • Wenn die Bedingung erfüllt ist, werden sowohl der aktuelle Hauptlauf als auch die verbleibenden Läufe C# abgebrochen. Die Meldung Print steht vor dem Stopp, da danach der Code für diesen Vorgang stoppt.
  • WaitAsync(250) gibt in diesem Beispiel die Pause 250 Millisekunden zwischen den Prüfungen an. Der Stoppbefehl ändert nicht die Länge normaler Skriptpausen.
for (int cycle = (int)(1); cycle <= 10; cycle += (int)(1))
{
    if (Truth(UO.Dead()))
    {
        UO.Print("Character is dead: stopping all C# scripts");
        UO.TerminateAll();
    }
    await Delay(250);
}

Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

2. Kompatibles Formular mit allen - Skriptfunktionen

Parameter und Ablauf:

  • Diese alternative Notation verwendet UO.Terminate mit einem Parameter subrutineName="all". Dies entspricht UO.TerminateAll().
  • Die Zeichenfolge all ist ein spezieller Wert, nicht der Name der Prozedur, die deklariert werden muss. EmergencyStop wird ebenfalls gelöscht.
  • Für den Notspielschlüssel verwenden Sie den einzeiligen Befehl aus dem ersten Beispiel: Die separate Prozedur EmergencyStop unterliegt selbst dem Verbot von Parallelläufen.
return  RunScenario();
 object? RunScenario()
{
    UO.Print("Stopping all C# scripts");
    UO.Terminate("all");
    return null;
}

3. Stoppen Sie den allgemeinen Betrieb, wenn ein erforderliches Objekt nicht mehr verfügbar ist – Skriptklasse

Parameter und Ablauf:

  • GetSerial speichert serial den benötigten Gegenstand, hier seinen eigenen Rucksack. Exists=0 bedeutet, dass dieses Objekt dem Client derzeit unbekannt ist.
  • TerminateAll wird nur dann ohne Argumente aufgerufen, wenn die ausgewählte Bedingung verletzt ist. Diese Richtlinie stoppt alle Vorgänge, nicht nur die Arbeit an einem bestimmten Rucksack.
  • Zunächst wird der Grund für den Stopp angezeigt. Sobald ein Löschungsantrag gestellt wird, wird auch das laufende Verfahren beendet; Mit der nächsten Aktion kann nicht gerechnet werden.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var bag = UO.GetSerial("backpack");
        if (Truth(UO.Exists(bag) == 0))
        {
            UO.Print("Required backpack is unavailable: stopping all scripts");
            UO.TerminateAll();
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

4. Stoppen Sie alle Arbeiten, nachdem die Verbindung unterbrochen wurde – direktes Skript

Parameter und Ablauf:

  • Wenn keine Verbindung besteht, werden alle Starts gestoppt. Der Befehl gibt nicht die Anzahl der abgebrochenen Skripte zurück und bricht auch die aktuelle Ausführung ab.
if (UO.Connected() == 0)
{
    UO.Print("Disconnected: requesting cancellation of every active script");
    UO.TerminateAll();
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.TerminateAll() — UO.TerminateAll()

Parameter: Keine Parameter.

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

public void TerminateAll() => bridge.Terminate("all");

UO.Time

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

int UO.Time();

Liest die lokale Tageszeit des Computers anhand der Zahl HHMMSS. Praktisch für die Auswahl der zulässigen Betriebszeit, nicht für die Messung der Dauer.

Parameter

Es gibt keine Parameter.

Rückgabewert

int HHMMSS, 0..235959 mit gültigen Minuten und Sekunden. 07:29:35 -> 72935; Mitternacht -> 0. Null ist eine gültige Zeit, kein Fehler oder ein logisches Flag false.

Verhalten

  • Es gibt keine Parameter, keine Formulare mit Argumenten. Leere Klammern geben nur die Zeit an: Der Anruf wartet nicht, startet keinen Timer und sendet keine Pakete an das Spiel.
  • RealTimeSource.Jetzt lautet DateTime.Jetzt: das lokale Datum/die lokale Uhrzeit des Computers, nicht UTC, nicht die Shard-Zeit und nicht die Spieluhr. Zeitzone, Sommerzeit und manuelle Zeitumstellung beeinflussen die Ergebnisse. Jeder Anruf fängt einen anderen Moment ein.
  • Führende Nullen bleiben nicht erhalten, Millisekunden bleiben nicht erhalten. Numerisch ergibt 13:00:00 minus 12:59:59 4041, obwohl eine Sekunde vergangen ist. Um Mitternacht wird der Wert wieder Null.
  • Subtrahieren Sie keine Kalendercodes, um die Verzögerung zu berechnen. Verwenden Sie Timer() und zwei Markierungen eines Laufs. Die Kalenderuhr kann zurückgestellt werden.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

var result = UO.Time();
UO.Print("Time: " + Convert.ToString(result));

1. Einzelne Zeitfelder anzeigen - direktes Skript

Parameter und Ablauf:

  • Der Stempel wird einmal gelesen, um verschiedene Sekunden nicht zu vermischen. Int(stamp/10000) – Stunden; Int(stamp/100) MOD 100 — Minuten; MOD 100 – Sekunden. Eine einfache Zeichenfolge füllt Felder nicht mit Nullen auf.
var stamp = UO.Time();
var hour = stamp / 10000;
var minute = stamp / 100 % 100;
var second = stamp % 100;
UO.Print(Convert.ToString(hour) + ":" + Convert.ToString(minute) + ":" + Convert.ToString(second));

2. Serien nur im Abendslot zulassen - Drehbuchfunktion

Parameter und Ablauf:

  • 180000 - 18:00:00 einschließlich; 220000 - 22:00:00 nicht inklusive. Eine Prüfung entscheidet darüber, ob mit Main fortgefahren wird. Der Zeitplan ist nicht registriert und die Serie startet nicht automatisch.
return  RunScenario();
 object? RunScenario()
{
    var stamp = UO.Time();
    if (Truth(stamp >= 180000) && Truth(stamp < 220000))
    {
        UO.Print("Evening batch permitted by local schedule");
    }
    else
    {
        UO.Print("Outside the local schedule");
        return null;
    }

    return null;
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Berücksichtigen Sie das Intervall nach Mitternacht – Szenarioklasse

Parameter und Ablauf:

  • ClockInWindow(Stempel, erster, letzter) akzeptiert gültiges HHMMSS. 230000..20000 bedeutet von 23:00 inklusive bis 02:00 nicht inklusive: OR berücksichtigt Mitternacht. Gleiche Grenzen bedeuten leeres Intervall. Während der ruhigen Zeit endet Main; Die Funktion ist vollständig gegeben.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        if (Truth(ClockInWindow(UO.Time(), 230000, 20000)))
        {
            UO.Print("Local quiet period; do not start a new batch");
            return null;
        }

        UO.Print("Outside the local quiet period");
        return null;
    }

    dynamic ClockInWindow(dynamic stamp, dynamic first, dynamic last)
    {
        if (Truth(first == last))
        {
            return false;
        }

        if (Truth(first < last))
        {
            return Truth(stamp >= first) && Truth(stamp < last);
        }

        return Truth(stamp >= first) || Truth(stamp < last);
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.Time() — UO.Time()

Parameter: Keine Parameter.

Ergebnis: int / Integer.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

public int Time()

        {

            var now = timeSource.Now;

            return now.Hour * 10000 + now.Minute * 100 + now.Second;

        }

UO.Timer

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

int UO.Timer();

Liest die Laufzeit der aktuellen Laufzeit in Zehntelsekunden. Geeignet für Ihre eigenen Verzögerungen und Aktionsmarken.

Parameter

Es gibt keine Parameter.

Rückgabewert

int 0..2147483647; Einheit ist 100 ms. Bei 399 ms wird 3 zurückgegeben. Dies ist der Uhrstand, nicht true/false und nicht die verbleibende Ladung.

Verhalten

  • Es gibt keine Parameter, keine Formulare mit Argumenten. Leere Klammern geben nur die Zeit an: Der Anruf wartet nicht, startet keinen Timer und sendet keine Pakete an das Spiel.
  • Der Ursprung gehört zu dieser Laufzeitinstanz. Eine neu laufende Prozedur erhält möglicherweise einen neuen Takt; Sie können Werte aus verschiedenen Läufen nicht vergleichen oder als absolutes Datum speichern. Während UO.Wait und einer Skriptpause tickt die Echtzeit weiter.
  • Der Bruchteil der Zehntel wird verworfen. Nach etwa 2485.5 Tagen erreicht die Zahl 2147483647 und bleibt dort, ohne zu überlaufen.
  • Dies ist Ihre Verzögerung, keine serverseitige Abklingzeit einer Fertigkeit/eines Zaubers oder eine Erfolgsbestätigung. Mit dem Befehl können Sie Serverbeschränkungen für Bewegung, Zauber oder Skripte nicht umgehen.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

var result = UO.Timer();
UO.Print("Timer: " + Convert.ToString(result));

1. Messen Sie die Dauer einer Operation – direktes Skript

Parameter und Ablauf:

  • WaitAsync(250) fordert 250 ms an; Die tatsächliche Verzögerung kann länger sein. Die Differenz zwischen den beiden Markierungen wird durch 10.0 dividiert, um die Sekunden zu erhalten. Anzeigeschritt UO.Timer - 100 ms.
var started = UO.Timer();
await Delay(250);
var elapsed = UO.Timer() - started;
var seconds = elapsed / 10.0;
UO.Print("Elapsed seconds: " + Convert.ToString(seconds));

Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));

2. Warten auf ein bereits angefordertes Fadenkreuz auf drei Sekunden beschränken – Skriptfunktion

Parameter und Ablauf:

  • Der Grenzwert 30 wird in Einheiten dieser Funktion angegeben. UO.Wait(50) gibt die Ausführung zwischen den Prüfungen frei. UO.Targeting liest das Vorhandensein einer Sehenswürdigkeit; Beispiel wirft oder zielt nicht. Wenn das Visier nicht erscheint, endet der Zyklus.
  • Eine zusätzliche Überprüfung des oberen Grenzwerts beendet die Wartezeit, auch wenn der Zähler am Grenzwert int stehen geblieben ist. Der Oszilloskopstatus wird wiederholt gelesen und kann sich zwischen den Lesungen ändern.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var started = UO.Timer();
    while (Truth(UO.Timer() - started < 30) && !(Truth(UO.Targeting())))
    {
        if (Truth(UO.Timer() >= 2147483647))
        {
            break;
        }

        await Delay(50);
    }

    if (Truth(UO.Targeting()))
    {
        UO.Print("Target cursor available");
    }
    else
    {
        UO.Print("Target wait ended");
    }

    return null;
}

Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Benutzerdefinierte Wiederholungsintervallfunktion – Skriptklasse

Parameter und Ablauf:

  • IntervalPassed(gestartet, aktuell, Intervall) ist vollständig unter Main definiert. Intervall=5 – eine halbe Sekunde in Einheiten dieser Uhr. Negatives Intervall, Umkehrung und int an der Obergrenze ergeben false; Das exakte Erreichen des Intervalls ergibt true.
  • Dies ist Ihre Verzögerung, keine serverseitige Abklingzeit einer Fertigkeit/eines Zaubers oder eine Erfolgsbestätigung. Mit dem Befehl können Sie Serverbeschränkungen für Bewegung, Zauber oder Skripte nicht umgehen.
return await new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenarioAsync();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

    async public Task<object?> RunScenarioAsync()
    {
        var started = UO.Timer();
        await Delay(500);
        var ready = IntervalPassed(started, UO.Timer(), 5);
        if (Truth(ready))
        {
            UO.Print("Local retry interval passed");
        }

        return null;
    }

    dynamic IntervalPassed(dynamic started, dynamic current, dynamic interval)
    {
        if (Truth(interval < 0) || Truth(current < started))
        {
            return false;
        }

        if (Truth(current >= 2147483647))
        {
            return false;
        }

        return current - started >= interval;
    }

    Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.Timer() — UO.Timer()

Parameter: Keine Parameter.

Ergebnis: int / Integer.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

public int Timer() => (int)Math.Max(0d, Math.Min(int.MaxValue, timeSource.SinceStart.TotalMilliseconds / 100d));

UO.Wait

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

void UO.Wait(object? waitTimeMS);

Hält das aktuelle Skript für die angegebene Anzahl von Millisekunden an. Nützlich zwischen wiederholten Statusprüfungen, um zu verhindern, dass das Skript in einer Endlosschleife ausgeführt wird.

Parameter

  • waitTimeMS – Ganzzahlige Zeit in Millisekunden: 1000 = eine Sekunde. Verwenden Sie 0..2147483647. Hierbei handelt es sich nicht um die Anzahl der Schritte, nicht um die Sekunden und nicht um das Zeitlimit für die Serverbestätigung.

Rückgabewert

void - kein Ergebnis. Rufen Sie auf einer separaten Leitung an. Das Ende der Verzögerung bedeutet nicht, dass sich das Objekt bewegt hat, der Zauber abgeschlossen ist oder die Verbindung hergestellt wurde: Prüfen Sie den gewünschten Zustand separat.

Verhalten

  • Null erzeugt keine wirkliche Verzögerung und eignet sich nicht als Pause in einer schnellen Schleife. Negative Zeit bedeutet nicht Unendlichkeit: UO.Wait reduziert sie auf 0; UO.Wait/sleep kann es mit aktiven Rückrufen ablehnen, und in der Client-Bridge ohne diese wird es nicht warten. Verwenden Sie für ein portables Skript nur nicht negative Zeiten.

Beispiel .csx

UO.Wait(100);
// For an asynchronous script, use the host helper:
await WaitAsync(100);

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Der Befehl steht in einer eigenen Anweisung. Die Meldung davor zeigt den Beginn des Aufrufs und bestätigt keine Serveraktion.

UO.Print("Calling UO.Wait");
UO.Wait(250);

1. UO.Wait – 1 – direktes Skript

Parameter und Ablauf:

  • 250 – Viertelsekunde. Nach dem Warten wird die nächste Zeile ausgeführt; Die Meldung „Verzögerung abgeschlossen“ ist der Text des Beispiels, nicht das zurückgegebene Ergebnis.
UO.Wait(250);
UO.Print("Delay complete");

2. UO.Wait — 2 — Skriptfunktion

Parameter und Ablauf:

  • WaitForOnline ist in diesem Skript vollständig deklariert. Das Argument 20 bedeutet maximal zwanzig Pausen von 250 ms. Die Verbindung wird vor Pausen und nach der letzten erneut überprüft. Der Helfer gibt den Zustand Connected (1/0) zurück; Der Wartebefehl selbst gibt nichts zurück und stellt keine Verbindung zum Server her.
return  RunScenario();
 object? RunScenario()
{
    return WaitForOnline(20);
    return null;
}

dynamic WaitForOnline(dynamic checks)
{
    while (Truth(checks > 0))
    {
        if (Truth(UO.Connected()))
        {
            return 1;
        }

        UO.Wait(250);
        checks = checks - 1;
    }

    return UO.Connected();
}

bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. UO.Wait – 3 – Szenarioklasse

Parameter und Ablauf:

  • Die Schleife führt genau drei Gewichtsmessungen durch. Zwischen den Messwerten gibt es zwei Pausen von 500 ms, nach der letzten gibt es keine Pause. Beim ersten Lesen und bei einer Gewichtsänderung wird eine Meldung ausgedruckt. Die vorherige Variable speichert den zu vergleichenden Wert, anstatt die Spielgewichtung anzupassen.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        var previous = -1;
        var checks = 0;
        while (Truth(checks < 3))
        {
            var weight = UO.Weight();
            if (Truth(weight != previous))
            {
                UO.Print("Weight: " + Convert.ToString(weight));
                previous = weight;
            }

            checks = checks + 1;
            if (Truth(checks < 3))
            {
                UO.Wait(500);
            }
        }

        return null;
    }

    bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.Wait(waitTimeMS) — UO.Wait(Any)

Parameter: waitTimeMS (Any)

Ergebnis: void / Unit.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

public async Task WaitAsync(int milliseconds)
    {
        ArgumentOutOfRangeException.ThrowIfNegative(milliseconds);
        Checkpoint();
        // Short slices allow Pause to suspend further script progress promptly.
        int remaining = milliseconds;
        while (remaining > 0)
        {
            int slice = Math.Min(remaining, 25);
            await Task.Delay(slice, Cancellation).ConfigureAwait(false);
            Checkpoint(); remaining -= slice;
        }
    }

Interner Implementierungscode; kein eigenständiges Skript.

case "wait": WaitWithEvents(Arg(0)); return InjectionValue.Unit;

UO.Waiting

Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어

C#-Signaturen

int UO.Waiting();

Prüft, ob vorbereitete Antworten in der Zielwarteschlange verbleiben.

Parameter

Es gibt keine Parameter.

Rückgabewert

int 1 – es liegt ein nicht aufgehobenes aufgeschobenes Ziel eines Objekts, einer Kachel oder eine Aufhebung der nächsten Sicht vor; 0 – Warteschlange ist leer. Es liegt daran, dass der Cursor nicht geöffnet ist. Verwenden Sie für den Cursor TargetPresent/Targeting.

Das Ergebnis des Befehls ist ein numerisches Flag: 1 bedeutet eine erfüllte Bedingung, 0 bedeutet eine nicht erfüllte Bedingung. Nach var result = command(...) prüfen, ob (result != 0) oder if (result == 0). Speichern Sie das Ergebnis eines Aufrufs: Ein wiederholter Aufruf kann die Aktion erneut ausführen oder den Status lesen, der sich bereits geändert hat.

Verhalten

  • Die gesamte Warteschlange des Clients wird gelesen. Wenn mehrere Prozeduren gleichzeitig laufen, werden die Reaktionen jedes einzelnen berücksichtigt.
  • Null bedeutet nur, dass keine Antwort aussteht. Es bestätigt nicht den erfolgreichen Einsatz einer Fertigkeit oder eines Zaubers auf dem Server.

Eigenständige C#-Skripte

Jedes Beispiel kann als separate Datei .csx gespeichert und in IDE ausgeführt werden. Die UO-Objekt- und Wartefunktionen stellen den Host der aktuellen Spielsitzung bereit. Ersetzen Sie Demo-serial-Namen, Koordinaten und Adressen durch Ihre eigenen.

Einfaches Beispiel

Führe diesen Code als eigene .csx-Datei aus. Die Argumente stehen direkt im Aufruf; ersetze Beispielnamen, Serials und Adressen durch eigene Werte.

Das Ergebnis eines Aufrufs wird im Journal ausgegeben. Zahlen werden nicht in bool umgewandelt; bei Arrays wird die Anzahl der Elemente angezeigt.

var result = UO.Waiting();
UO.Print("Waiting: " + Convert.ToString(result));

1. Vorbereitung prüfen – Direktskript

Parameter und Ablauf:

  • Nach WaitTargetSelf und vor dem Serverziel 1 wird erwartet.
  • CancelWaitTarget löscht die Warteschlange; Der nächste Test ergibt 0.
UO.WaitTargetSelf();
UO.Print(Convert.ToString(UO.Waiting()));
UO.CancelWaitTarget();

2. Warten Sie, bis die Antwort ausgegeben wird – Skriptfunktion

Parameter und Ablauf:

  • Die Prüfung hat keine Parameter. UO.Wait=50 ms, maximale 20 Erwartungen.
  • Bleibt die Antwort bestehen, wird sie abgebrochen. Fügen Sie separat eine Prüfung für das Ergebnis der Serveraktion hinzu.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var attempts = 0;
    while (Truth(UO.Waiting()) && Truth(attempts < 20))
    {
        await Delay(50);
        attempts = attempts + 1;
    }

    if (Truth(UO.Waiting()))
    {
        UO.CancelWaitTarget();
    }

    return null;
}

Task Delay(object? milliseconds) => WaitAsync(checked((int)Convert.ToDouble(milliseconds)));
bool Truth(object? value) => value is bool flag ? flag : value is string text ? !string.IsNullOrEmpty(text) : value != null && Convert.ToDouble(value) != 0;

3. Unterschied zwischen Warteschlange und Sicht anzeigen – Skriptklasse

Parameter und Ablauf:

  • Die erste Zeile zeigt die verzögerten Reaktionen, die zweite den Sehzustand.
  • Eine Warteschlange ohne Cursor und ein Cursor ohne Warteschlange sind möglich; diese Werte sind nicht austauschbar.
return  new ScriptScenario(UO, WaitAsync, Args, Cancellation, Checkpoint).RunScenario();
class ScriptScenario
{
    private readonly global::ClassicUO.CSharp.CSharpGameApi UO;
    private readonly Func<int, Task> WaitAsync;
    private readonly string[] Args;
    private readonly CancellationToken Cancellation;
    private readonly Action Checkpoint;
    public ScriptScenario(global::ClassicUO.CSharp.CSharpGameApi api, Func<int, Task> wait, string[] args, CancellationToken cancellation, Action checkpoint)
    {
        UO = api;
        WaitAsync = wait;
        Args = args;
        Cancellation = cancellation;
        Checkpoint = checkpoint;
    }

     public object? RunScenario()
    {
        UO.Print("Queued: " + Convert.ToString(UO.Waiting()));
        UO.Print("Cursor: " + Convert.ToString(UO.TargetPresent()));
        return null;
    }
}

Implementierung des Befehls

C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.

UO.Waiting() — UO.Waiting()

Parameter: Keine Parameter.

Ergebnis: int / Integer.

Beim Aufruf:

Interner Implementierungscode; kein eigenständiges Skript.

public int Waiting() => bridge.GetWaitTargetQueue().Length > 0 ? 1 : 0;

Clone this wiki locally