Repository navigation
DE UO Topic scripts runtime
Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
| 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 |
UO.StartScript · UO.StopScript · UO.StopAllScripts · UO.PauseResumeScript · UO.GetScriptName · UO.SetScriptName · UO.GetScriptPath · UO.GetScriptsCount · UO.GetScriptsList · UO.GetScriptState · UO.Exec · UO.Launch
UO.CallSub · UO.SubExists · UO.FunRunning · UO.Terminate · UO.TerminateAll · UO.SetEvent · UO.SetEventProc
UO.Wait · UO.Waiting · UO.Timer · UO.Time · UO.Date
UO.GetPauseScriptOnDisconnectStatus · UO.SetPauseScriptOnDisconnectStatus
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.
Parameter, Ergebnis und alle Szenarien
var indices = UO.GetScriptsList();
foreach (var index in indices)
{
UO.Print(Convert.ToString(index) + ": " + UO.GetScriptName(index));
}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;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
-
subrutineNameist der durch RegisterRoutine gegebene Stringname. Leerzeichen an den Rändern werden entfernt; Bei der Suche nach registrierten Namen wird die Groß-/Kleinschreibung nicht beachtet.
void – kein Ergebnis; Ein unbekannter Name CallSub verursacht einen Fehler und die erneute Ausführung eines bereits aktiven Namens wird übersprungen.
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.
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.
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.
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);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;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;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);
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: subrutineName (String)
Ergebnis: void / Unit.
Beim Aufruf:
-
ClassicUO.CSharp.CSharpCallbacks.TryInvoke. -
InjectionScript.Runtime.InjectionApiUO.CallSub. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.Exec:bridge.Exec(subrutineName).
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);Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
Es gibt keine Parameter.
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.
- 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.
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.
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));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);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;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;
}
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
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;
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
void UO.Exec(object? parameters);Führt einen Textspielbefehl aus oder führt einen registrierten C#-Delegaten oder eine geladene C#-Datei aus.
-
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.
void: kein Ergebnis. Die Rückgabe der Kontrolle bedeutet nicht das Ende des Starts oder die Bestätigung der Spielaktion durch den Server.
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.
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.
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.
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);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");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);
}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);
}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'");C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: parameters (String)
Ergebnis: void / Unit.
Beim Aufruf:
-
ClassicUO.CSharp.CSharpCallbacks.TryInvoke. -
InjectionScript.Runtime.InjectionRuntime.Exec. -
InjectionScript.Runtime.InjectionRuntime.Tokenize:Tokenize(parameters). -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.Exec:bridge.Exec(parts[1].Text). -
InjectionScript.Runtime.InjectionRuntime.TryHandleLegacyConsoleCommand:TryHandleLegacyConsoleCommand(command, rawArguments). -
InjectionScript.Runtime.InjectionRuntime.NormalizeConsoleAlias:NormalizeConsoleAlias(command). -
InjectionScript.Runtime.InjectionRuntime.IsRemainderTextCommand:IsRemainderTextCommand(command). -
InjectionScript.Runtime.InjectionRuntime.ToConsoleValue:ToConsoleValue(token.Text). -
InjectionScript.Runtime.InjectionRuntime.CallNativeSubrutine:CallNativeSubrutine(command, args).
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);
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
-
subrutineNameist der durch RegisterRoutine gegebene Stringname. Leerzeichen an den Rändern werden entfernt; Bei der Suche nach registrierten Namen wird die Groß-/Kleinschreibung nicht beachtet.
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.
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.
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.
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.
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);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);
}
}Parameter und Ablauf:
- Der asynchrone Delegat ändert den Shared Counter über
Interlocked. Nach FunRunning=0 wird das Ergebnis bisVolatilegelesen. 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;
}Parameter und Ablauf:
- Terminate wählt die registrierte Aufgabe der aktuellen Ausführung aus. Ich warte darauf, dass WaitAsync ihren Stornierungstoken verwendet.
finallyfü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);
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: subrutineName (String)
Ergebnis: int / Integer.
Beim Aufruf:
-
ClassicUO.CSharp.CSharpCallbacks.TryInvoke. -
InjectionScript.Runtime.InjectionApiUO.FunRunning. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.FunRunning:bridge.FunRunning(subrutineName).
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;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
dynamic UO.GetPauseScriptOnDisconnectStatus();Liest die Skriptpauseneinstellung, wenn der Manager deaktiviert ist.
Es gibt keine Parameter.
int 1 — PauseScriptsOnDisconnect aktiviert; 0 – deaktiviert.
- Liest das Manager-Flag, nicht die aktuelle Pause eines einzelnen Skripts. Der Anruf selbst wird weder pausiert noch fortgesetzt.
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.
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));Parameter und Ablauf:
- Der Wert beschreibt die Managereinstellung.
var enabled = UO.GetPauseScriptOnDisconnectStatus();
UO.Print(Convert.ToString(enabled));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;
}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)));
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: Keine Parameter.
Ergebnis: dynamic / Any.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetPauseScriptOnDisconnectStatus:bridge.GetPauseScriptOnDisconnectStatus().
Interner Implementierungscode; kein eigenständiges Skript.
case "getpausescriptondisconnectstatus": return new InjectionValue(bridge.GetPauseScriptOnDisconnectStatus());Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
string UO.GetScriptName(object? scriptIndex);Liest den Anzeigenamen des aktiven Laufs.
-
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.
string: Anzeigename oder „“, wenn kein Index vorhanden ist. Der Name eines vorhandenen Starts kann auch explizit auf die leere Zeichenfolge festgelegt werden.
- 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.
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.
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));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);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;
}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;
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: scriptIndex (Any)
Ergebnis: string / String.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetScriptName:bridge.GetScriptName(Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Interner Implementierungscode; kein eigenständiges Skript.
case "getscriptname": return new InjectionValue(bridge.GetScriptName(Arg(0)));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
string UO.GetScriptPath(object? scriptIndex);Liest den Pfad der aktiven Startquelldatei.
-
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.
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.
- 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.
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.
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));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;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;
}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;
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: scriptIndex (Any)
Ergebnis: string / String.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetScriptPath:bridge.GetScriptPath(Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Interner Implementierungscode; kein eigenständiges Skript.
case "getscriptpath": return new InjectionValue(bridge.GetScriptPath(Arg(0)));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.GetScriptState(object? scriptIndex);Liest den Ausführungsstatus nach Index.
-
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.
int – Statuscode: 0 = nein/unbekannt, 1 = läuft, 2 = Pause. Dies ist nicht bool: explizit mit 1 oder 2 vergleichen.
- 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.
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.
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));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);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;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;
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: scriptIndex (Any)
Ergebnis: int / Integer.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetScriptState:bridge.GetScriptState(Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Interner Implementierungscode; kein eigenständiges Skript.
case "getscriptstate": return new InjectionValue(bridge.GetScriptState(Arg(0)));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.GetScriptsCount();Zählt aktive Ausführungen in diesem Client.
Es gibt keine Parameter.
int >= 0: Anzahl der aktiven Läufe, einschließlich der pausierten. Dies ist eine Menge, nicht bool oder ein Skriptindex.
- 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.
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.
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));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));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)));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;
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: Keine Parameter.
Ergebnis: int / Integer.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetScriptsCount:bridge.GetScriptsCount().
Interner Implementierungscode; kein eigenständiges Skript.
case "getscriptscount": return new InjectionValue(bridge.GetScriptsCount());Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
dynamic UO.GetScriptsList();Gibt die aktuellen numerischen Skriptindizes zurück.
Es gibt keine Parameter.
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.
- 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.
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.
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));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));
}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;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;
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: Keine Parameter.
Ergebnis: dynamic / Array.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetScriptsList:bridge.GetScriptsList().
Interner Implementierungscode; kein eigenständiges Skript.
case "getscriptslist": return new InjectionValue(bridge.GetScriptsList().Select(value => new InjectionValue(value)).ToArray());Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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);-
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.
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.
- 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.
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.
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));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;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();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;
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: file (Any)
Ergebnis: int / Integer.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.Register [Launch]. -
InjectionScript.Runtime.InjectionApiUO.CompactLaunch:CompactLaunch(values).
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))Parameter: file (Any), parameters (Any)
Ergebnis: int / Integer.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.Register [Launch]. -
InjectionScript.Runtime.InjectionApiUO.CompactLaunch:CompactLaunch(values).
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))Parameter: file (Any), parameters (Any), workingDirectory (Any)
Ergebnis: int / Integer.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.Register [Launch]. -
InjectionScript.Runtime.InjectionApiUO.CompactLaunch:CompactLaunch(values).
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))Parameter: file (Any), parameters (Any), workingDirectory (Any), hidden (Any)
Ergebnis: int / Integer.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.Register [Launch]. -
InjectionScript.Runtime.InjectionApiUO.CompactLaunch:CompactLaunch(values).
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))Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
-
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.
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).
- 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.
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.
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; }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;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;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) ?? "");
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: scriptIndex (Any)
Ergebnis: void / Unit.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.PauseResumeScript:bridge.PauseResumeScript(Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Interner Implementierungscode; kein eigenständiges Skript.
case "pauseresumescript": bridge.PauseResumeScript(Arg(0)); return InjectionValue.Unit;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
-
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.
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.
- 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/
finallyfü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.
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.
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.
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);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;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;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);
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: name (Any), stateValue (Any)
Ergebnis: void / Unit.
Beim Aufruf:
-
ClassicUO.CSharp.CSharpCallbacks.TryInvoke. -
InjectionScript.Runtime.InjectionApiUO.SetEvent. -
InjectionScript.Runtime.InjectionApiUO.SetEvent:SetEvent(name, stateValue, InjectionValue.True, new InjectionValue(string.Empty)).
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));Parameter: name (Any), stateValue (Any), repeatOrHandler (Any)
Ergebnis: void / Unit.
Beim Aufruf:
-
ClassicUO.CSharp.CSharpCallbacks.TryInvoke. -
InjectionScript.Runtime.InjectionApiUO.SetEvent. -
InjectionScript.Runtime.InjectionValue.ToString:repeatOrHandler.ToString(). -
InjectionScript.Runtime.NumberConversions.TryStr2Int:NumberConversions.TryStr2Int(raw, out _). -
InjectionScript.Runtime.InjectionApiUO.SetEvent:SetEvent(name, stateValue, InjectionValue.True, repeatOrHandler).
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));
}Parameter: nameValue (Any), stateValue (Any), repeatValue (Any), subNameValue (Any)
Ergebnis: void / Unit.
Beim Aufruf:
-
ClassicUO.CSharp.CSharpCallbacks.TryInvoke. -
InjectionScript.Runtime.InjectionApiUO.SetEvent. -
InjectionScript.Runtime.InjectionApiUO.NormalizeLegacyEventName:NormalizeLegacyEventName(nameValue.ToString()). -
InjectionScript.Runtime.InjectionValue.ToString:nameValue.ToString(). -
InjectionScript.Runtime.NumberConversions.ToInt:NumberConversions.ToInt(stateValue). -
InjectionScript.Runtime.InjectionApiUO.IsSupportedLegacyEventName:IsSupportedLegacyEventName(name). -
InjectionScript.Runtime.InjectionApiUO.SystemMessage:SystemMessage($"SetEvent: unsupported event '{name}'. Supported: SeeNewPlayer, Death, ChangeHitPoints, ChangeMana, ChangeStamina."). -
InjectionScript.Runtime.InjectionApiUO.NormalizeLegacyEventHandler:NormalizeLegacyEventHandler(subNameValue.ToString()). -
InjectionScript.Runtime.InjectionApiUO.CaptureLegacyEventSnapshot:CaptureLegacyEventSnapshot(subscription).
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;
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
-
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.
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.
- 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/
finallyfü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.
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.
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.
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);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;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;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);
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: eventname (Any), procname (Any)
Ergebnis: void / Unit.
Beim Aufruf:
-
ClassicUO.CSharp.CSharpCallbacks.TryInvoke. -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Text:Text(1). -
InjectionScript.Runtime.InjectionApiUO.SetEvent:SetEvent(arguments[0], InjectionValue.False). -
InjectionScript.Runtime.InjectionApiUO.SetEvent:SetEvent(arguments[0], InjectionValue.True, InjectionValue.True, arguments[1]).
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;
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
void UO.SetPauseScriptOnDisconnectStatus(object? value);Ändert die Regel für Skripte, anzuhalten, wenn die Verbindung unterbrochen wird.
-
value- 0 schaltet sich aus; Jede Ganzzahl ungleich Null enthält.
void – kein Wert. Rufen Sie eine separate Leitung an; Der Abschluss bestätigt nicht die Aktion des Servers.
- 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.
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.
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);Parameter und Ablauf:
- Ändert die Regel für Skripte, anzuhalten, wenn die Verbindung unterbrochen wird.
UO.SetPauseScriptOnDisconnectStatus(1);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;
}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);
}
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: value (Any)
Ergebnis: void / Unit.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.SetPauseScriptOnDisconnectStatus:bridge.SetPauseScriptOnDisconnectStatus(Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Interner Implementierungscode; kein eigenständiges Skript.
case "setpausescriptondisconnectstatus": bridge.SetPauseScriptOnDisconnectStatus(Arg(0)); return InjectionValue.Unit;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
-
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.
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).
- 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.
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.
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; }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;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) ?? "");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;
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: scriptIndex (Any), value (Any)
Ergebnis: void / Unit.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.SetScriptName:bridge.SetScriptName(Arg(0), Text(1)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Text:Text(1).
Interner Implementierungscode; kein eigenständiges Skript.
case "setscriptname": bridge.SetScriptName(Arg(0), Text(1)); return InjectionValue.Unit;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.StartScript(object? scriptPath);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.
- 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.
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.
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));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;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;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;
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: scriptPath (Any)
Ergebnis: int / Integer.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.StartScript:bridge.StartScript(Text(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Text:Text(0).
Interner Implementierungscode; kein eigenständiges Skript.
case "startscript": return new InjectionValue(bridge.StartScript(Text(0)));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
void UO.StopAllScripts();Es gibt keine Parameter.
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).
- 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.
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.
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();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();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;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;
}
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: Keine Parameter.
Ergebnis: void / Unit.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.StopAllScripts:bridge.StopAllScripts().
Interner Implementierungscode; kein eigenständiges Skript.
case "stopallscripts": bridge.StopAllScripts(); return InjectionValue.Unit;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
-
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.
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).
- 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.
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.
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; }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;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;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) ?? "");
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: scriptIndex (Any)
Ergebnis: void / Unit.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.StopScript:bridge.StopScript(Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
Interner Implementierungscode; kein eigenständiges Skript.
case "stopscript": bridge.StopScript(Arg(0)); return InjectionValue.Unit;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
-
subrutineNameist der durch RegisterRoutine gegebene Stringname. Leerzeichen an den Rändern werden entfernt; Bei der Suche nach registrierten Namen wird die Groß-/Kleinschreibung nicht beachtet.
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.
- 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.
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.
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.
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"));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;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;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);
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: subrutineName (String)
Ergebnis: int / Integer.
Beim Aufruf:
-
ClassicUO.CSharp.CSharpCallbacks.TryInvoke. -
InjectionScript.Runtime.InjectionApiUO.SubExists. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.SubExists:bridge.SubExists(subrutineName).
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;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
void UO.Terminate();
void UO.Terminate(object? subrutineName);-
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 wieharvest.csx::Main. Ein lokaler Callback-Name wieHarvestfunktioniert erst nach einer ausdrücklichen Registrierung mitRegisterRoutine. Eine Datei besitzt einenMain-Einstieg; einzelne Klassenmethoden werden nicht automatisch separat startbare Prozeduren.
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.
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.
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.
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");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");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;
}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;
}
}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();
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: Keine Parameter.
Ergebnis: void / Unit.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.Terminate. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.Terminate:bridge.Terminate(string.Empty).
Interner Implementierungscode; kein eigenständiges Skript.
public void Terminate() => bridge.Terminate(string.Empty);Parameter: subrutineName (String)
Ergebnis: void / Unit.
Beim Aufruf:
-
ClassicUO.CSharp.CSharpCallbacks.TryInvoke. -
InjectionScript.Runtime.InjectionApiUO.Terminate. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.Terminate:bridge.Terminate(subrutineName).
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);Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
void UO.TerminateAll();Es gibt keine Parameter.
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.
- 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.
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.
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;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;
}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();
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: Keine Parameter.
Ergebnis: void / Unit.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.TerminateAll. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.Terminate:bridge.Terminate("all").
Interner Implementierungscode; kein eigenständiges Skript.
public void TerminateAll() => bridge.Terminate("all");Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
Es gibt keine Parameter.
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.
- 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.
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.
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));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));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;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;
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
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;
}Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.Timer();Liest die Laufzeit der aktuellen Laufzeit in Zehntelsekunden. Geeignet für Ihre eigenen Verzögerungen und Aktionsmarken.
Es gibt keine Parameter.
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.
- 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.
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.
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));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)));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;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;
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
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));Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
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.
-
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.
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.
- 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.
UO.Wait(100);
// For an asynchronous script, use the host helper:
await WaitAsync(100);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.
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);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");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;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;
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: waitTimeMS (Any)
Ergebnis: void / Unit.
Beim Aufruf:
-
ClassicUO.CSharp.CSharpScriptGlobals.WaitAsync. -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility. -
InjectionScript.Runtime.InjectionApiUO.WaitWithEvents:WaitWithEvents(Arg(0)). -
InjectionScript.Runtime.InjectionApiUO.ExecuteClientApiCompatibility::Arg:Arg(0).
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;Українська · Русский · English · Deutsch · Français · Italiano · Español · 繁體中文 · 日本語 · 한국어
int UO.Waiting();Prüft, ob vorbereitete Antworten in der Zielwarteschlange verbleiben.
Es gibt keine Parameter.
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.
- 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.
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.
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));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();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;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;
}
}C# unterscheidet Groß- und Kleinschreibung. Verwenden Sie den genauen UO-Namen. Numerische Flags mit 0 vergleichen; bool nur bei Rückgabetyp bool verwenden.
Parameter: Keine Parameter.
Ergebnis: int / Integer.
Beim Aufruf:
-
InjectionScript.Runtime.InjectionApiUO.Waiting. -
ClassicUO.Game.Managers.ClassicUOInjectionApiBridge.GetWaitTargetQueue:bridge.GetWaitTargetQueue().
Interner Implementierungscode; kein eigenständiges Skript.
public int Waiting() => bridge.GetWaitTargetQueue().Length > 0 ? 1 : 0;ClassicUO — Bad Newbie & C# Scripts IDE