Skip to content

JA UO Topic http

Codex edited this page Oct 12, 2026 · 4 revisions

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

HTTP

家 · C# · IDE · UO API · A–Z · 例 · Languages

HTTP - クエリと応答の読み取り。ステータスコード、ヘッダー、レスポンスボディは別のデータです。

セクション

トピック コマンドと説明
HTTP_Get UO.HTTP_Get
HTTP_Post UO.HTTP_Post
HTTP_Header UO.HTTP_Header
HTTP_Body UO.HTTP_Body
外部メッセージ UO.Messenger - Telegram、Discord、Viber

すべてのテーマコマンド

HTTP リクエスト

UO.HTTP_Get · UO.HTTP_Post · UO.HTTP_Header · UO.HTTP_Body

このトピックに関する例

各コマンド カードには、直接コード、関数、クラスなどのいくつかの独立したシナリオがあります。以下は厳選された短いシナリオです。制限と完全な分析がカードに含まれています。

UO.HTTP_Get

パラメータ、結果、およびすべてのシナリオ

UO.HTTP_Get("https://example.com/csharp-config.json");
try
{
    string body = Convert.ToString(UO.HTTP_Body()) ?? "";
    using (var document = System.Text.Json.JsonDocument.Parse(body))
    {
        if (document.RootElement.TryGetProperty("minMana", out var value) &&
            value.TryGetInt32(out int threshold) && threshold is >= 0 and <= 100)
            return threshold;
    }
}
catch (System.Text.Json.JsonException)
{
    UO.Print("Response is not a valid configuration; using the default.");
}
return 30;

UO.HTTP_Body

パラメータ、結果、およびすべてのシナリオ

UO.HTTP_Get("https://example.com/C#-permission");
var permission = TrimText(UO.HTTP_Body());
return Truth(permission == "allow");

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

string TrimText(object? value) => (Convert.ToString(value) ?? "").Trim();

コマンドの完全なリファレンス


UO.HTTP_Body

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

C# のシグネチャ

dynamic UO.HTTP_Body();

このスクリプトの最後の HTTP 応答のテキストを読み取ります。たとえば、HTTP_Get の後、設定を使用して JSON を解析したり、サービスの応答を予期される文字列と比較したりできます。読み取り自体はネットワークに送信されません。

引数

パラメータはありません。

戻り値

string — 保存されたテキスト。このランタイムの最初のリクエストの前、ストリームの GET の後、およびネットワーク エラーの後 - 空の行。通常の回答には、HTTP 204 など、空の本文もあります。納期の指標として結果を true/false と比較しないでください。

動作

  • 最後の応答は、スクリプトの現在のランタイムにのみ保存されます。このランタイムの次の GET/POST がこれを置き換えます。同時に実行されている他のスクリプトでは変更されません。回答はプロフィールに保存されません。次のリクエスト以降に必要な場合は、ボディとヘッダーを事前に変数にコピーしてください。
  • GET/POST 実行中のスクリプト スレッドでの応答を待ちます。本文のリクエストと読み取りにかかる合計時間は 20 秒です。スクリプトを停止すると待機がキャンセルされます。 HTTP_Body/HTTP_Header 何も期待しません。 FileStream が転送された場合でも、ボディ全体がメモリにロードされます。これは、大きなファイルのストリーミング ダウンロードではありません。
  • テキストは、応答の文字セットに従って、エンコードが存在しない/不明である - UTF-8 でデコードされます。答え HTTP 4xx/5xx も読み込まれます。ネットワーク エラーまたはタイムアウトが発生すると、クライアントはエラーを書き込み、本文とヘッダーが空になります。 Try/Catch は、予期される応答のチェックに代わるものではありません。スクリプトキャンセルはさらに延長されます。ローカル ファイルの書き込みまたは無効な引数エラーは、Try/Catch によってキャッチできます。
  • HTTP_Body は最後のバッファのみを読み取ります。要求を繰り返したり、応答をクリアしたり、別のスクリプトからデータを返したりすることはありません。バイナリ GET の後には、このテキスト バッファではなく、MemoryStream.ToArray() または保存されたファイルを使用します。

単独で実行できる C# スクリプト

各サンプルは個別のファイル .csx として保存し、IDE で実行できます。 UO オブジェクトと待機関数は、現在のゲーム セッションのホストを提供します。デモの serial の名前、座標、アドレスを自分のものに置き換えます。

簡単な例

このコードを独立した .csx ファイルとして実行します。引数は呼び出しに直接記載されています。例の名前、serial、アドレスを自分の値に置き換えてください。

1 回の呼び出し結果をジャーナルに表示します。数値は bool に変換されません。配列の場合は要素数を表示します。

UO.HTTP_Get("https://example.com/");
object? result = UO.HTTP_Body();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1。予期されるテキストを含むアクションのみを許可 - 直接スクリプト

引数と実行の流れ:

  • サービスは許可を返す必要があります。空のものも含め、別の答えは false になります。この例では解像度を計算するだけです。移動や戦闘を引き起こしません。
  • example.com のアドレスは例示的なものであり、そのようなサービスを提供するものではありません。それらを自分のものに置き換えてください。この例を実行すると、実際の HTTP クエリが作成されます。この例では、ゲーム アクションは実行されません。
UO.HTTP_Get("https://example.com/C#-permission");
var permission = TrimText(UO.HTTP_Body());
return Truth(permission == "allow");

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

string TrimText(object? value) => (Convert.ToString(value) ?? "").Trim();

2。 2 つの回答から説明を収集 - スクリプト機能

引数と実行の流れ:

  • まずルート名が保存され、次に説明が要求されます。 routeName がなければ、2 番目の GET が最初の答えを置き換えます。
  • example.com のアドレスは例示的なものであり、そのようなサービスを提供するものではありません。それらを自分のものに置き換えてください。この例を実行すると、実際の HTTP クエリが作成されます。この例では、ゲーム アクションは実行されません。
return  RunScenario();
 object? RunScenario()
{
    UO.HTTP_Get("https://example.com/route-name");
    var routeName = UO.HTTP_Body();
    UO.HTTP_Get("https://example.com/route-description");
    return routeName + ": " + UO.HTTP_Body();
    return null;
}

3。バイナリ ストリームをテキスト バッファから分離する - スクリプト クラス

引数と実行の流れ:

  • GET と System.IO.MemoryStream の後は、バイトがストリーム内にあり、HTTP_Body は空です。このルールは、二者択一の正解にも適用されます。空のテキストはバイトがないことを意味しません。
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()
    {
        using (var data = new System.IO.MemoryStream())
        {
            UO.HTTP_Get("https://example.com/route-data.bin", data);
            string body = Convert.ToString(UO.HTTP_Body()) ?? "";
            UO.Print($"Binary bytes: {data.Length}; text-body characters: {body.Length}");
            return body;
        }

        return null;
    }
}

コマンドの実装

C# は大文字と小文字を区別します。正確な UO 名を使用してください。数値フラグは 0 と比較し、戻り値が bool の場合だけ bool を使います。

UO.HTTP_Body() — UO.HTTP_Body()

引数: 引数はありません。

結果: dynamic / Any.

呼び出し時:

内部実装のコードです。単独のスクリプトとして実行できません。

case "http_body": return new InjectionValue(httpBody);

UO.HTTP_Get

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

C# のシグネチャ

void UO.HTTP_Get(object? url);
void UO.HTTP_Get(object? url, object? lStream);

HTTP/HTTPS にデータをロードします。サービスからの設定の読み取りまたはファイルの受信に適しています。ゲーム接続を管理したり、ダウンロードしたコードを実行したりしません。

引数

  • url - 必須 string: 完全なアドレス http:// または https://. example.com をサービスのアドレスに置き換えます。このリクエストにはゲームとゲームサーバーは必要ありません。ゲーム プロキシ プロファイルではなく、プロセスの通常のネットワーク接続が使用されます。
  • lStream はオプションの標準です。NET System.IO.Stream、書き込み可能: たとえば、new System.IO.MemoryStream() または System.IO.File.Create(path)。これを使用しない場合、または 0/null を使用すると、テキストは HTTP_Body() となります。スレッドは元のバイトを受け取ります。シーク可能なストリームの場合、前のコンテンツはゼロにリセットされ、書き込みの前後の位置は 0 になります。シーク不可能なスレッドは、現在位置への書き込みを受け取ります。 File.Create 経由で FileStream を作成すると、ファイルはすぐに無効になります。親ディレクトリが存在する必要があります。不適切な引数または読み取り専用ストリームは、リクエストの前に拒否されます。

戻り値

void - 戻り値はありません。別の回線で電話してください。結果をbool、ID、またはバイト数として使用することはできません。通常のリクエスト後のテキストは HTTP_Body() によって読み取られ、送信されたストリームからバイナリ データが読み取られます。

動作

  • 最後の応答は、スクリプトの現在のランタイムにのみ保存されます。このランタイムの次の GET/POST がこれを置き換えます。同時に実行されている他のスクリプトでは変更されません。回答はプロフィールに保存されません。次のリクエスト以降に必要な場合は、ボディとヘッダーを事前に変数にコピーしてください。
  • GET/POST 実行中のスクリプト スレッドでの応答を待ちます。本文のリクエストと読み取りにかかる合計時間は 20 秒です。スクリプトを停止すると待機がキャンセルされます。 HTTP_Body/HTTP_Header 何も期待しません。 FileStream が転送された場合でも、ボディ全体がメモリにロードされます。これは、大きなファイルのストリーミング ダウンロードではありません。
  • テキストは、応答の文字セットに従って、エンコードが存在しない/不明である - UTF-8 でデコードされます。答え HTTP 4xx/5xx も読み込まれます。ネットワーク エラーまたはタイムアウトが発生すると、クライアントはエラーを書き込み、本文とヘッダーが空になります。 Try/Catch は、予期される応答のチェックに代わるものではありません。スクリプトキャンセルはさらに延長されます。ローカル ファイルの書き込みまたは無効な引数エラーは、Try/Catch によってキャッチできます。
  • GET スレッドなしではテキストと見出しが更新されます。 GET はストリームを使用してバイトを書き込み、HTTP_Body をクリアしてヘッダーを保存します。空の応答/ネットワーク エラーでも、ストリームの内容は空のデータに置き換えられます。古いファイルを保存するには、まず MemoryStream にダウンロードしてデータを確認します。

単独で実行できる C# スクリプト

各サンプルは個別のファイル .csx として保存し、IDE で実行できます。 UO オブジェクトと待機関数は、現在のゲーム セッションのホストを提供します。デモの serial の名前、座標、アドレスを自分のものに置き換えます。

簡単な例

このコードを独立した .csx ファイルとして実行します。引数は呼び出しに直接記載されています。例の名前、serial、アドレスを自分の値に置き換えてください。

コマンドは独立した文です。直前のメッセージは呼び出しの開始を示し、サーバーの動作完了を確認するものではありません。

UO.Print("Calling UO.HTTP_Get");
UO.HTTP_Get("https://example.com/");

1。範囲チェック付きのJSON構成の読み取り - 直接スクリプト

引数と実行の流れ:

  • example.com - デモ アドレス;それをあなたのものと交換してください。 System.Text.Json は応答本文を読み取り、0 から 100 までの整数 minMana のみを受け入れます。空/無効な JSON の場合、デフォルト値 30 が与えられます。
UO.HTTP_Get("https://example.com/csharp-config.json");
try
{
    string body = Convert.ToString(UO.HTTP_Body()) ?? "";
    using (var document = System.Text.Json.JsonDocument.Parse(body))
    {
        if (document.RootElement.TryGetProperty("minMana", out var value) &&
            value.TryGetInt32(out int threshold) && threshold is >= 0 and <= 100)
            return threshold;
    }
}
catch (System.Text.Json.JsonException)
{
    UO.Print("Response is not a valid configuration; using the default.");
}
return 30;

2。ファイルを保存する前にバイナリバイトをチェック - スクリプト関数

引数と実行の流れ:

  • 標準の System.IO.MemoryStream が送信されます。応答の元のバイトを受け取ります。 HTTP_Body が空になります。既存の download.bin は、空ではないデータを受信した後にのみ置き換えられます。長さをチェックしても、内容が正しいことは証明されません。
return  RunScenario();
 object? RunScenario()
{
    using (var data = new System.IO.MemoryStream())
    {
        UO.HTTP_Get("https://example.com/route-data.bin", data);
        if (data.Length == 0)
        {
            UO.Print("The response is empty; no file was written.");
            return false;
        }

        System.IO.File.WriteAllBytes("download.bin", data.ToArray());
        return true;
    }

    return null;
}

3。バイナリ応答を FileStream - スクリプト クラスに直接ダウンロードします。

引数と実行の流れ:

  • System.IO.File.Create はファイルを作成するか、すぐに null にします。 GET は元のバイトを書き込みます。応答が空の場合、ファイルは空のままになります。以前のバージョンを保存するには、まず前のスクリプトと同様に MemoryStream を使用します。を使用するとストリームが閉じられます。
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()
    {
        using (var output = System.IO.File.Create("http-download.bin"))
        {
            UO.HTTP_Get("https://example.com/route-data.bin", output);
        }

        return UO.HTTP_Header();
        return null;
    }
}

コマンドの実装

C# は大文字と小文字を区別します。正確な UO 名を使用してください。数値フラグは 0 と比較し、戻り値が bool の場合だけ bool を使います。

UO.HTTP_Get(url) — UO.HTTP_Get(Any)

引数: url (Any)

結果: void / Unit.

呼び出し時:

内部実装のコードです。単独のスクリプトとして実行できません。

case "http_get":

                {

                    bool hasStream = arguments.Length > 1

                        && !(arguments[1].Kind == InjectionValueKind.Integer && arguments[1].Integer == 0)

                        && arguments[1].Kind != InjectionValueKind.Unit;

                    // Validate before network side effects and before changing the last response.

                    if (hasStream && !(arguments[1].Object is MemoryStreamObject))

                        throw new NativeSubrutineException("UO.HTTP_Get: LStream must be a writable System.IO.Stream, 0, or omitted.");



                    string[] response = bridge.HttpRequest("GET", Text(0), string.Empty);

                    httpHeader = response.Length > 1 ? response[1] : string.Empty;

                    httpBody = hasStream ? string.Empty : response.Length > 0 ? response[0] : string.Empty;

                    if (!hasStream)

                    {

                        return InjectionValue.Unit;

                    }



                    byte[] raw = response.Length > 3 && !string.IsNullOrEmpty(response[3])

                        ? Convert.FromBase64String(response[3])

                        : Array.Empty<byte>();

                    if (arguments[1].Object is MemoryStreamObject memoryStream)

                        memoryStream.ReplaceBytes(raw);

                    else

                        throw new NativeSubrutineException("UO.HTTP_Get: LStream must be a writable System.IO.Stream.");



                    // Stream overloads keep the response as bytes, not cached text.

                    return InjectionValue.Unit;

                }

UO.HTTP_Get(url, lStream) — UO.HTTP_Get(Any,Any)

引数: url (Any), lStream (Any)

結果: void / Unit.

呼び出し時:

内部実装のコードです。単独のスクリプトとして実行できません。

if (name == "HTTP_Get" && arguments.Length == 2 && arguments[1] is Stream stream)
            {
                if (!stream.CanWrite) throw new ArgumentException("HTTP_Get requires a writable .NET stream.");
                // Adapt the existing binary response path without fetching the
                // response twice or converting its bytes through text encoding.
                var type = typeof(InjectionValue).Assembly.GetType("InjectionScript.Runtime.ObjectTypes.MemoryStreamObject", throwOnError: true)!;
                using var native = (IDisposable)Activator.CreateInstance(type, nonPublic: true)!;
                value = Invoke(name, [arguments[0], native]);
                var bytes = (InjectionValue)type.GetMethod("ToArray")!.Invoke(native, null)!;
                byte[] payload = bytes.Array.Select(item => checked((byte)item.Integer)).ToArray();
                if (stream.CanSeek) { stream.SetLength(0); stream.Position = 0; }
                stream.Write(payload);
                if (stream.CanSeek) stream.Position = 0;
            }
            else value = Invoke(name, arguments);

内部実装のコードです。単独のスクリプトとして実行できません。

case "http_get":

                {

                    bool hasStream = arguments.Length > 1

                        && !(arguments[1].Kind == InjectionValueKind.Integer && arguments[1].Integer == 0)

                        && arguments[1].Kind != InjectionValueKind.Unit;

                    // Validate before network side effects and before changing the last response.

                    if (hasStream && !(arguments[1].Object is MemoryStreamObject))

                        throw new NativeSubrutineException("UO.HTTP_Get: LStream must be a writable System.IO.Stream, 0, or omitted.");



                    string[] response = bridge.HttpRequest("GET", Text(0), string.Empty);

                    httpHeader = response.Length > 1 ? response[1] : string.Empty;

                    httpBody = hasStream ? string.Empty : response.Length > 0 ? response[0] : string.Empty;

                    if (!hasStream)

                    {

                        return InjectionValue.Unit;

                    }



                    byte[] raw = response.Length > 3 && !string.IsNullOrEmpty(response[3])

                        ? Convert.FromBase64String(response[3])

                        : Array.Empty<byte>();

                    if (arguments[1].Object is MemoryStreamObject memoryStream)

                        memoryStream.ReplaceBytes(raw);

                    else

                        throw new NativeSubrutineException("UO.HTTP_Get: LStream must be a writable System.IO.Stream.");



                    // Stream overloads keep the response as bytes, not cached text.

                    return InjectionValue.Unit;

                }

UO.HTTP_Header

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

C# のシグネチャ

dynamic UO.HTTP_Header();

このスクリプトの最後の HTTP 応答のヘッダー (Content-Type など) を読み取り、宣言されたデータ形式を調べます。これは、応答本文、要求ヘッダー、または数値コード HTTP ではありません。

引数

パラメータはありません。

戻り値

string — CRLF で区切られた、名前: 値の形式の文字列。最初のリクエストの前とネットワーク エラーの後 - 空の行。 HTTP/1.1 200 OK の行はここにはありません。ステータス コードは別個のコマンドでは表されません。名前の順序と大文字小文字は保証されません。

動作

  • 最後の応答は、スクリプトの現在のランタイムにのみ保存されます。このランタイムの次の GET/POST がこれを置き換えます。同時に実行されている他のスクリプトでは変更されません。回答はプロフィールに保存されません。次のリクエスト以降に必要な場合は、ボディとヘッダーを事前に変数にコピーしてください。
  • GET/POST 実行中のスクリプト スレッドでの応答を待ちます。本文のリクエストと読み取りにかかる合計時間は 20 秒です。スクリプトを停止すると待機がキャンセルされます。 HTTP_Body/HTTP_Header 何も期待しません。 FileStream が転送された場合でも、ボディ全体がメモリにロードされます。これは、大きなファイルのストリーミング ダウンロードではありません。
  • テキストは、応答の文字セットに従って、エンコードが存在しない/不明である - UTF-8 でデコードされます。答え HTTP 4xx/5xx も読み込まれます。ネットワーク エラーまたはタイムアウトが発生すると、クライアントはエラーを書き込み、本文とヘッダーが空になります。 Try/Catch は、予期される応答のチェックに代わるものではありません。スクリプトキャンセルはさらに延長されます。ローカル ファイルの書き込みまたは無効な引数エラーは、Try/Catch によってキャッチできます。
  • HTTP_Header は、応答のヘッダーとそのコンテンツを結合します。バイナリ GET 以降も使用できます。名前は、大文字と小文字を区別しない方法でチェックする必要があります。 Content-Type はサーバー ステートメントであり、コンテンツ チェックではありません。ダウンロードしたテキストをコードとして実行しないでください。

単独で実行できる C# スクリプト

各サンプルは個別のファイル .csx として保存し、IDE で実行できます。 UO オブジェクトと待機関数は、現在のゲーム セッションのホストを提供します。デモの serial の名前、座標、アドレスを自分のものに置き換えます。

簡単な例

このコードを独立した .csx ファイルとして実行します。引数は呼び出しに直接記載されています。例の名前、serial、アドレスを自分の値に置き換えてください。

1 回の呼び出し結果をジャーナルに表示します。数値は bool に変換されません。配列の場合は要素数を表示します。

UO.HTTP_Get("https://example.com/");
object? result = UO.HTTP_Header();
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1。大文字と小文字を区別せずに応答ヘッダーを読み取る - 直接スクリプト

引数と実行の流れ:

  • 見出しは行ごとに解析されます。 Content-Type 名は大文字と小文字を区別せずに比較されます。文字列がない場合は、空の文字列が返されます。
UO.HTTP_Get("https://example.com/csharp-status");
return ReadHeader(Convert.ToString(UO.HTTP_Header()) ?? "", "Content-Type");

string ReadHeader(string headers, string name)
{
    foreach (string line in headers.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries))
    {
        int separator = line.IndexOf(':');
        if (separator > 0 && line[..separator].Trim().Equals(name, StringComparison.OrdinalIgnoreCase))
            return line[(separator + 1)..].Trim();
    }
    return "";
}

2。宣言されたチェックJSON Content-Type - スクリプト関数

引数と実行の流れ:

  • ローカルに保存されたヘッダー テキストがチェックされます。 Content-Type 自体は JSON の正確さを保証しません。 System.Text.Json の内容を別途確認してください。
return  RunScenario();
 object? RunScenario()
{
    UO.HTTP_Get("https://example.com/csharp-status");
    string headers = Convert.ToString(UO.HTTP_Header()) ?? "";
    return headers.Contains("application/json", StringComparison.OrdinalIgnoreCase);
    return null;
}

3。バイナリ応答ヘッダーの保存 - スクリプト クラス

引数と実行の流れ:

  • GET は、ソースバイトを System.IO.MemoryStream に転送します。最後の応答ヘッダーは依然として HTTP_Header です。このフォームのテキスト HTTP_Body が空です。ヘッダーのみがファイルに保存されます。
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()
    {
        using (var data = new System.IO.MemoryStream())
        {
            UO.HTTP_Get("https://example.com/route-data.bin", data);
            string headers = Convert.ToString(UO.HTTP_Header()) ?? "";
            System.IO.File.WriteAllText("http-response-headers.txt", headers);
            UO.Print($"Saved response headers; downloaded {data.Length} binary bytes.");
            return headers;
        }

        return null;
    }
}

コマンドの実装

C# は大文字と小文字を区別します。正確な UO 名を使用してください。数値フラグは 0 と比較し、戻り値が bool の場合だけ bool を使います。

UO.HTTP_Header() — UO.HTTP_Header()

引数: 引数はありません。

結果: dynamic / Any.

呼び出し時:

内部実装のコードです。単独のスクリプトとして実行できません。

case "http_header": return new InjectionValue(httpHeader);

UO.HTTP_Post

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

C# のシグネチャ

dynamic UO.HTTP_Post(object? url, object? postData);

POST メソッドを使用してテキストを HTTP サービスに送信し、応答テキストを返します。たとえば、スクリプトでルートの停止を報告できます。これは既成の Telegram/Discord コマンドではありません。プロトコル、認証、およびリクエスト形式は個別のサポートが必要です。

引数

  • url - 必須 string: 完全なアドレス http:// または https://. example.com をサービスのアドレスに置き換えます。このリクエストにはゲームとゲームサーバーは必要ありません。ゲーム プロキシ プロファイルではなく、プロセスの通常のネットワーク接続が使用されます。
  • postData — リクエスト本文を持つ必須の string。 Content-Type: text/plain で UTF-8 によって送信されました。 charset=utf-8。フォームの自動エンコードや application/json への切り替えは行われません。 System.Text.Json.JsonSerializer.Serialize はテキストのみを生成します。サンプルサーバーは JSON を text/plain として正確に受け入れる必要があります。これらのコマンドを使用してカスタム ヘッダーを構成することはできません。

戻り値

string — 応答テキスト。 HTTP_Body() からもアクセスできます。これはbool ではなく、コード HTTP でもありません。空の文字列はエラーを示しませんが、空でない文字列はサーバー上の操作の成功を示しません。

動作

  • 最後の応答は、スクリプトの現在のランタイムにのみ保存されます。このランタイムの次の GET/POST がこれを置き換えます。同時に実行されている他のスクリプトでは変更されません。回答はプロフィールに保存されません。次のリクエスト以降に必要な場合は、ボディとヘッダーを事前に変数にコピーしてください。
  • GET/POST 実行中のスクリプト スレッドでの応答を待ちます。本文のリクエストと読み取りにかかる合計時間は 20 秒です。スクリプトを停止すると待機がキャンセルされます。 HTTP_Body/HTTP_Header 何も期待しません。 FileStream が転送された場合でも、ボディ全体がメモリにロードされます。これは、大きなファイルのストリーミング ダウンロードではありません。
  • テキストは、応答の文字セットに従って、エンコードが存在しない/不明である - UTF-8 でデコードされます。答え HTTP 4xx/5xx も読み込まれます。ネットワーク エラーまたはタイムアウトが発生すると、クライアントはエラーを書き込み、本文とヘッダーが空になります。 Try/Catch は、予期される応答のチェックに代わるものではありません。スクリプトキャンセルはさらに延長されます。ローカル ファイルの書き込みまたは無効な引数エラーは、Try/Catch によってキャッチできます。
  • POST は本文とヘッダーを更新し、同じ本文を文字列として返します。応答が空だからといって、POST を自動的に繰り返さないでください。サーバーがすでにアクションを実行している可能性があります。例の承認済み/ステータス チェックはサービスとの合意であり、HTTP 成功の組み込みの兆候ではありません。

単独で実行できる C# スクリプト

各サンプルは個別のファイル .csx として保存し、IDE で実行できます。 UO オブジェクトと待機関数は、現在のゲーム セッションのホストを提供します。デモの serial の名前、座標、アドレスを自分のものに置き換えます。

簡単な例

このコードを独立した .csx ファイルとして実行します。引数は呼び出しに直接記載されています。例の名前、serial、アドレスを自分の値に置き換えてください。

1 回の呼び出し結果をジャーナルに表示します。数値は bool に変換されません。配列の場合は要素数を表示します。

object? result = UO.HTTP_Post("https://example.com/", "Hello from C#");
UO.Print(result is Array values ? "Count: " + values.Length : Convert.ToString(result));

1。サービスの合意された応答を確認する - 直接スクリプト

引数と実行の流れ:

  • サービスはテキスト「Route stop」を受け入れ、合意に基づいて「accepted」で応答します。 Main はこのテキストのみを含む true を返します。これはサービスのプロトコルのチェックであり、HTTP コードのチェックではありません。
  • example.com のアドレスは例示的なものであり、そのようなサービスを提供するものではありません。それらを自分のものに置き換えてください。この例を実行すると、実際の HTTP クエリが作成されます。この例では、ゲーム アクションは実行されません。
var reply = UO.HTTP_Post("https://example.com/C#-event", "Route stopped");
return Truth(TrimText(reply) == "accepted");

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

string TrimText(object? value) => (Convert.ToString(value) ?? "").Trim();

2。シリアル化された JSON を送信し、JSON 応答を解析する - スクリプト関数

引数と実行の流れ:

  • System.Text.Json.JsonSerializer は辞書文字列をエスケープします。ステータス値はJSONを確認した後に読み取られます。デモのアドレスを実際のアドレスに置き換えます。
return  RunScenario();
 object? RunScenario()
{
    var report = new Dictionary<string, string>
    {
        ["event"] = "route-stopped",
        ["text"] = "line one\nline two"
    };
    string payload = System.Text.Json.JsonSerializer.Serialize(report);
    string reply = Convert.ToString(UO.HTTP_Post("https://example.com/csharp-report", payload)) ?? "";
    try
    {
        using (var document = System.Text.Json.JsonDocument.Parse(reply))
        {
            return document.RootElement.TryGetProperty("status", out var value) ? value.GetString() : "unknown";
        }
    }
    catch (System.Text.Json.JsonException)
    {
        return "invalid response";
    }

    return null;
}

3。次のリクエストまで応答を保存 - スクリプト クラス

引数と実行の流れ:

  • firstReply と firstHeaders には答え POST が格納されます。後続の GET は内部バッファを置き換えますが、ローカル変数にはまだ最初の応答が含まれています。
  • example.com のアドレスは例示的なものであり、そのようなサービスを提供するものではありません。それらを自分のものに置き換えてください。この例を実行すると、実際の HTTP クエリが作成されます。この例では、ゲーム アクションは実行されません。
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 firstReply = UO.HTTP_Post("https://example.com/C#-event", "Route stopped");
        var firstHeaders = UO.HTTP_Header();
        UO.HTTP_Get("https://example.com/C#-status");
        return firstReply + "|" + firstHeaders;
        return null;
    }
}

コマンドの実装

C# は大文字と小文字を区別します。正確な UO 名を使用してください。数値フラグは 0 と比較し、戻り値が bool の場合だけ bool を使います。

UO.HTTP_Post(url, postData) — UO.HTTP_Post(Any,Any)

引数: url (Any), postData (Any)

結果: dynamic / Any.

呼び出し時:

内部実装のコードです。単独のスクリプトとして実行できません。

case "http_post":

                {

                    string[] response = bridge.HttpRequest("POST", Text(0), Text(1));

                    httpBody = response.Length > 0 ? response[0] : string.Empty;

                    httpHeader = response.Length > 1 ? response[1] : string.Empty;

                    return new InjectionValue(httpBody);

                }

UO.Messenger

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

C# のシグネチャ

dynamic UO.Messenger(object? provider);

テキスト通知と Telegram、Discord、または Viber メッセージの受信用のオブジェクトを作成します。たとえば、スクリプトはリソース収集の終了を通知したり、事前に指定されたユーザーからの停止要求をチェックしたりできます。オブジェクトを作成してもボットにはまだ接続されておらず、何も送信されません。

引数

  • provider - string: 「テレグラム」、「ディスコード」、または「バイバー」;大文字と小文字は重要ではありません。それ以外の値ではエラーが発生します。

戻り値

オブジェクトMessenger。これはboolでもIDでもありません。このオブジェクトのID メッセージ、送信者、チャットは常に string: 文字列と比較され、Convert.ToInt32/Convert.ToDouble によって変換されません。

動作

  • Provider() → string; Connected() → 1/0 (true/false): プロバイダーと最後の認証チェックの結果。 Connected は、現時点でインターネットが利用できることを保証するものではありません。
  • Connect(token) → null: ボットトークンをチェックします。 ConnectFromFile(path) → null: UTF-8 トークンをファイルから最大 1024 バイトまで読み取ります。相対パスは、現在のスクリプト フォルダーから計算されます。再接続にはDisconnectが必要です。 Try/Catch でエラーをキャッチできます。
  • Disconnect() → null: ローカル受信を停止し、トークンとカーソルをクリアします。オブジェクトは再度接続できます。 Dispose() → null: オブジェクトを完全に閉じます。
  • SendMessage(text, recipient) → string: ID がメッセージを受信しました。パラメータ - テキストおよび文字列チャット ID Telegram、チャンネル ID Discord または ID Viber 加入者。長さ制限: それぞれ4096/2000/7000。 Viber JSON ≤30000 バイトも。空白のテキストは禁止されています。 Discord では、全員や役割についてのメンションは作成されません。
  • WatchChannel(channelId) → null: Discord、現在の最後のメッセージを記憶し、後続のメッセージのみを読み取ります。 WatchChannel(channelId, afterMessageId) → null: 指定された文字列 ID の後に始まります。 『0』には歴史が含まれています。オブジェクトあたり最大 32 チャンネル。
  • Receive(timeoutSeconds) → Array; Receive(): 0 タイムアウト。範囲 0..20 秒。空の配列は、利用可能なテキスト メッセージがないことを意味します。 Telegram は long ポーリングを使用し、Discord は選択されたチャネルをポーリングし、Viber は Webhook キューを読み取ります。ネットワーク要求には最大 30 秒かかる場合があります。
  • 各MessengerMessage: Id()、SenderId()、SenderName()、ChatId()、Text() → string。チャネルからの Telegram 投稿には SenderId が含まれない場合があります。ボットからの添付ファイル、テキスト以外のイベント、Discord メッセージは返されません。
  • RetryAfter() → int: サービスを制限した後に待機する秒数。この期間が終了するまで、新しい HTTP-リクエストは実行されません。失敗後の送信は自動的には繰り返されません。サーバーはすでにメッセージを受信して​​いる可能性があります。
  • StartReceiver(localPort, publicHttpsUrl) → int: Viber のみ。ポート 1..65535、ビジー状態のローカル ポートを返します。パブリック HTTPS アドレスは /viber/ で終わり、事前に元の本文と署名ヘッダーを付けて POST を 127.0.0.1:port/viber/ に転送する必要があります。このメソッドは、Webhook を Viber に登録します。
  • 個人アカウントのパスワードではなく、ボット トークンが必要です。既存の Webhook を含む Telegram は削除されずに拒否されます。 Discord にはチャンネルの読み取り/送信権限と、アクセス可能なテキストの MESSAGE_CONTENT が必要です。 Viber は登録ユーザーに送信します。
  • Receive は、スタック全体を解析した後でのみカーソルを保存します。 Telegram/Discord はリクエストごとに最大 100 エントリを返します。 call 後続のパケットを再度受信します。第 2 引数 WatchChannel を指定しない Discord は古い話をスキップします。
  • Viber はソース本体の HMAC-SHA256 をチェックします。キュー - 100 メッセージ、繰り返される ID は、最後の 2048 配信用に保存されます。オーバーフローにより、サービスによる再試行のために HTTP 503 が与えられます。 Content-Length を持つ HTTPS プロキシが必要です。ローカル入力のチャンク化されたリクエストは拒否されます。
  • トークンは、プロファイル、エラー テキスト、引数履歴 Connect には記録されません。デバッガに表示されるスクリプト変数に保存しないようにするには、ConnectFromFile を使用します。トークン ファイルを公開しないでください。
  • プロシージャ内にオブジェクトを作成します。同時に 32 を超えてはなりません。使用/破棄すると、より早く解放されます。スクリプトが完了、失敗、または停止すると、そのすべてのメッセンジャー オブジェクトが閉じられます。 Viber レシーバーを閉じても、Webhook はサービスから削除されません。
  • これはテキスト インターフェイスです。受信したテキストをコードとして実行したり、ゲーム アカウントを接続したりしません。送信者を信頼するための条件は、スクリプト自体によって設定されます。

単独で実行できる C# スクリプト

各サンプルは個別のファイル .csx として保存し、IDE で実行できます。 UO オブジェクトと待機関数は、現在のゲーム セッションのホストを提供します。デモの serial の名前、座標、アドレスを自分のものに置き換えます。

簡単な例

このコードを独立した .csx ファイルとして実行します。引数は呼び出しに直接記載されています。例の名前、serial、アドレスを自分の値に置き換えてください。

dynamic messenger = UO.Messenger("telegram");
UO.Print(messenger.Provider());
messenger.Dispose();

1。電報:作業完了後の通知 - ダイレクトスクリプト

引数と実行の流れ:

  • telegram-token.txt をスクリプトの横に配置し、12345678 をチャット ID に置き換えます。この例では、1 つの通知を送信し、文字列 ID を返します。サーバー応答を受信して​​も、人間による読み取りが確認されるわけではありません。
  • 独自のボット設定が必要です。例はローカル テストの回答を使用してテストされます。実際のユーザーには送信されませんでした。
var bot = UO.Messenger("telegram");
using (var resource = bot)
{
    bot.ConnectFromFile("telegram-token.txt");
    var messageId = bot.SendMessage("Harvest finished", "12345678");
    return messageId;
}

2。 Discord: 選択したユーザーからのリクエストを停止 - スクリプト機能

引数と実行の流れ:

  • チャンネルとID を許可する送信者を入力してください。 true は、この小切手が彼からテキスト ストップを受け取ったことを意味します。例自体は動きを止めるものではありません。この結果は、独自のデューティ サイクル条件で使用できます。
  • 独自のボット設定が必要です。例はローカル テストの回答を使用してテストされます。実際のユーザーには送信されませんでした。
return  RunScenario();
 object? RunScenario()
{
    var bot = UO.Messenger("discord");
    using (var resource = bot)
    {
        bot.ConnectFromFile("discord-token.txt");
        bot.WatchChannel("123456789012345678");
        var messages = bot.Receive(5);
        foreach (var message in messages)
        {
            if (Truth(message.SenderId() == "987654321098765432") && Truth(Convert.ToString(TrimText(message.Text())) == "stop"))
            {
                return true;
            }
        }

        return false;
    }

    return null;
}

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

3。 JSON ファイルから受信機設定をロード - スクリプト クラス

引数と実行の流れ:

  • System.Text.Json はローカル ポート/publicUrl を読み取ります。トークンは別のローカル ファイルに保存されます。この例では実際のディスパッチは実行されません。任意の受信テキストではなく、信頼できる SenderId がチェックされます。
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 settingsDocument = System.Text.Json.JsonDocument.Parse(System.IO.File.ReadAllText("viber-settings.json"));
        using (settingsDocument)
        {
            var settings = settingsDocument.RootElement;
            var bot = UO.Messenger("viber");
            using (var resource = bot)
            {
                bot.ConnectFromFile("viber-token.txt");
                bot.StartReceiver(settings.GetProperty("port").GetInt32(), settings.GetProperty("publicUrl").GetString());
                var messages = bot.Receive(5);
                foreach (var message in messages)
                {
                    if (Truth(message.SenderId() == "trusted-subscriber-id"))
                    {
                        return message.Text();
                    }
                }

                return "";
            }
        }

        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# は大文字と小文字を区別します。正確な UO 名を使用してください。数値フラグは 0 と比較し、戻り値が bool の場合だけ bool を使います。

UO.Messenger(provider) — UO.Messenger(String)

引数: provider (String)

結果: dynamic / Object.

呼び出し時:

内部実装のコードです。単独のスクリプトとして実行できません。

private InjectionObject CreateMessenger(string provider)
        {
            var owner=NativeScriptResourceScope.Current??throw new StatementFailedException("Create messenger objects inside an active C# script execution.");owner.Checkpoint();
            var client=MessengerFactory!=null?MessengerFactory(provider,()=>owner.Cancellation,owner.Checkpoint):new Messaging.MessengerClient(provider,()=>owner.Cancellation,owner.Checkpoint);
            var resource=new MessengerObject(client,owner.Forget,file=>Path.GetFullPath(Path.Combine(paths.ScriptPath??string.Empty,file)));owner.Track(resource);return resource;
        }

Clone this wiki locally