Skip to content

KO 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 · 예 · 언어

HTTP-질의 및 응답 읽기. 상태 코드, 헤더, 응답 본문은 별도의 데이터입니다.

섹션

주제 명령 및 설명
HTTP_Get UO.HTTP_Get
HTTP_Post UO.HTTP_Post
HTTP_Header UO.HTTP_Header
HTTP_Body UO.HTTP_Body
외부 메시지 UO.Messenger - 텔레그램, 디스코드, 바이버

모든 테마 명령

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, 주소를 자신의 값으로 바꾸세요.

한 번의 호출 결과를 저널에 표시합니다. 숫자를 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. 두 가지 답변에서 설명 수집 - 스크립트 기능

매개변수와 실행 흐름:

  • 먼저 경로 이름이 저장된 다음 설명이 요청됩니다. routeName가 없으면 두 번째 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. 텍스트 버퍼에서 바이너리 스트림 분리 - 스크립트 클래스

매개변수와 실행 흐름:

  • System.IO.MemoryStream의 GET 이후에는 바이트가 스트림에 있고 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, 쓰기 가능: 예를 들어 새로운 System.IO.MemoryStream() 또는 System.IO.File.Create(경로)입니다. 그것이 없거나 0/null를 사용하면 텍스트는 HTTP_Body()가 됩니다. 스레드는 원본 바이트를 받습니다. 검색 가능한 스트림의 경우 이전 콘텐츠는 0으로 재설정되고 쓰기 전후의 위치는 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. 파일을 저장하기 전에 바이너리 바이트를 확인하세요 - 스크립트 기능

매개변수와 실행 흐름:

  • 표준 시스템.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, 주소를 자신의 값으로 바꾸세요.

한 번의 호출 결과를 저널에 표시합니다. 숫자를 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입니다. UTF-8에서 콘텐츠 유형: text/plain; 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, 주소를 자신의 값으로 바꾸세요.

한 번의 호출 결과를 저널에 표시합니다. 숫자를 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 중지됨 텍스트를 수락하고 동의에 따라 수락됨으로 응답합니다. 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: 파일에서 최대 1024 바이트까지 UTF-8 토큰을 읽습니다. 상대 경로는 현재 스크립트 폴더에서 계산됩니다. 다시 연결하려면 Disconnect가 필요합니다. Try/Catch를 통해 오류를 포착할 수 있습니다.
  • Disconnect() → null: 로컬 수신을 중지하고 토큰과 커서를 지웁니다. 개체를 다시 연결할 수 있습니다. Dispose() → null: 개체를 완전히 닫습니다.
  • SendMessage(text, recipient) → string: ID 메시지를 받았습니다. 매개변수 - 텍스트 및 문자열 채팅 ID 텔레그램, 채널 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는 웹훅 대기열을 읽습니다. 네트워크 요청에는 최대 30초가 소요될 수 있습니다.
  • 각 MessengerMessage: Id(), SenderId(), SenderName(), ChatId(), Text() → string. 채널의 텔레그램 게시물에는 SenderId이 없을 수 있습니다. 첨부 파일, 텍스트가 아닌 이벤트, 봇의 Discord 메시지는 반환되지 않습니다.
  • RetryAfter() → int: 서비스 제한 후 대기 시간(초)입니다. 이 기간이 만료되기 전에는 새로운 HTTP 요청이 실행되지 않습니다. 실패 후 전송은 자동으로 반복되지 않습니다. 서버가 이미 메시지를 받았을 수도 있습니다.
  • StartReceiver(localPort, publicHttpsUrl) → int: Viber 전용; port 1..65535, 사용 중인 로컬 포트를 반환합니다. 공개 HTTPS-주소는 /viber/로 끝나고 미리 원래 본문과 서명 헤더를 사용하여 POST를 127.0.0.1:port/viber/로 전달해야 합니다. 이 메서드는 Viber에 웹훅을 등록합니다.
  • 개인 계정 비밀번호가 아닌 봇 토큰이 필요합니다. 기존 웹훅이 있는 텔레그램은 제거하지 않고 거부됩니다. Discord에는 채널 읽기/전송 권한이 필요하며 액세스 가능한 텍스트를 위해서는 MESSAGE_CONTENT가 필요합니다. Viber는 구독한 사용자에게 보냅니다.
  • 수신은 전체 스택을 구문 분석한 후에만 커서를 저장합니다. Telegram/Discord는 요청당 최대 100 항목을 반환합니다. 후속 패킷에 대해 다시 수신을 호출하십시오. 두 번째 논쟁이 없는 불일치 WatchChannel는 이전 이야기를 건너뜁니다.
  • Viber는 소스 본문의 HMAC-SHA256을 확인합니다. 대기열 - 100 메시지, 반복되는 ID는 마지막 2048 전달에 대해 저장됩니다. 오버플로는 서비스별 재시도를 위해 HTTP 503를 제공합니다. Content-Length가 있는 HTTPS 프록시가 필요합니다. 로컬 입력에 대한 청크 요청은 거부됩니다.
  • 토큰은 Connect 프로필, 오류 텍스트 또는 인수 기록에 기록되지 않습니다. 디버거에 표시되는 스크립트 변수에 저장하지 않으려면 ConnectFromFile를 사용하세요. 토큰 파일을 게시하지 마십시오.
  • 프로시저 내부에 개체를 만듭니다. 동시에 32 이하; /Dispose를 사용하면 더 일찍 해제됩니다. 스크립트가 완료되거나 실패하거나 중지되면 모든 메신저 개체가 닫힙니다. Viber 수신기를 닫아도 서비스에서 웹훅이 삭제되지는 않습니다.
  • 이것은 텍스트 인터페이스입니다. 수신된 텍스트를 코드로 실행하지 않으며 게임 계정을 연결하지 않습니다. 보낸 사람을 신뢰하기 위한 조건은 스크립트 자체에서 설정됩니다.

독립 실행 C# 스크립트

각 예제는 별도의 파일 .csx로 저장하고 IDE에서 실행할 수 있습니다. UO 개체와 대기 기능은 현재 게임 세션의 호스트를 제공합니다. 데모 serial 이름, 좌표, 주소를 자신의 것으로 바꾸세요.

간단한 예제

이 코드를 별도의 .csx 파일로 실행하세요. 인수는 호출에 직접 표시됩니다. 예제의 이름, serial, 주소를 자신의 값으로 바꾸세요.

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

1. 텔레그램: 작업 완료 후 알림 - 직접 스크립트

매개변수와 실행 흐름:

  • telegram-token.txt를 스크립트 옆에 놓고 12345678를 채팅 ID로 바꾸세요. 이 예에서는 하나의 알림을 보내고 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