KO UO Topic client connection - LIHACHTETAN/ClassicUO-Bad-Newbie-CSharp-Scripts-IDE GitHub Wiki

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

ํด๋ผ์ด์–ธํŠธ ๋ฐ ์—ฐ๊ฒฐ

ํ™ˆ ยท C# ยท IDE ยท UO API ยท Aโ€“Z ยท ์˜ˆ ยท ์–ธ์–ด

์—ฐ๊ฒฐ, ์›”๋“œ ์ž…์žฅ ์ƒํƒœ, ๋Œ€๊ธฐ ์‹œ๊ฐ„, ์„œ๋ฒ„ ์ฃผ์†Œ ๋ฐ ์บ๋ฆญํ„ฐ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

์„น์…˜

์ฃผ์ œ ๋ช…๋ น ๋ฐ ์„ค๋ช…
Connect UO.Connect
Disconnect UO.Disconnect
Connected UO.Connected
Online UO.Online
Ping UO.GetPing
Server IP UO.GameServerIPString
Shard Name UO.ShardName
Shard Path UO.ShardPath
์บ๋ฆญํ„ฐ ๋ชฉ๋ก UO.GetCharsListForShard
Resend UO.Resend
CheckLag UO.CheckLag

๋ชจ๋“  ํ…Œ๋งˆ ๋ช…๋ น

์—ฐ๊ฒฐ

UO.Connect ยท UO.Disconnect ยท UO.Connected ยท UO.Online ยท UO.IsOnline ยท UO.ConnectedTime ยท UO.DisconnectedTime ยท UO.GetPing ยท UO.CheckLag ยท UO.GameServerIPString ยท UO.ShardName ยท UO.ShardPath ยท UO.GetCharsListForShard ยท UO.Resend ยท UO.CloseUO

์ฃผ์ œ์— ๋Œ€ํ•œ ์˜ˆ

๊ฐ ๋ช…๋ น ์นด๋“œ์—๋Š” ์ง์ ‘ ์ฝ”๋“œ, ํ•จ์ˆ˜ ๋ฐ ํด๋ž˜์Šค ๋“ฑ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋…๋ฆฝ์ ์ธ ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์„ ํƒ๋œ ์งง์€ ์‹œ๋‚˜๋ฆฌ์˜ค์ž…๋‹ˆ๋‹ค. ์ œํ•œ์‚ฌํ•ญ๊ณผ ์ „์ฒด ๋ถ„์„์ด ์นด๋“œ์— ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

UO.Connected

๋งค๊ฐœ๋ณ€์ˆ˜, ๊ฒฐ๊ณผ ๋ฐ ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค

if (Truth(Truth(UO.Connected()) == false))
{
    return null;
}
UO.UseSkill("Hiding");

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

UO.GameServerIPString

๋งค๊ฐœ๋ณ€์ˆ˜, ๊ฒฐ๊ณผ ๋ฐ ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค

var address = UO.GameServerIPString();
UO.Print(address);

์ „์ฒด ๋ช…๋ น ์ฐธ์กฐ


UO.CheckLag

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

int UO.CheckLag();
dynamic UO.CheckLag(object? timeoutMS);
int UO.CheckLag(object? timeout, object? retries);

ํ• ๋‹น๋œ ์‹œ๊ฐ„ ๋‚ด์— ๊ฒŒ์ž„ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ƒˆ๋กœ์šด ์‘๋‹ต์„ ๋ฐ›์•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ์ง€์—ฐ ํ›„ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ณ„์†ํ•˜๊ธฐ ์ „์— ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

  • timeout - ์‹œ๊ฐ„ ์ดˆ๊ณผ / timeoutMS - ํ•œ ๋ฒˆ์˜ ์‹œ๋„์— ๋Œ€ํ•œ ๋Œ€๊ธฐ ์‹œ๊ฐ„(๋ฐ€๋ฆฌ์ดˆ)์œผ๋กœ, int๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. ์Œ์ˆ˜ ๊ฐ’์€ 0์œผ๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. 0๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์š”์ฒญ์ด ์ „์†ก๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์‘๋‹ต์„ ๊ธฐ๋Œ€ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋ฌดํ•œ์ • ํƒ€์ž„์•„์›ƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.
  • timeoutMS - ์‹œ๊ฐ„ ์ดˆ๊ณผ / timeoutMS - ํ•œ ๋ฒˆ์˜ ์‹œ๋„์— ๋Œ€ํ•œ ๋Œ€๊ธฐ ์‹œ๊ฐ„(๋ฐ€๋ฆฌ์ดˆ)์œผ๋กœ, int๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. ์Œ์ˆ˜ ๊ฐ’์€ 0์œผ๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. 0๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์š”์ฒญ์ด ์ „์†ก๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์‘๋‹ต์„ ๊ธฐ๋Œ€ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋ฌดํ•œ์ • ํƒ€์ž„์•„์›ƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.
  • retries - ์žฌ์‹œ๋„ - ์ถ”๊ฐ€ ๋ฐ˜๋ณต ํšŸ์ˆ˜๊ฐ€ ์•„๋‹Œ ์ด ์‹œ๋„ ํšŸ์ˆ˜์ž…๋‹ˆ๋‹ค. int๋กœ ๋ณ€ํ™˜๋˜๋ฉฐ ์•„๋ž˜๋Š” 1๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด (250, 3) - 250ms์—์„œ ์ตœ๋Œ€ 3๋ฒˆ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ์„ฑ๊ณต์ ์ธ ์‘๋‹ต์€ ๊ฒ€์‚ฌ๋ฅผ ์กฐ๊ธฐ์— ์™„๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

์ˆซ์ž ํ”Œ๋ž˜๊ทธ int: 1 (์กฐ๊ฑด ์ถฉ์กฑ) - ์ƒˆ๋กœ์šด ์‘๋‹ต์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. 0 (์กฐ๊ฑด ๋ฏธ์ถฉ์กฑ) - ์š”์ฒญ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฑฐ๋‚˜ ์ œํ•œ ์‹œ๊ฐ„์ด ๋งŒ๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ผ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋“ฑ๋ก object? ์‹ค์ œ๋กœ๋Š” ์ด๊ฒƒ์„ int๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ•‘ ๊ฐ’์ด๋‚˜ ์‹œ๋„ ํšŸ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

๋™์ž‘

  • CheckLag()๋Š” ํ•œ ๋ฒˆ ์‹œ๋„ํ•˜๊ณ  ์ตœ๋Œ€ 10000ms ๋™์•ˆ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. CheckLag(timeoutMS) - ์ง€์ •๋œ ๊ธฐ๋Œ€์น˜๋ฅผ ๊ฐ€์ง€๊ณ  ํ•œ ๋ฒˆ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. CheckLag(timeout, retries)๋Š” ์„ฑ๊ณตํ•˜๊ฑฐ๋‚˜ ์ด ์‹œ๋„ ํšŸ์ˆ˜๊ฐ€ ์†Œ์ง„๋  ๋•Œ๊นŒ์ง€ ํ™•์ธ์„ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.
  • ๊ธฐ๋‹ค๋ฆฌ๋ฉด ๊ฒŒ์ž„ ๋™์ž‘์„ ํ™•์ธํ•˜๋Š” ๋Œ€์‹  ํ˜ธ์ถœ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ง€์—ฐ๋ฉ๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์€ ๋‹ค์‹œ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์œผ๋ฉฐ ๋„คํŠธ์›Œํฌ ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„๊ฐ€ ์—์ฝ”์— ์‘๋‹ตํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹คํŒจ ์ž์ฒด๋กœ๋Š” ์—ฐ๊ฒฐ์ด ๋Š์–ด์กŒ๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํƒ€์ด๋ฐ์€ ํ๋ฆ„ ์ผ์ •์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ๋ชจ๋“  ํ”„๋ ˆ์ž„์—์„œ ํ™œ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”. ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ค‘์ง€ํ•˜๋ฉด ๋Œ€๊ธฐ๊ฐ€ ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค.
  • UO.GetPing ยท UO.CheckLag ยท UO.IsOnline

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €๋„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ bool๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฐ์—ด์ด๋ฉด ์š”์†Œ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

1. CheckLag - 1 - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†๋Š” ์–‘์‹์€ ์ตœ๋Œ€ 10์ดˆ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. true๋Š” ์ƒˆ๋กœ์šด ์—์ฝ” ์‘๋‹ต์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ˆจ๊ธฐ๊ธฐ๋Š” ๋ณ„๋„์˜ ๋ช…๋ น์œผ๋กœ ํ˜ธ์ถœ๋˜๋ฉฐ ๊ฒŒ์ž„ ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ์˜ํ•ด ๋ฌด์‹œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
if (Truth(Truth(UO.CheckLag()) == true))
{
    UO.UseSkill("Hiding");
}
else
{
    UO.Print("No fresh server response");
}

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

2. CheckLag โ€” 2 โ€” ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • 250 โ€” ํ•œ ๋ฒˆ์˜ ์‹œ๋„๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ค‘, 3 โ€” ์ด ์‹œ๋„ ํšŸ์ˆ˜. ์„ฑ๊ณตํ•˜๋ฉด ๋” ์ด์ƒ ์‹œ๋„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. 0๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๊ณ„์†๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” 250 ms ํ•‘ ์ธก์ •์ด๋‚˜ ์„ธ ๋ฒˆ์˜ ์ถ”๊ฐ€ ๋ฐ˜๋ณต์ด ์•„๋‹™๋‹ˆ๋‹ค.
return  RunScenario();
 object? RunScenario()
{
    var responsive = UO.CheckLag(250, 3);
    if (Truth(responsive == 0))
    {
        UO.Print("No response after the allowed attempts");
        return null;
    }

    UO.Print("Fresh response received; the script can continue");
    return null;
}

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

3. CheckLag - 3 - ์‹œ๋‚˜๋ฆฌ์˜ค ์ˆ˜์—…

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • CanContinue(timeoutMs, ์‹œ๋„)๋Š” ๋จผ์ € UO.IsOnline๋ฅผ ํ™•์ธํ•œ ๋‹ค์Œ ์ตœ์‹  ๋‹ต๋ณ€์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. false ๋ฐ 0๋Š” ์ด ์ˆ ์–ด์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. 500 ms ๋ฐ 2 ์‹œ๋„๋Š” ๋ณ„๋„๋กœ ์ง€์ •๋ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
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(CanContinue(500, 2))))
        {
            return null;
        }

        UO.UseSkill("Hiding");
        return null;
    }

    dynamic CanContinue(dynamic timeoutMs, dynamic attempts)
    {
        if (Truth(Truth(UO.IsOnline()) == false))
        {
            return false;
        }

        return Truth(Truth(UO.CheckLag(timeoutMs, attempts)) == true);
    }

    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.CheckLag() โ€” UO.CheckLag()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: int / Integer.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

public int CheckLag() => bridge.CheckLag(10_000);

UO.CheckLag(timeoutMS) โ€” UO.CheckLag(Any)

๋งค๊ฐœ๋ณ€์ˆ˜: timeoutMS (Any)

๊ฒฐ๊ณผ: dynamic / Any.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "checklag": return new InjectionValue(bridge.CheckLag(Arg(0, 10_000)));

UO.CheckLag(timeout, retries) โ€” UO.CheckLag(Any,Any)

๋งค๊ฐœ๋ณ€์ˆ˜: timeout (Any), retries (Any)

๊ฒฐ๊ณผ: int / Integer.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

public int CheckLag(InjectionValue timeout, InjectionValue retries)

        {

            int timeoutMs = Math.Max(0, NumberConversions.ToInt(timeout));

            int attempts = Math.Max(1, NumberConversions.ToInt(retries));

            for (int attempt = 0; attempt < attempts; attempt++)

            {

                if (bridge.CheckLag(timeoutMs) != 0)

                    return 1;

            }

            return 0;

        }

UO.CloseUO

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

void UO.CloseUO();

Client.Game.Exit๋ฅผ ํ†ตํ•ด ํ˜„์žฌ ํด๋ผ์ด์–ธํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ข…๋ฃŒํ•˜๋„๋ก ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

void - ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—†์Šต๋‹ˆ๋‹ค.

๋™์ž‘

  • CloseUO์€ ๊ฐ™์€ ๋‹ค๋ฆฌ๋กœ ํ–ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. CloseHandle. ์ข…๋ฃŒ๋Š” ๊ฒŒ์ž„ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. Client.Game์ด ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ ์•„๋ฌด๋Ÿฐ ์กฐ์น˜๋„ ์ทจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์€ ๋ณ„๋„์˜ ๊ฒ€ํ”„๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๋ช…๋ น์€ ๋…๋ฆฝ๋œ ๋ฌธ์ž…๋‹ˆ๋‹ค. ์•ž์˜ ๋ฉ”์‹œ์ง€๋Š” ํ˜ธ์ถœ ์‹œ์ž‘์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ ์„œ๋ฒ„ ๋™์ž‘์˜ ์™„๋ฃŒ๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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

1. ํด๋ผ์ด์–ธํŠธ ์ข…๋ฃŒ - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ํ˜ธ์ถœ์€ ํด๋ผ์ด์–ธํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ข…๋ฃŒ๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
UO.CloseUO();

2. ๋ช…์‹œ์  ์ข…๋ฃŒ ์กฐ๊ฑด - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ์ด ์˜ˆ์—์„œ๋Š” ์ œ์–ด๋œ ์กฐ๊ฑด์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. 0 ๊ฐ’์€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์—ด๋ฆฐ ์ƒํƒœ๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
return  RunScenario();
 object? RunScenario()
{
    var finishClient = 0;
    if (Truth(finishClient))
    {
        UO.CloseUO();
    }

    return null;
}

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

3. ์™„๋ฃŒ ์ ˆ์ฐจ - ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ์™„์ „ํžˆ ์„ ์–ธ๋œ ๋„์šฐ๋ฏธ๋Š” ๋ช…์‹œ์ ์ธ ์ข…๋ฃŒ ํ™œ์„ฑํ™”๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.
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()
    {
        FinishClient(0);
        return null;
    }

    void FinishClient(dynamic enabled)
    {
        if (Truth(enabled))
        {
            UO.CloseUO();
        }
    }

    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.CloseUO() โ€” UO.CloseUO()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: void / Unit.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "closeuo": bridge.CloseHandle(); break;

UO.Connect

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

void UO.Connect();

ํ˜„์žฌ ํด๋ผ์ด์–ธํŠธ ์„ธ์…˜์˜ ์—ฐ๊ฒฐ ๋˜๋Š” ์žฌ์—ฐ๊ฒฐ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

void - ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—†์Šต๋‹ˆ๋‹ค.

๋™์ž‘

  • ๊ด€๋ฆฌ์ž ์„ธ์…˜์—์„œ SessionControl.RequestConnect์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๋…๋ฆฝ ์‹คํ–‰ํ˜• ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ํ™œ์„ฑ/์ค€๋น„๋œ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.
  • GameScene์˜ ๊ฒฝ์šฐ ์—…๋ฐ์ดํŠธ ์ค‘์— ์žฅ๋ฉด์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋„๋ก ์ €์žฅ๋œ ์žฌ์ ‘์†์„ ๊ณ„ํšํ•ฉ๋‹ˆ๋‹ค. LoginScene๋Š” ํ˜„์žฌ ๊ณ„์ •๊ณผ ์ €์žฅ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Reconnect๋ฅผ ์ผœ๊ณ  ์ž๋™ ์žฌ์—ฐ๊ฒฐ์ด ๊บผ์ง„ ๊ฒฝ์šฐ์—๋„ ๊ธฐ์–ต๋œ ์ƒค๋“œ/์บ๋ฆญํ„ฐ๋กœ Connect๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  • ํŒ€์€ ์„ธ์ƒ์— ๋“ค์–ด๊ฐ€๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ์ž‘์—…์— ์—ฐ๊ฒฐ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ณ„๋„์˜ ๋Œ€๊ธฐ ํ›„ UO.Connected๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๋ช…๋ น์€ ๋…๋ฆฝ๋œ ๋ฌธ์ž…๋‹ˆ๋‹ค. ์•ž์˜ ๋ฉ”์‹œ์ง€๋Š” ํ˜ธ์ถœ ์‹œ์ž‘์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ ์„œ๋ฒ„ ๋™์ž‘์˜ ์™„๋ฃŒ๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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

1. ์—ฐ๊ฒฐ - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ํ˜ธ์ถœ์€ ์—ฐ๊ฒฐ์„ ์‹œ์ž‘ํ•˜๊ธฐ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.
UO.Connect();

2. ์—ฐ๊ฒฐ์ด ์—†์„ ๋•Œ ์—ฐ๊ฒฐ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ๊ฒ€์ฆ์„ ํ†ตํ•ด ์žฌ์š”์ฒญ์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
return  RunScenario();
 object? RunScenario()
{
    if (!(Truth(UO.Connected())))
    {
        UO.Connect();
    }

    return null;
}

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

3. ๋‚˜์ค‘์— ์ƒํƒœ ํ™•์ธ - ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • 1000ms๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค๊ณ  ํ•ด์„œ ์ง„์ž…์ด ๋ณด์žฅ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ถœ๋ ฅ์—๋Š” ์‹ค์ œ ํ˜„์žฌ ํ”Œ๋ž˜๊ทธ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
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()
    {
        UO.Connect();
        await Delay(1000);
        UO.Print(Convert.ToString(UO.Connected()));
        return null;
    }

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

๋ช…๋ น ๊ตฌํ˜„

C#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.Connect() โ€” UO.Connect()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: void / Unit.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "connect": bridge.ConnectClient(); return InjectionValue.Unit;

UO.Connected

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

dynamic UO.Connected();

ํ˜„์žฌ ์„ธ์…˜์ด ๊ฒŒ์ž„ ์„ธ๊ณ„์— ์žˆ๋Š”์ง€, ๊ฒŒ์ž„ ์—ฐ๊ฒฐ์ด ์—ด๋ ค ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์บ๋ฆญํ„ฐ ํ–‰๋™ ์ „์ด๋‚˜ ์ž…์žฅ ๋Œ€๊ธฐ ์ค‘์— ์‚ฌ์šฉํ•˜์„ธ์š”.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

int. 1 - ํ”Œ๋ ˆ์ด์–ด, ๋กœ๋“œ๋œ ์นด๋“œ ๋ฐ ํ™œ์„ฑ ๊ฒŒ์ž„ ์†Œ์ผ“์ด ๋™์‹œ์— ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด 0. ์—ด๋ฆฐ ํด๋ผ์ด์–ธํŠธ ์ฐฝ, ์บ๋ฆญํ„ฐ ๋ชฉ๋ก ๋˜๋Š” ๋กœ๊ทธ์ธ ๋‹จ๊ณ„์˜ TCP ์—ฐ๊ฒฐ์€ 1๋ฅผ ์˜๋ฏธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ int: 1(์กฐ๊ฑด ์ถฉ์กฑ), 0(์กฐ๊ฑด ์ถฉ์กฑ๋˜์ง€ ์•Š์Œ). ์ด๋Š” ์ˆซ์ž ํ”Œ๋ž˜๊ทธ์ž…๋‹ˆ๋‹ค. C#์—์„œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜์„ธ์š”!= 0 ๋˜๋Š” ๊ฒฐ๊ณผ == 0์ž…๋‹ˆ๋‹ค. int์™€ true/false ๋ฐ if(๊ฒฐ๊ณผ)๋ฅผ ์ง์ ‘ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ช…๋ น์˜ ๊ฒฐ๊ณผ๋Š” ์ˆซ์ž ํ”Œ๋ž˜๊ทธ์ž…๋‹ˆ๋‹ค. 1๋Š” ์ถฉ์กฑ๋œ ์กฐ๊ฑด์„ ์˜๋ฏธํ•˜๊ณ , 0๋Š” ์ถฉ์กฑ๋˜์ง€ ์•Š์€ ์กฐ๊ฑด์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. var result = command(...) ํ›„์— (๊ฒฐ๊ณผ != 0) ๋˜๋Š” (๊ฒฐ๊ณผ == 0)์ธ์ง€ ํ™•์ธํ•˜์„ธ์š”. ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ณต๋œ ํ˜ธ์ถœ์„ ํ†ตํ•ด ํ•ด๋‹น ์ž‘์—…์„ ๋‹ค์‹œ ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜ ์ด๋ฏธ ๋ณ€๊ฒฝ๋œ ์ƒํƒœ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋™์ž‘

  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค: serial, type, ์บ๋ฆญํ„ฐ ์ด๋ฆ„ ๋ฐ IP๋Š” ์ „์†กํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. UO.Online(), UO.Connected(), UO.IsOnline()๋„ ๊ฐ™์€ ๊ฒƒ์„ ํ™•์ธํ•˜์„ธ์š”. ์ด๋Š” ๋‹ค๋ฅธ ๊ด€๋ฆฌ์ž ํ”„๋กœํ•„์ด ์•„๋‹Œ ํ•ด๋‹น ์„ธ์…˜ ์†Œ์œ ์ž์˜ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • UO.Wait์—๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ์ž๋™ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ์˜ˆ์ œ ์‹คํ–‰์„ ์ˆ˜๋™์œผ๋กœ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ™•์ธ์€ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์—๋งŒ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์€ ์ผ์‹œ ์ค‘์ง€๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €๋„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ bool๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฐ์—ด์ด๋ฉด ์š”์†Œ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

1. ๊ฒŒ์ž„ ์Šคํ‚ฌ์„ ์˜คํ”„๋ผ์ธ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜์ง€ ๋งˆ์„ธ์š” - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • false๋Š” 0์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. return์€ Main์„ UseSkill๋กœ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. ์Šคํ‚ฌ ์ด๋ฆ„์ธ UseSkill์˜ ์œ ์ผํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ•˜์ด๋“œ์ž…๋‹ˆ๋‹ค. 1๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๋Š” ์Šคํ‚ฌ ์‚ฌ์šฉ๋งŒ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” ์บ๋ฆญํ„ฐ์™€ ์„œ๋ฒ„์˜ ์ƒํƒœ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
if (Truth(Truth(UO.Connected()) == false))
{
    return null;
}
UO.UseSkill("Hiding");

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

2. ์—ฐ๊ฒฐ์ด ์—†์„ ๋•Œ ์—ฐ๊ฒฐ ์š”์ฒญ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • 0๊ณผ์˜ ๋น„๊ต๋Š” ์ž๋™ ์žฌ์—ฐ๊ฒฐ ์„ค์ •์ด ์•„๋‹Œ ํ˜„์žฌ ์—ฐ๊ฒฐ ์ƒํƒœ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ธ์ˆ˜๊ฐ€ ์—†๋Š” Connect๋Š” ์ €์žฅ๋œ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๊ณ  ๋กœ๊ทธ์ธ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ ์‹œ์ž‘๋œ ๋กœ๊ทธ์ธ ์ค‘์— ๋ช…๋ น์„ ๋ฐ˜๋ณตํ•ด๋„ ๋‘ ๋ฒˆ์งธ ์„ธ์…˜์ด ์ƒ์„ฑ๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Connected() == 0))
    {
        UO.Connect();
    }

    return null;
}

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

3. ์‹œ๊ฐ„ ์ œํ•œ์œผ๋กœ ์„ธ์ƒ์ด ์ค€๋น„๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ - ์‹œ๋‚˜๋ฆฌ์˜ค ์ˆ˜์—…

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • WaitForWorld(timeoutMs)๋Š” ๋‚ด์žฅ ๋ช…๋ น์ด ์•„๋‹Œ ์™„์ „ํžˆ ํ‘œ์‹œ๋œ ์‚ฌ์šฉ์ž ์ •์˜ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. 5000 โ€” ์˜ˆ์‚ฐ(๋ฐ€๋ฆฌ์ดˆ), UO.Wait(50) โ€” ํ™•์ธ ๊ฐ„๊ฒฉ. ์Œ์ˆ˜ ๊ฐ’์€ false๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. 0 ๊ธฐ์„ฑ ์„ธ๊ณ„๋งŒ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค. Timer๋Š” ์ดˆ๋ฅผ ์ธก์ •ํ•˜๋ฏ€๋กœ ๊ทธ ์ฐจ์ด์— 1000์„ ๊ณฑํ•ฉ๋‹ˆ๋‹ค. ์ž๋™ ์ผ์‹œ์ค‘์ง€๋Š” ๋ฏธ๋ฆฌ ๊บผ์•ผ ํ•˜๋ฉฐ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” Connect๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉฐ ์‹œ๊ฐ„์ด ๋งŒ๋ฃŒ๋˜์–ด๋„ ์‹œ์ž‘๋œ ์ž…๋ ฅ์„ ์ทจ์†Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
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()
    {
        if (Truth(UO.GetPauseScriptOnDisconnectStatus()))
        {
            return null;
        }

        if (Truth(await WaitForWorld(5000)))
        {
            UO.UseSkill("Hiding");
        }

        return null;
    }

    async Task<dynamic> WaitForWorld(dynamic timeoutMs)
    {
        if (Truth(timeoutMs < 0))
        {
            return false;
        }

        var started = Environment.TickCount;
        while (!(Truth(UO.Connected())))
        {
            if (Truth((Environment.TickCount - started) * 1000.0 >= timeoutMs))
            {
                return false;
            }

            await Delay(50);
        }

        return true;
    }

    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#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.Connected() โ€” UO.Connected()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: dynamic / Any.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "connected": return new InjectionValue(bridge.IsOnline());

UO.ConnectedTime

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

dynamic UO.ConnectedTime();

์บ๋ฆญํ„ฐ๊ฐ€ ๋งˆ์ง€๋ง‰์œผ๋กœ ์›”๋“œ์— ์„ฑ๊ณต์ ์œผ๋กœ ์ง„์ž…ํ•œ ๋‹ฌ๋ ฅ ์Šคํƒฌํ”„๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋™์ผํ•œ ์ž‘์—…์„ ๊ณ„์†ํ•˜๊ธฐ ์ „์— ๋Œ€๊ธฐํ•˜๊ฑฐ๋‚˜ ์ผ์‹œ ์ค‘์ง€ํ•˜๋Š” ๋™์•ˆ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

double: 1899-12-30์˜ ์ผ์ˆ˜, ์†Œ์ˆ˜๋ถ€ - ์‹œ๊ฐ„(OLE ์ž๋™ํ™” ๋‚ ์งœ). 0๋Š” ํ•ด๋‹น ์„ธ์…˜ ์†Œ์œ ์ž๊ฐ€ ์•„์ง ์„ธ์ƒ์— ๋“ค์–ด์˜ค์ง€ ์•Š์•˜์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š๊ธด ํ›„์—๋„ ๋งˆ์ง€๋ง‰ ์ž…๋ ฅ ํ‘œ์‹œ๊ฐ€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ bool ๋˜๋Š” ์ดˆ ๋‹จ์œ„์˜ ๊ธฐ๊ฐ„์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋™์ž‘

  • ๋…ผ์Ÿ์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ก์€ ๋™์ผํ•œ ์„ธ์…˜ ์†Œ์œ ์ž์˜ ์Šคํฌ๋ฆฝํŠธ์— ๊ณตํ†ต๋ฉ๋‹ˆ๋‹ค. ๋Šฆ์€ ์‹œ์ž‘, ์ผ์‹œ ์ค‘์ง€ ๋ฐ ๋‹ซ๊ธฐ IDE๋Š” ํ‘œ์‹œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์„ธ์…˜ ํ”„๋กœ์„ธ์Šค๋Š” ์ƒˆ๋กœ์šด ์ด์•ผ๊ธฐ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์—ฐ๊ฒฐ์— ๋Œ€ํ•œ ๋กœ๊ทธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.
  • ์›”๋“œ์— ์บ๋ฆญํ„ฐ๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๊ณ  ๋กœ๊ทธ์ธ ์‹œ๋„์— ์‹คํŒจํ•˜๋ฉด ๋กœ๊ทธ์ธ ์„ฑ๊ณต์œผ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜คํ”„๋ผ์ธ ํ™•์ธ์„ ๋ฐ˜๋ณตํ•ด๋„ ์ข…๋ฃŒ ์‹œ๊ฐ„์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์ƒํƒœ์˜ ๊ฒฝ์šฐ 0์ด ์•„๋‹Œ ๋‚ ์งœ ๋Œ€์‹  UO.Connected()๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
  • ์‹œ๊ณ„๋Š” ์ปดํ“จํ„ฐ์˜ ๋กœ์ปฌ ์‹œ๊ณ„์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ฐจ์ด์— 86400์„ ๊ณฑํ•˜๋ฉด ๋‹ฌ๋ ฅ ์ดˆ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์‹œ๊ณ„/์‹œ๊ฐ„๋Œ€๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ๊ฒฐ๊ณผ๊ฐ€ ์™œ๊ณก๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ์˜ ๊ฒฝ์šฐ ๋‹จ์กฐ๋กœ์šด Timer()๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ํ˜ธ์ถœ์€ ์›์ž์  ์Šค๋ƒ…์ƒท์„ ํ˜•์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋™์ผํ•œ ํ‘œ์‹œ๋Š” ๊ณ ์œ ํ•œ ID ์—ฐ๊ฒฐ์ด ์•„๋‹™๋‹ˆ๋‹ค.
  • UO.Wait์—๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ์ž๋™ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ์˜ˆ์ œ ์‹คํ–‰์„ ์ˆ˜๋™์œผ๋กœ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ™•์ธ์€ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์—๋งŒ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์€ ์ผ์‹œ ์ค‘์ง€๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €๋„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ bool๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฐ์—ด์ด๋ฉด ์š”์†Œ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

1. ์ฒซ ๋ฒˆ์งธ ์ž…๋ ฅ ์š”์ฒญ - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • 0๋Š” ์ด ํŠน์ • ํ”„๋กœ์„ธ์Šค์— ์ž…๋ ฅ์ด ์—†๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. Connect ์ €์žฅ๋œ ํ”„๋กœํ•„์„ ์‚ฌ์šฉํ•˜๋ฉฐ ๋กœ๊ทธ์ธ๋งŒ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์—์„œ๋Š” ์ด๋ฏธ ์ข…๋ฃŒ๋œ ์—ฐ๊ฒฐ์„ ์˜๋„์ ์œผ๋กœ ๋ณต์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • UO.Wait์—๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ์ž๋™ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ์˜ˆ์ œ ์‹คํ–‰์„ ์ˆ˜๋™์œผ๋กœ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ™•์ธ์€ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์—๋งŒ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์€ ์ผ์‹œ ์ค‘์ง€๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
if (Truth(UO.ConnectedTime() == 0))
{
    UO.Connect();
}

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

2. ์‹ ๊ทœ ๋กœ๊ทธ์ธ ํ›„ ์˜ˆ์ƒ ๋Œ€์ƒ ์žฌ์„ค์ • - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • 30.0 โ€” ๋ช‡ ์ดˆ ๋งŒ์— ์˜ˆ์‚ฐ ๋ชจ๋‹ˆํ„ฐ๋ง Timer; 250 โ€” ๊ฐ„๊ฒฉ UO.Wait(๋ฐ€๋ฆฌ์ดˆ) ์ง„์ž… ํ‘œ์‹œ๋ฅผ ๋ณ€๊ฒฝํ•œ ํ›„ CancelWaitTarget๋Š” ์ด์ „ ์ง€์—ฐ ๋Œ€์ƒ์„ ์ง€์›๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์ž…๋ ฅ์ด ์—†์œผ๋ฉด ์ด ์ž‘์—… ์—†์ด ๋ฃจํ”„๊ฐ€ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.
  • UO.Wait์—๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ์ž๋™ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ์˜ˆ์ œ ์‹คํ–‰์„ ์ˆ˜๋™์œผ๋กœ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ™•์ธ์€ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์—๋งŒ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์€ ์ผ์‹œ ์ค‘์ง€๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    var login = UO.ConnectedTime();
    var started = Environment.TickCount;
    while (Truth(Environment.TickCount - started < 30.0))
    {
        if (Truth(UO.Connected()) && Truth(UO.ConnectedTime() != login))
        {
            UO.CancelWaitTarget();
            return null;
        }

        await Delay(250);
    }

    return null;
}

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

3. ๊ณ„์†ํ•˜๊ธฐ ์ „์— ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ - ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • SameConnection(๋กœ๊ทธ์ธ)์€ bool์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํ‘œ์‹œ๋ฅผ ์ €์žฅํ•˜๊ณ  500ms ๋™์•ˆ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ์—ฐ๊ฒฐ์ด ์—†๊ฑฐ๋‚˜ ์ž…๋ ฅ์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๊ณ„์†์„ ๊ธˆ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์žฌํ…Œ์ŠคํŠธ์ด๋ฉฐ ํ–ฅํ›„ ์„œ๋ฒ„ ๊ฐ€์šฉ์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • UO.Wait์—๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ์ž๋™ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ์˜ˆ์ œ ์‹คํ–‰์„ ์ˆ˜๋™์œผ๋กœ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ™•์ธ์€ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์—๋งŒ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์€ ์ผ์‹œ ์ค‘์ง€๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
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 login = UO.ConnectedTime();
        await Delay(500);
        if (!(Truth(SameConnection(login))))
        {
            return null;
        }

        UO.AddToSystemJournal("Same connection; continue this batch");
        return null;
    }

    dynamic SameConnection(dynamic login)
    {
        return Truth(login != 0) && Truth(UO.Connected()) && Truth(UO.ConnectedTime() == login);
    }

    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#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.ConnectedTime() โ€” UO.ConnectedTime()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: dynamic / Any.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "connectedtime":

                    UpdateConnectionState();

                    return new InjectionValue(state.ConnectedTime == default(DateTime) ? 0d : state.ConnectedTime.ToOADate());

UO.Disconnect

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

void UO.Disconnect();

ํ˜„์žฌ ๋˜๋Š” ์„ค์น˜๋œ ํด๋ผ์ด์–ธํŠธ ์ „์†ก์˜ ์—ฐ๊ฒฐ์„ ๋Š๊ณ  ๋‹ค์‹œ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

void - ๋ฐ˜ํ™˜ ๊ฐ’์ด ์—†์Šต๋‹ˆ๋‹ค.

๋™์ž‘

  • ์ž๋™ ์žฌ์—ฐ๊ฒฐ์ด ๊บผ์ง„ ๊ฒฝ์šฐ BeginScriptControlledDisconnect๋Š” ์ž‘์—…์ž๊ฐ€ ๋‚˜์ค‘์— ์ „ํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ €์žฅํ•ฉ๋‹ˆ๋‹ค UO.Connect. ๊ด€๋ฆฌ์ž ์„ธ์…˜์€ RequestDisconnect๋ฅผ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋…๋ฆฝํ˜• ํด๋ผ์ด์–ธํŠธ๋Š” Socket.Disconnect ๋ฐ PrepareForReconnect๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ „์—ญ ์žฌ์—ฐ๊ฒฐ์ด ํ™œ์„ฑํ™”๋˜๋ฉด ์ €์žฅ๋œ ์žฅ๋ฉด ์ „ํ™˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์˜ˆ์•ฝํ•ฉ๋‹ˆ๋‹ค. LoginScene์—์„œ๋Š” ํŒ์—…์„ ์ง€์šฐ๊ณ  Main์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • void๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์žฌ์ ‘์† ๊ฒฐ๊ณผ๊ฐ€ ๋ณด๊ณ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ ์ƒํƒœ๋Š” ๋ณ„๋„๋กœ ์ฝํ˜€์ง‘๋‹ˆ๋‹ค. ์ž๋™ ์žฌ์—ฐ๊ฒฐ ์„ค์ •์„ ํ†ตํ•ด ์ƒˆ๋กœ์šด ๋กœ๊ทธ์ธ์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๋ช…๋ น์€ ๋…๋ฆฝ๋œ ๋ฌธ์ž…๋‹ˆ๋‹ค. ์•ž์˜ ๋ฉ”์‹œ์ง€๋Š” ํ˜ธ์ถœ ์‹œ์ž‘์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ ์„œ๋ฒ„ ๋™์ž‘์˜ ์™„๋ฃŒ๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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

1. ์„ธ์…˜ ์—ฐ๊ฒฐ ๋Š๊ธฐ - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ์ด ๋ช…๋ น์€ ํ™œ์„ฑ ์ „์†ก๊ณผ ์„ค์น˜๋œ ์ „์†ก์„ ๋ชจ๋‘ ์ทจ์†Œํ•ฉ๋‹ˆ๋‹ค.
UO.Disconnect();

2. ๋ช…์‹œ์  ์žฌ์—ฐ๊ฒฐ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • AR๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋˜๋ฉด ํ˜ธ์ถœ ์ž‘์—…์ž๋Š” ์Šค์Šค๋กœ Connect์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    UO.Disconnect();
    await Delay(1000);
    UO.Connect();
    return null;
}

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

3. ์—ฐ๊ฒฐ๋œ ์„ธ์…˜๋งŒ ๋น„ํ™œ์„ฑํ™” - ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ์กฐ๊ฑด์€ ํ˜„์žฌ ์„ธ์…˜์— ๋Œ€ํ•œ ๋กœ์ปฌ ํ”Œ๋ž˜๊ทธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
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(UO.Connected()))
        {
            UO.Disconnect();
        }

        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.Disconnect() โ€” UO.Disconnect()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: void / Unit.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "disconnect": bridge.DisconnectClient(); return InjectionValue.Unit;

UO.DisconnectedTime

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

dynamic UO.DisconnectedTime();

๋งˆ์ง€๋ง‰์œผ๋กœ ๊ฒŒ์ž„ ์—ฐ๊ฒฐ์ด ๋Š์–ด์กŒ์„ ๋•Œ์˜ ๋‹ฌ๋ ฅ ์Šคํƒฌํ”„๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ค‘๋‹จ์„ ์ง„๋‹จํ•˜๊ณ  ์—ฐ๊ฒฐ ์™„๋ฃŒ ๊ธฐ๊ฐ„์„ ์ถ”์ •ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•˜๋ฉฐ ๋กœ๊ทธ์ธ ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

double: ํ•˜๋ฃจ ์ค‘ ๋ถ„์ˆ˜ ๋ถ€๋ถ„์ด ํฌํ•จ๋œ 1899-12-30์˜ ์ผ์ˆ˜์ž…๋‹ˆ๋‹ค. ํœด์‹ ํ›„ - ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ค‘๋‹จ์„ ์ธ์ง€ํ•œ ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ค‘๋‹จ ์ „์€ ์„ธ์…˜ ์†Œ์œ ์ž๊ฐ€ ์ƒ์„ฑ๋œ ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์˜คํ”„๋ผ์ธ ํ”Œ๋ž˜๊ทธ๊ฐ€ ์•„๋‹ˆ๋ฉฐ ๋ฐ€๋ฆฌ์ดˆ๋„ ์•„๋‹™๋‹ˆ๋‹ค.

๋™์ž‘

  • ๋…ผ์Ÿ์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ก์€ ๋™์ผํ•œ ์„ธ์…˜ ์†Œ์œ ์ž์˜ ์Šคํฌ๋ฆฝํŠธ์— ๊ณตํ†ต๋ฉ๋‹ˆ๋‹ค. ๋Šฆ์€ ์‹œ์ž‘, ์ผ์‹œ ์ค‘์ง€ ๋ฐ ๋‹ซ๊ธฐ IDE๋Š” ํ‘œ์‹œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์„ธ์…˜ ํ”„๋กœ์„ธ์Šค๋Š” ์ƒˆ๋กœ์šด ์ด์•ผ๊ธฐ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์—ฐ๊ฒฐ์— ๋Œ€ํ•œ ๋กœ๊ทธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.
  • ์›”๋“œ์— ์บ๋ฆญํ„ฐ๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๊ณ  ๋กœ๊ทธ์ธ ์‹œ๋„์— ์‹คํŒจํ•˜๋ฉด ๋กœ๊ทธ์ธ ์„ฑ๊ณต์œผ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜คํ”„๋ผ์ธ ํ™•์ธ์„ ๋ฐ˜๋ณตํ•ด๋„ ์ข…๋ฃŒ ์‹œ๊ฐ„์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์ƒํƒœ์˜ ๊ฒฝ์šฐ 0์ด ์•„๋‹Œ ๋‚ ์งœ ๋Œ€์‹  UO.Connected()๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
  • ์‹œ๊ณ„๋Š” ์ปดํ“จํ„ฐ์˜ ๋กœ์ปฌ ์‹œ๊ณ„์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ฐจ์ด์— 86400์„ ๊ณฑํ•˜๋ฉด ๋‹ฌ๋ ฅ ์ดˆ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์‹œ๊ณ„/์‹œ๊ฐ„๋Œ€๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ๊ฒฐ๊ณผ๊ฐ€ ์™œ๊ณก๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ์˜ ๊ฒฝ์šฐ ๋‹จ์กฐ๋กœ์šด Timer()๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ํ˜ธ์ถœ์€ ์›์ž์  ์Šค๋ƒ…์ƒท์„ ํ˜•์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋™์ผํ•œ ํ‘œ์‹œ๋Š” ๊ณ ์œ ํ•œ ID ์—ฐ๊ฒฐ์ด ์•„๋‹™๋‹ˆ๋‹ค.
  • UO.Wait์—๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ์ž๋™ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ์˜ˆ์ œ ์‹คํ–‰์„ ์ˆ˜๋™์œผ๋กœ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ™•์ธ์€ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์—๋งŒ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์€ ์ผ์‹œ ์ค‘์ง€๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €๋„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ bool๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฐ์—ด์ด๋ฉด ์š”์†Œ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

1. ์™„๋ฃŒ๋œ ์—ฐ๊ฒฐ ๊ธฐ๊ฐ„ ์ถ”์ • - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • CompletedConnectionSeconds()๋Š” ์—ฐ๊ฒฐ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ ์ฝ๊ธฐ ์‚ฌ์ด์— ์ž…๋ ฅ์ด ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ ์ดˆ ๋˜๋Š” -1๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. 86400 โ€” ํ•˜๋ฃจ์˜ ์ดˆ. ๋งˆ์ง€๋ง‰ ์ž…๋ ฅ/์ค‘๋‹จ ์Œ๋งŒ ๋‹ค์‹œ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ๋ชจ๋“  ์„ธ์…˜์˜ ๊ธฐ๋ก์„ ์š”์•ฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • UO.Wait์—๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ์ž๋™ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ์˜ˆ์ œ ์‹คํ–‰์„ ์ˆ˜๋™์œผ๋กœ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ™•์ธ์€ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์—๋งŒ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์€ ์ผ์‹œ ์ค‘์ง€๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
var seconds = CompletedConnectionSeconds();
if (Truth(seconds >= 0))
{
    UO.AddToSystemJournal("Completed connection seconds: " + Convert.ToString(seconds));
}

dynamic CompletedConnectionSeconds()
{
    var login = UO.ConnectedTime();
    var loss = UO.DisconnectedTime();
    if (Truth(login == 0) || Truth(loss < login) || Truth(UO.Connected()))
    {
        return -1;
    }
    if (Truth(UO.ConnectedTime() != login))
    {
        return -1;
    }
    return (loss - login) * 86400.0;
}

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

2. ์˜คํ”„๋ผ์ธ์œผ๋กœ ์ž ์‹œ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๋กœ๊ทธ์ธ ์š”์ฒญ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ์ž๋™ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ํ™œ์„ฑํ™”๋˜๋ฉด ์ด ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์ฆ‰์‹œ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์˜คํ”„๋ผ์ธ์œผ๋กœ ์ž‘์—…ํ•˜๋ ค๋ฉด ๋ฏธ๋ฆฌ ๊บผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. UO.Wait(1000) ์˜คํ”„๋ผ์ธ ์ดํ›„ ์ด์ „ ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. Connect๋Š” ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ ์„ค์ •์„ ๋Œ€์ฒดํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • UO.Wait์—๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ์ž๋™ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ์˜ˆ์ œ ์‹คํ–‰์„ ์ˆ˜๋™์œผ๋กœ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ™•์ธ์€ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์—๋งŒ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์€ ์ผ์‹œ ์ค‘์ง€๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
return await RunScenarioAsync();
async Task<object?> RunScenarioAsync()
{
    if (Truth(UO.GetPauseScriptOnDisconnectStatus()))
    {
        return null;
    }

    if (Truth(UO.Connected()))
    {
        return null;
    }

    var loss = UO.DisconnectedTime();
    await Delay(1000);
    if (!(Truth(UO.Connected())) && Truth(UO.DisconnectedTime() == loss))
    {
        UO.Connect();
    }

    return null;
}

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

3. ๊ฒ€์‚ฌ ์‚ฌ์ด์˜ ์ค‘๋‹จ์„ ํ™•์ธํ•˜์„ธ์š” - ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • previousLoss์™€ ๋น„๊ตํ•˜๋ฉด ์ด๋ฏธ ์žฌ์ง„์ž…์ด ๋ฐœ์ƒํ•œ ํ›„์—๋„ ์ค‘๋‹จ์ด ๋ฐœ์ƒํ•จ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 30์ดˆ๋Š” ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ๋ชจ๋‹ˆํ„ฐ๋ง์„ ์ œํ•œํ•˜๊ณ , WaitAsync(250)๋Š” ๊ฒ€์‚ฌ ์‚ฌ์ด์— ์Šค๋ ˆ๋“œ๋ฅผ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๋ฐฉํ•ด ์š”์†Œ๋ฅผ ํ•˜๋‚˜์˜ ์•Œ๋ฆผ์œผ๋กœ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • UO.Wait์—๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ์ž๋™ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ์˜ˆ์ œ ์‹คํ–‰์„ ์ˆ˜๋™์œผ๋กœ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ™•์ธ์€ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์—๋งŒ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์€ ์ผ์‹œ ์ค‘์ง€๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
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 previousLoss = UO.DisconnectedTime();
        var started = Environment.TickCount;
        while (Truth(Environment.TickCount - started < 30.0))
        {
            if (Truth(UO.DisconnectedTime() != previousLoss))
            {
                UO.AddToSystemJournal("A connection loss occurred; check the session");
                return null;
            }

            await Delay(250);
        }

        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;
}

๋ช…๋ น ๊ตฌํ˜„

C#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.DisconnectedTime() โ€” UO.DisconnectedTime()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: dynamic / Any.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "disconnectedtime":

                    UpdateConnectionState();

                    return new InjectionValue(state.DisconnectedTime.ToOADate());

UO.GameServerIPString

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

dynamic UO.GameServerIPString();

ํด๋ผ์ด์–ธํŠธ์˜ ์ „์—ญ ์„ค์ •์—์„œ ๊ตฌ์„ฑ๋œ ์„œ๋ฒ„ ์ฃผ์†Œ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

string โ€” Settings.GlobalSettings.IP ๋˜๋Š” ๊ฐ’์ด ์—†๋Š” ๊ฒฝ์šฐ ๋นˆ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.

๋™์ž‘

  • ํ˜„์žฌ ๋ธŒ๋ฆฌ์ง€์˜ GameServerAddress๋Š” ์ „์—ญ ์„ค์ • IP์„ ์ฝ์Šต๋‹ˆ๋‹ค. ์ด๋Š” DNS/network ์š”์ฒญ๋„ ์•„๋‹ˆ๊ณ  ์‹ค์ œ ํ”ผ์–ด์˜ ์ฃผ์†Œ๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ๋„ ์•„๋‹™๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ž ์„ธ์…˜์€ ์ž์ฒด ์—ฐ๊ฒฐ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €๋„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ bool๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฐ์—ด์ด๋ฉด ์š”์†Œ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

1. ์ฃผ์†Œ ์ฝ๊ธฐ - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ํ˜„์žฌ ์ „์—ญ ์„ค์ • IP์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.
var address = UO.GameServerIPString();
UO.Print(address);

2. ๋นˆ ์ฃผ์†Œ ํ™•์ธ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ๊ณต๋ฐฑ ๊ฐ’์€ ๊ตฌ์„ฑ์ด ์—†์Œ์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ ์ธก์ •๋œ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹˜์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
return  RunScenario();
 object? RunScenario()
{
    var address = UO.GameServerIPString();
    if (Truth(Len(address) == 0))
    {
        UO.Print("no configured address");
    }

    return null;
}

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

3. ์Šค๋ƒ…์ƒท ์ €์žฅ - ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ๋ณ€์ˆ˜๋Š” ์ฒซ ๋ฒˆ์งธ ํ˜ธ์ถœ์—์„œ ์–ป์€ ๋ฌธ์ž์—ด์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
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 address = UO.GameServerIPString();
        await Delay(100);
        UO.Print(address);
        return null;
    }

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

๋ช…๋ น ๊ตฌํ˜„

C#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.GameServerIPString() โ€” UO.GameServerIPString()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: dynamic / Any.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "gameserveripstring": return new InjectionValue(bridge.GameServerAddress);

UO.GetCharsListForShard

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

dynamic UO.GetCharsListForShard();

ํด๋ผ์ด์–ธํŠธ์— ์•Œ๋ ค์ง„ ํ˜„์žฌ ์ƒค๋“œ์˜ ์บ๋ฆญํ„ฐ ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

๋ฌธ์ž์—ด ๋ฐฐ์—ด. ์•Œ๋ ค์ง„ ์ด๋ฆ„์ด ์—†์œผ๋ฉฐ ํ˜„์žฌ ๋ฌธ์ž๋Š” ๋นˆ ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค.

๋™์ž‘

  • ๊ด€๋ฆฌ์ž ์„ธ์…˜์€ SessionControl.Characters๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค. ๋…๋ฆฝ ์‹คํ–‰ํ˜•์—์„œ๋Š” LastCharacterManager๊ฐ€ ๊ณ„์ •/์„œ๋ฒ„์— ๋จผ์ € ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋ชฉ๋ก์ด ๋น„์–ด ์žˆ์œผ๋ฉด LoginScene.๋ฌธ์ž๊ฐ€ ์—†๋Š” ์ด๋ฆ„์„ ์ฝ์œผ์„ธ์š”. ๊ทธ๋Ÿฌ๋ฉด ํ˜„์žฌ Player.Name๊ฐ€ ์œ ์ผํ•œ ์š”์†Œ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ์ด๋Š” ์ง€์—ญ์ ์œผ๋กœ ์œ ๋ช…ํ•œ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์€ ์„œ๋ฒ„์—์„œ ์ „์ฒด ๋ชฉ๋ก์„ ์š”์ฒญํ•˜์ง€ ์•Š์œผ๋ฉฐ ์บ์‹œ์˜ ์ตœ์‹ ์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €๋„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ bool๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฐ์—ด์ด๋ฉด ์š”์†Œ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

1. ์ด๋ฆ„ ์ธ์‡„ - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ๋ฃจํ”„๋Š” ์•Œ๋ ค์ง„ ์ด๋ฆ„์˜ ์‹ค์ œ ๋ฐฐ์—ด์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
var names = UO.GetCharsListForShard();
for (int i = (int)(0); i <= ArrayLength(names)-1; i += (int)(1))
{
    UO.Print(names[i]);
}

int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;

2. ์•Œ๋ ค์ง„ ์ด๋ฆ„ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ์ธ๋ฑ์Šค 0๋Š” ๋น„์–ด ์žˆ์ง€ ์•Š์€ ๋ฐฐ์—ด์—๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
return  RunScenario();
 object? RunScenario()
{
    var names = UO.GetCharsListForShard();
    if (Truth(ArrayLength(names) > 0))
    {
        UO.Print(names[0]);
    }

    return null;
}

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

3. ์ด๋ฆ„ ์ˆ˜ - ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ๋ชฉ๋ก ํฌ๊ธฐ๋Š” ์„œ๋ฒ„์˜ ๊ณ„์ • ์Šฌ๋กฏ ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
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 names = UO.GetCharsListForShard();
        UO.Print(Convert.ToString(ArrayLength(names)));
        return null;
    }

    int ArrayLength(object? value) => value is System.Array array ? array.Length : 0;
}

๋ช…๋ น ๊ตฌํ˜„

C#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.GetCharsListForShard() โ€” UO.GetCharsListForShard()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: dynamic / Any.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "getcharslistforshard": return StringArray(bridge.GetCharactersForCurrentShard());

UO.GetPing

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

int UO.GetPing();
int UO.GetPing(object? timeout);

๊ฒŒ์ž„ ์„œ๋ฒ„ ์‘๋‹ต ์ง€์—ฐ์„ ์ฝ์Šต๋‹ˆ๋‹ค. ์ธ์ˆ˜๊ฐ€ ์—†์œผ๋ฉด ๋งˆ์ง€๋ง‰ ์ฐจ์›์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ƒˆ๋กœ์šด ์‘๋‹ต์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

  • timeout - ์‹œ๊ฐ„ ์ดˆ๊ณผ / timeoutMS - ํ•œ ๋ฒˆ์˜ ์‹œ๋„์— ๋Œ€ํ•œ ๋Œ€๊ธฐ ์‹œ๊ฐ„(๋ฐ€๋ฆฌ์ดˆ)์œผ๋กœ, int๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. ์Œ์ˆ˜ ๊ฐ’์€ 0์œผ๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. 0๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์š”์ฒญ์ด ์ „์†ก๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์‘๋‹ต์„ ๊ธฐ๋Œ€ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋ฌดํ•œ์ • ํƒ€์ž„์•„์›ƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

int, ๋ฐ€๋ฆฌ์ดˆ. ๊ฐ’ >= 0 โ€“ ์ธก์ •; 0 ms๋„ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค. -1 - ์ธก์ • ์—†์Œ: ์ธ์ˆ˜๊ฐ€ ์žˆ๋Š” ์–‘์‹์˜ ๊ฒฝ์šฐ ์š”์ฒญ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ ์‘๋‹ต์ด ์ œ๋•Œ์— ์ˆ˜์‹ ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ bool์ด ์•„๋‹™๋‹ˆ๋‹ค. 0๋Š” ์‹คํŒจ๋กœ ๊ฐ„์ฃผํ•  ์ˆ˜ ์—†์œผ๋ฉฐ -1๋Š” ์„ฑ๊ณต์œผ๋กœ ๊ฐ„์ฃผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋™์ž‘

  • GetPing()๋Š” ์•„๋ฌด ๊ฒƒ๋„ ๋ณด๋‚ด์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ๋งˆ์ง€๋ง‰ ServerPing์„ ์ฝ์Šต๋‹ˆ๋‹ค. ์ด์ „ ๊ฐ’ ์ž์ฒด๋กœ๋Š” ์—ฐ๊ฒฐ์ด ํ˜„์žฌ ์ž‘๋™ํ•˜๊ณ  ์žˆ์Œ์„ ์ฆ๋ช…ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ‰ํ™œํ™”/๋ฐฑ์—… TCP ํ‘œ์‹œ๊ธฐ ping ๋ฐ ICMP Ping(ํ˜ธ์ŠคํŠธ)์ด ์•„๋‹Œ ๋งˆ์ง€๋ง‰ ์„œ๋ฒ„ ์—์ฝ” ์ธก์ •์ž…๋‹ˆ๋‹ค. GetPing(timeout)์€ ์ƒˆ๋กœ์šด ์‘๋‹ต์„ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๋งˆ์ง€๋ง‰ ์„œ๋ฒ„ ์ธก์ •๊ฐ’์„ ์ฝ์Šต๋‹ˆ๋‹ค.
  • ๊ธฐ๋‹ค๋ฆฌ๋ฉด ๊ฒŒ์ž„ ๋™์ž‘์„ ํ™•์ธํ•˜๋Š” ๋Œ€์‹  ํ˜ธ์ถœ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ง€์—ฐ๋ฉ๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์€ ๋‹ค์‹œ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์œผ๋ฉฐ ๋„คํŠธ์›Œํฌ ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„๊ฐ€ ์—์ฝ”์— ์‘๋‹ตํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹คํŒจ ์ž์ฒด๋กœ๋Š” ์—ฐ๊ฒฐ์ด ๋Š์–ด์กŒ๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํƒ€์ด๋ฐ์€ ํ๋ฆ„ ์ผ์ •์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ๋ชจ๋“  ํ”„๋ ˆ์ž„์—์„œ ํ™œ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”. ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ค‘์ง€ํ•˜๋ฉด ๋Œ€๊ธฐ๊ฐ€ ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค.
  • UO.GetPing ยท UO.CheckLag ยท UO.IsOnline

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €๋„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ bool๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฐ์—ด์ด๋ฉด ์š”์†Œ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

1. GetPing - 1 - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ์ƒˆ๋กœ์šด ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์—†์ด ์บ์‹œ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค. ์ด ์˜ˆ์—์„œ๋Š” 50 ๋˜๋Š” 200ms๋ฅผ ์„ ํƒํ•˜์—ฌ 250ms ์ž„๊ณ„๊ฐ’์—์„œ ์Šคํฌ๋ฆฝํŠธ ์ž์ฒด๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ์•Œ ์ˆ˜ ์—†๋Š” ์ฐจ์›์€ ๋ณ„๋„๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ์ด ์ˆซ์ž๋Š” ๋ฒ”์šฉ ์„œ๋ฒ„ ์ œํ•œ์ด ์•„๋‹Œ ์˜ˆ์‹œ ์„ค์ •์ž…๋‹ˆ๋‹ค.
var pingMs = UO.GetPing();
if (Truth(pingMs < 0))
{
    UO.Print("No server latency sample");
    return null;
}
var delayMs = 50;
if (Truth(pingMs > 250))
{
    delayMs = 200;
}
await Delay(delayMs);

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

2. GetPing โ€” 2 โ€” ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • 1000 โ€” ์ƒˆ๋กœ์šด ์‘๋‹ต์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ตœ๋Œ€ ์‹œ๊ฐ„(๋ฐ€๋ฆฌ์ดˆ)์ž…๋‹ˆ๋‹ค. -1์—์„œ ์ ˆ์ฐจ๊ฐ€ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์ธก์ •์ด ์„ฑ๊ณตํ•˜๋ฉด Hiding์ด ์š”์ฒญ๋ฉ๋‹ˆ๋‹ค. ์—์ฝ” ์‘๋‹ต์€ ํ•ด๋‹น ์Šคํ‚ฌ์˜ ์„ฑ๊ณต์ ์ธ ์‚ฌ์šฉ์„ ์ฆ๋ช…ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
return  RunScenario();
 object? RunScenario()
{
    var pingMs = UO.GetPing(1000);
    if (Truth(pingMs == -1))
    {
        UO.Print("No fresh server response");
        return null;
    }

    UO.UseSkill("Hiding");
    return null;
}

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

3. GetPing - 3 - ์‹œ๋‚˜๋ฆฌ์˜ค ์ˆ˜์—…

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • MeanPing(์ƒ˜ํ”Œ, timeoutMs) ์ „์ฒด๊ฐ€ ํ‘œ์‹œ๋จ: 3๋Š” 500ms๋ฅผ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ์‹คํŒจํ•œ ์ธก์ •์€ ํ‰๊ท ์—์„œ ์ œ์™ธ๋ฉ๋‹ˆ๋‹ค. ์„ฑ๊ณตํ•œ ๊ฒƒ์ด ์—†์œผ๋ฉด -1๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ƒ˜ํ”Œ์€ 1โ€“10๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. UO.Wait(100)๋Š” ์‹œ๋„ ๊ฐ„ ์š”์ฒญ ๋น„์œจ์„ ์ค„์ž…๋‹ˆ๋‹ค.
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 meanMs = await MeanPing(3, 500);
        if (Truth(meanMs < 0))
        {
            UO.Print("No successful samples");
        }
        else
        {
            UO.Print("Measured mean, ms: " + Convert.ToString(meanMs));
        }

        return null;
    }

    async Task<dynamic> MeanPing(dynamic samples, dynamic timeoutMs)
    {
        if (Truth(samples < 1) || Truth(samples > 10))
        {
            return -1;
        }

        var total = 0;
        var count = 0;
        for (int i = (int)(1); i <= samples; i += (int)(1))
        {
            var current = UO.GetPing(timeoutMs);
            if (Truth(current >= 0))
            {
                total = total + current;
                count = count + 1;
            }

            await Delay(100);
        }

        if (Truth(count == 0))
        {
            return -1;
        }

        return total / count;
    }

    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#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.GetPing() โ€” UO.GetPing()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: int / Integer.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

public int GetPing() => bridge.GetPing();

UO.GetPing(timeout) โ€” UO.GetPing(Any)

๋งค๊ฐœ๋ณ€์ˆ˜: timeout (Any)

๊ฒฐ๊ณผ: int / Integer.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

public int GetPing(InjectionValue timeout) => bridge.GetPing(Math.Max(0, NumberConversions.ToInt(timeout)));

UO.IsOnline

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

int UO.IsOnline();

ํ˜„์žฌ ์„ธ์…˜์ด ๊ฒŒ์ž„ ์„ธ๊ณ„์— ์žˆ๋Š”์ง€, ๊ฒŒ์ž„ ์—ฐ๊ฒฐ์ด ์—ด๋ ค ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์บ๋ฆญํ„ฐ ํ–‰๋™ ์ „์ด๋‚˜ ์ž…์žฅ ๋Œ€๊ธฐ ์ค‘์— ์‚ฌ์šฉํ•˜์„ธ์š”.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

int. 1 - ํ”Œ๋ ˆ์ด์–ด, ๋กœ๋“œ๋œ ์นด๋“œ ๋ฐ ํ™œ์„ฑ ๊ฒŒ์ž„ ์†Œ์ผ“์ด ๋™์‹œ์— ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด 0. ์—ด๋ฆฐ ํด๋ผ์ด์–ธํŠธ ์ฐฝ, ์บ๋ฆญํ„ฐ ๋ชฉ๋ก ๋˜๋Š” ๋กœ๊ทธ์ธ ๋‹จ๊ณ„์˜ TCP ์—ฐ๊ฒฐ์€ 1๋ฅผ ์˜๋ฏธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ int: 1(์กฐ๊ฑด ์ถฉ์กฑ), 0(์กฐ๊ฑด ์ถฉ์กฑ๋˜์ง€ ์•Š์Œ). ์ด๋Š” ์ˆซ์ž ํ”Œ๋ž˜๊ทธ์ž…๋‹ˆ๋‹ค. C#์—์„œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜์„ธ์š”!= 0 ๋˜๋Š” ๊ฒฐ๊ณผ == 0์ž…๋‹ˆ๋‹ค. int์™€ true/false ๋ฐ if(๊ฒฐ๊ณผ)๋ฅผ ์ง์ ‘ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ช…๋ น์˜ ๊ฒฐ๊ณผ๋Š” ์ˆซ์ž ํ”Œ๋ž˜๊ทธ์ž…๋‹ˆ๋‹ค. 1๋Š” ์ถฉ์กฑ๋œ ์กฐ๊ฑด์„ ์˜๋ฏธํ•˜๊ณ , 0๋Š” ์ถฉ์กฑ๋˜์ง€ ์•Š์€ ์กฐ๊ฑด์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. var result = command(...) ํ›„์— (๊ฒฐ๊ณผ != 0) ๋˜๋Š” (๊ฒฐ๊ณผ == 0)์ธ์ง€ ํ™•์ธํ•˜์„ธ์š”. ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ณต๋œ ํ˜ธ์ถœ์„ ํ†ตํ•ด ํ•ด๋‹น ์ž‘์—…์„ ๋‹ค์‹œ ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜ ์ด๋ฏธ ๋ณ€๊ฒฝ๋œ ์ƒํƒœ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋™์ž‘

  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค: serial, type, ์บ๋ฆญํ„ฐ ์ด๋ฆ„ ๋ฐ IP๋Š” ์ „์†กํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. UO.Online(), UO.Connected(), UO.IsOnline()๋„ ๊ฐ™์€ ๊ฒƒ์„ ํ™•์ธํ•˜์„ธ์š”. ์ด๋Š” ๋‹ค๋ฅธ ๊ด€๋ฆฌ์ž ํ”„๋กœํ•„์ด ์•„๋‹Œ ํ•ด๋‹น ์„ธ์…˜ ์†Œ์œ ์ž์˜ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • UO.Wait์—๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ์ž๋™ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ์˜ˆ์ œ ์‹คํ–‰์„ ์ˆ˜๋™์œผ๋กœ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ™•์ธ์€ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์—๋งŒ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์€ ์ผ์‹œ ์ค‘์ง€๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €๋„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ bool๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฐ์—ด์ด๋ฉด ์š”์†Œ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

1. ๊ฒŒ์ž„ ์Šคํ‚ฌ์„ ์˜คํ”„๋ผ์ธ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜์ง€ ๋งˆ์„ธ์š” - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • false๋Š” 0์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. return์€ Main์„ UseSkill๋กœ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. ์Šคํ‚ฌ ์ด๋ฆ„์ธ UseSkill์˜ ์œ ์ผํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ•˜์ด๋“œ์ž…๋‹ˆ๋‹ค. 1๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๋Š” ์Šคํ‚ฌ ์‚ฌ์šฉ๋งŒ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” ์บ๋ฆญํ„ฐ์™€ ์„œ๋ฒ„์˜ ์ƒํƒœ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
if (Truth(Truth(UO.IsOnline()) == false))
{
    return null;
}
UO.UseSkill("Hiding");

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

2. ์—ฐ๊ฒฐ์ด ์—†์„ ๋•Œ ์—ฐ๊ฒฐ ์š”์ฒญ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • 0๊ณผ์˜ ๋น„๊ต๋Š” ์ž๋™ ์žฌ์—ฐ๊ฒฐ ์„ค์ •์ด ์•„๋‹Œ ํ˜„์žฌ ์—ฐ๊ฒฐ ์ƒํƒœ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ธ์ˆ˜๊ฐ€ ์—†๋Š” Connect๋Š” ์ €์žฅ๋œ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๊ณ  ๋กœ๊ทธ์ธ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ ์‹œ์ž‘๋œ ๋กœ๊ทธ์ธ ์ค‘์— ๋ช…๋ น์„ ๋ฐ˜๋ณตํ•ด๋„ ๋‘ ๋ฒˆ์งธ ์„ธ์…˜์ด ์ƒ์„ฑ๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.IsOnline() == 0))
    {
        UO.Connect();
    }

    return null;
}

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

3. ์‹œ๊ฐ„ ์ œํ•œ์œผ๋กœ ์„ธ์ƒ์ด ์ค€๋น„๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ - ์‹œ๋‚˜๋ฆฌ์˜ค ์ˆ˜์—…

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • WaitForWorld(timeoutMs)๋Š” ๋‚ด์žฅ ๋ช…๋ น์ด ์•„๋‹Œ ์™„์ „ํžˆ ํ‘œ์‹œ๋œ ์‚ฌ์šฉ์ž ์ •์˜ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. 5000 โ€” ์˜ˆ์‚ฐ(๋ฐ€๋ฆฌ์ดˆ), UO.Wait(50) โ€” ํ™•์ธ ๊ฐ„๊ฒฉ. ์Œ์ˆ˜ ๊ฐ’์€ false๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. 0 ๊ธฐ์„ฑ ์„ธ๊ณ„๋งŒ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค. Timer๋Š” ์ดˆ๋ฅผ ์ธก์ •ํ•˜๋ฏ€๋กœ ๊ทธ ์ฐจ์ด์— 1000์„ ๊ณฑํ•ฉ๋‹ˆ๋‹ค. ์ž๋™ ์ผ์‹œ์ค‘์ง€๋Š” ๋ฏธ๋ฆฌ ๊บผ์•ผ ํ•˜๋ฉฐ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” Connect๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉฐ ์‹œ๊ฐ„์ด ๋งŒ๋ฃŒ๋˜์–ด๋„ ์‹œ์ž‘๋œ ์ž…๋ ฅ์„ ์ทจ์†Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
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()
    {
        if (Truth(UO.GetPauseScriptOnDisconnectStatus()))
        {
            return null;
        }

        if (Truth(await WaitForWorld(5000)))
        {
            UO.UseSkill("Hiding");
        }

        return null;
    }

    async Task<dynamic> WaitForWorld(dynamic timeoutMs)
    {
        if (Truth(timeoutMs < 0))
        {
            return false;
        }

        var started = Environment.TickCount;
        while (!(Truth(UO.IsOnline())))
        {
            if (Truth((Environment.TickCount - started) * 1000.0 >= timeoutMs))
            {
                return false;
            }

            await Delay(50);
        }

        return true;
    }

    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#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.IsOnline() โ€” UO.IsOnline()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: int / Integer.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

public int IsOnline() => bridge.IsOnline();

UO.Online

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

int UO.Online();

ํ˜„์žฌ ์„ธ์…˜์ด ๊ฒŒ์ž„ ์„ธ๊ณ„์— ์žˆ๋Š”์ง€, ๊ฒŒ์ž„ ์—ฐ๊ฒฐ์ด ์—ด๋ ค ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์บ๋ฆญํ„ฐ ํ–‰๋™ ์ „์ด๋‚˜ ์ž…์žฅ ๋Œ€๊ธฐ ์ค‘์— ์‚ฌ์šฉํ•˜์„ธ์š”.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

int. 1 - ํ”Œ๋ ˆ์ด์–ด, ๋กœ๋“œ๋œ ์นด๋“œ ๋ฐ ํ™œ์„ฑ ๊ฒŒ์ž„ ์†Œ์ผ“์ด ๋™์‹œ์— ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด 0. ์—ด๋ฆฐ ํด๋ผ์ด์–ธํŠธ ์ฐฝ, ์บ๋ฆญํ„ฐ ๋ชฉ๋ก ๋˜๋Š” ๋กœ๊ทธ์ธ ๋‹จ๊ณ„์˜ TCP ์—ฐ๊ฒฐ์€ 1๋ฅผ ์˜๋ฏธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ int: 1(์กฐ๊ฑด ์ถฉ์กฑ), 0(์กฐ๊ฑด ์ถฉ์กฑ๋˜์ง€ ์•Š์Œ). ์ด๋Š” ์ˆซ์ž ํ”Œ๋ž˜๊ทธ์ž…๋‹ˆ๋‹ค. C#์—์„œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜์„ธ์š”!= 0 ๋˜๋Š” ๊ฒฐ๊ณผ == 0์ž…๋‹ˆ๋‹ค. int์™€ true/false ๋ฐ if(๊ฒฐ๊ณผ)๋ฅผ ์ง์ ‘ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ช…๋ น์˜ ๊ฒฐ๊ณผ๋Š” ์ˆซ์ž ํ”Œ๋ž˜๊ทธ์ž…๋‹ˆ๋‹ค. 1๋Š” ์ถฉ์กฑ๋œ ์กฐ๊ฑด์„ ์˜๋ฏธํ•˜๊ณ , 0๋Š” ์ถฉ์กฑ๋˜์ง€ ์•Š์€ ์กฐ๊ฑด์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. var result = command(...) ํ›„์— (๊ฒฐ๊ณผ != 0) ๋˜๋Š” (๊ฒฐ๊ณผ == 0)์ธ์ง€ ํ™•์ธํ•˜์„ธ์š”. ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ณต๋œ ํ˜ธ์ถœ์„ ํ†ตํ•ด ํ•ด๋‹น ์ž‘์—…์„ ๋‹ค์‹œ ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜ ์ด๋ฏธ ๋ณ€๊ฒฝ๋œ ์ƒํƒœ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋™์ž‘

  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค: serial, type, ์บ๋ฆญํ„ฐ ์ด๋ฆ„ ๋ฐ IP๋Š” ์ „์†กํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. UO.Online(), UO.Connected(), UO.IsOnline()๋„ ๊ฐ™์€ ๊ฒƒ์„ ํ™•์ธํ•˜์„ธ์š”. ์ด๋Š” ๋‹ค๋ฅธ ๊ด€๋ฆฌ์ž ํ”„๋กœํ•„์ด ์•„๋‹Œ ํ•ด๋‹น ์„ธ์…˜ ์†Œ์œ ์ž์˜ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • UO.Wait์—๋Š” ๋ฐ€๋ฆฌ์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ์ž๋™ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ์˜ˆ์ œ ์‹คํ–‰์„ ์ˆ˜๋™์œผ๋กœ ์ผ์‹œ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ™•์ธ์€ ์ผ์‹œ ์ค‘์ง€๊ฐ€ ์ œ๊ฑฐ๋œ ํ›„์—๋งŒ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ช…๋ น์€ ์ผ์‹œ ์ค‘์ง€๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ž๋™ ์žฌ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €๋„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ bool๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฐ์—ด์ด๋ฉด ์š”์†Œ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

1. ๊ฒŒ์ž„ ์Šคํ‚ฌ์„ ์˜คํ”„๋ผ์ธ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜์ง€ ๋งˆ์„ธ์š” - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • false๋Š” 0์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. return์€ Main์„ UseSkill๋กœ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. ์Šคํ‚ฌ ์ด๋ฆ„์ธ UseSkill์˜ ์œ ์ผํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ•˜์ด๋“œ์ž…๋‹ˆ๋‹ค. 1๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๋Š” ์Šคํ‚ฌ ์‚ฌ์šฉ๋งŒ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” ์บ๋ฆญํ„ฐ์™€ ์„œ๋ฒ„์˜ ์ƒํƒœ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
if (Truth(Truth(UO.Online()) == false))
{
    return null;
}
UO.UseSkill("Hiding");

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

2. ์—ฐ๊ฒฐ์ด ์—†์„ ๋•Œ ์—ฐ๊ฒฐ ์š”์ฒญ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • 0๊ณผ์˜ ๋น„๊ต๋Š” ์ž๋™ ์žฌ์—ฐ๊ฒฐ ์„ค์ •์ด ์•„๋‹Œ ํ˜„์žฌ ์—ฐ๊ฒฐ ์ƒํƒœ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ธ์ˆ˜๊ฐ€ ์—†๋Š” Connect๋Š” ์ €์žฅ๋œ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๊ณ  ๋กœ๊ทธ์ธ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ ์‹œ์ž‘๋œ ๋กœ๊ทธ์ธ ์ค‘์— ๋ช…๋ น์„ ๋ฐ˜๋ณตํ•ด๋„ ๋‘ ๋ฒˆ์งธ ์„ธ์…˜์ด ์ƒ์„ฑ๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.Online() == 0))
    {
        UO.Connect();
    }

    return null;
}

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

3. ์‹œ๊ฐ„ ์ œํ•œ์œผ๋กœ ์„ธ์ƒ์ด ์ค€๋น„๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ธฐ - ์‹œ๋‚˜๋ฆฌ์˜ค ์ˆ˜์—…

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • WaitForWorld(timeoutMs)๋Š” ๋‚ด์žฅ ๋ช…๋ น์ด ์•„๋‹Œ ์™„์ „ํžˆ ํ‘œ์‹œ๋œ ์‚ฌ์šฉ์ž ์ •์˜ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. 5000 โ€” ์˜ˆ์‚ฐ(๋ฐ€๋ฆฌ์ดˆ), UO.Wait(50) โ€” ํ™•์ธ ๊ฐ„๊ฒฉ. ์Œ์ˆ˜ ๊ฐ’์€ false๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. 0 ๊ธฐ์„ฑ ์„ธ๊ณ„๋งŒ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค. Timer๋Š” ์ดˆ๋ฅผ ์ธก์ •ํ•˜๋ฏ€๋กœ ๊ทธ ์ฐจ์ด์— 1000์„ ๊ณฑํ•ฉ๋‹ˆ๋‹ค. ์ž๋™ ์ผ์‹œ์ค‘์ง€๋Š” ๋ฏธ๋ฆฌ ๊บผ์•ผ ํ•˜๋ฉฐ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” Connect๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉฐ ์‹œ๊ฐ„์ด ๋งŒ๋ฃŒ๋˜์–ด๋„ ์‹œ์ž‘๋œ ์ž…๋ ฅ์„ ์ทจ์†Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ด ๋ช…๋ น์€ ๋กœ์ปฌ ์ƒํƒœ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค. ํ•‘์„ ๋ณด๋‚ด์ง€ ์•Š๊ณ , ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๊ณ , ์ผ์‹œ ์ค‘์ง€ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ธํ„ฐ๋„ท ๊ฐ€์šฉ์„ฑ์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ์€ ํ›„ ์—ฐ๊ฒฐ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋Š” ๋‹ค์Œ ์ž‘์—…์˜ ์„ฑ๊ณต์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
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()
    {
        if (Truth(UO.GetPauseScriptOnDisconnectStatus()))
        {
            return null;
        }

        if (Truth(await WaitForWorld(5000)))
        {
            UO.UseSkill("Hiding");
        }

        return null;
    }

    async Task<dynamic> WaitForWorld(dynamic timeoutMs)
    {
        if (Truth(timeoutMs < 0))
        {
            return false;
        }

        var started = Environment.TickCount;
        while (!(Truth(UO.Online())))
        {
            if (Truth((Environment.TickCount - started) * 1000.0 >= timeoutMs))
            {
                return false;
            }

            await Delay(50);
        }

        return true;
    }

    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#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.Online() โ€” UO.Online()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: int / Integer.

ํ˜ธ์ถœ ์‹œ:

ํ˜ธ์ถœ ์‹œ ์ €์žฅ๋œ ์ฒ˜๋ฆฌ๊ธฐ delegate๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋“ฑ๋ก ๋ฉ”์„œ๋“œ๋Š” API๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ์ด delegate๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

() => bridge.IsOnline()

API ์ƒ์„ฑ: ์ด ํ•จ์ˆ˜๋“ค์€ API๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. ๋ช…๋ น์„ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๋‹ค์‹œ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


UO.Resend

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

void UO.Resend();

์„ธ๊ณ„๋ฅผ ๋‹ค์‹œ ๋™๊ธฐํ™”ํ•˜๋ผ๋Š” ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

void - ๊ฐ’์ด ์—†์Šต๋‹ˆ๋‹ค. ๋ณ„๋„์˜ ํšŒ์„ ์œผ๋กœ ์ „ํ™”ํ•˜์„ธ์š”. ์™„๋ฃŒ๋Š” ์„œ๋ฒ„์˜ ์ž‘์—…์„ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋™์ž‘

  • Resync๋Š” ๊ฒŒ์ž„ ์Šค๋ ˆ๋“œ์—์„œ NetClient.Socket.Send_Resync๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์ด๋Š” ์žฌ์—ฐ๊ฒฐ์ด๋‚˜ ๋ฐ์ดํ„ฐ ์ˆ˜์‹  ํ™•์ธ์ด ์•„๋‹Œ ์—…๋ฐ์ดํŠธ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.
  • ์˜ˆ์ œ์—์„œ UO.Wait๋Š” ์Šคํฌ๋ฆฝํŠธ ์ผ์‹œ ์ค‘์ง€๋งŒ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ผ์‹œ ์ค‘์ง€๊ฐ€ ๋๋‚ฌ๋‹ค๊ณ  ํ•ด์„œ ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์„ ์™„๋ฃŒํ–ˆ์Œ์„ ์ฆ๋ช…ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๋ช…๋ น์€ ๋…๋ฆฝ๋œ ๋ฌธ์ž…๋‹ˆ๋‹ค. ์•ž์˜ ๋ฉ”์‹œ์ง€๋Š” ํ˜ธ์ถœ ์‹œ์ž‘์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ ์„œ๋ฒ„ ๋™์ž‘์˜ ์™„๋ฃŒ๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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

1. ์ง์ ‘ ํ†ตํ™” - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ์„ธ๊ณ„๋ฅผ ๋‹ค์‹œ ๋™๊ธฐํ™”ํ•˜๋ผ๋Š” ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
UO.Resend();

2. ๋ช…์‹œ์  ์˜ต์…˜ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • Resync๋Š” ๊ฒŒ์ž„ ์Šค๋ ˆ๋“œ์—์„œ NetClient.Socket.Send_Resync๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์ด๋Š” ์žฌ์—ฐ๊ฒฐ์ด๋‚˜ ๋ฐ์ดํ„ฐ ์ˆ˜์‹  ํ™•์ธ์ด ์•„๋‹Œ ์—…๋ฐ์ดํŠธ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.
return  RunScenario();
 object? RunScenario()
{
    if (Truth(UO.IsOnline()))
    {
        UO.Resend();
    }

    return null;
}

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

3. ์ „์ฒด ๋„์šฐ๋ฏธ ๊ธฐ๋Šฅ - ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ์˜ˆ์ œ์—์„œ 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()
    {
        UO.Resend();
        UO.Wait(500);
        UO.Print(UO.GetX());
        return null;
    }
}

๋ช…๋ น ๊ตฌํ˜„

C#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.Resend() โ€” UO.Resend()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: void / Unit.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "resend": bridge.Resync(); break;

UO.ShardName

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

dynamic UO.ShardName();

์ƒค๋“œ ์ด๋ฆ„์„ ์ฝ์Šต๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

string โ€” ๋ธŒ๋ฆฌ์ง€ ํ•„๋“œ์˜ ํ…์ŠคํŠธ.ShardName; ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉด ๋นˆ ๋ฌธ์ž์—ด์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์—ฐ๊ฒฐ ๊ธฐํ˜ธ๊ฐ€ ์•„๋‹ˆ๋ฉฐ ์ˆซ์ž ID๋„ ์•„๋‹™๋‹ˆ๋‹ค.

๋™์ž‘

  • ExecuteClientApiCompatibility๋Š” ํ”„๋กœํ•„์ด๋‚˜ ์„œ๋ฒ„ ์„ ํƒ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๋ธŒ๋ฆฌ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.ShardName.
  • ํ˜„์žฌ ๋กœ์ปฌ ์ƒํƒœ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค. ํŒจํ‚ค์ง€, ๋Œ€์ƒ ๋˜๋Š” ์ž๋™ ์—…๋ฐ์ดํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ์ฝ๊ธฐ์—์„œ๋Š” ๋‹ค๋ฅธ ์ƒํƒœ๊ฐ€ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €๋„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ bool๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฐ์—ด์ด๋ฉด ์š”์†Œ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

1. ์ง์ ‘ ํ†ตํ™” - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ์ƒค๋“œ ์ด๋ฆ„์„ ์ฝ์Šต๋‹ˆ๋‹ค.
var value = UO.ShardName();
UO.Print(value);

2. ๋ช…์‹œ์  ์˜ต์…˜ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ExecuteClientApiCompatibility๋Š” ํ”„๋กœํ•„์ด๋‚˜ ์„œ๋ฒ„ ์„ ํƒ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๋ธŒ๋ฆฌ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.ShardName.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.ShardName();
    if (Truth(Len(value) > 0))
    {
        UO.TextPrint(value);
    }

    return null;
}

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

3. ์ „์ฒด ๋„์šฐ๋ฏธ ๊ธฐ๋Šฅ - ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ํ˜„์žฌ ๋กœ์ปฌ ์ƒํƒœ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค. ํŒจํ‚ค์ง€, ๋Œ€์ƒ ๋˜๋Š” ์ž๋™ ์—…๋ฐ์ดํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ์ฝ๊ธฐ์—์„œ๋Š” ๋‹ค๋ฅธ ์ƒํƒœ๊ฐ€ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
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 before = UO.ShardName();
        UO.Wait(500);
        var after = UO.ShardName();
        UO.Print(before = after);
        return null;
    }
}

๋ช…๋ น ๊ตฌํ˜„

C#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.ShardName() โ€” UO.ShardName()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: dynamic / Any.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "shardname":

                case "profileshardname": return new InjectionValue(bridge.ShardName);

UO.ShardPath

ะฃะบั€ะฐั—ะฝััŒะบะฐ ยท ะ ัƒััะบะธะน ยท English ยท Deutsch ยท Franรงais ยท Italiano ยท Espaรฑol ยท ็น้ซ”ไธญๆ–‡ ยท ๆ—ฅๆœฌ่ชž ยท ํ•œ๊ตญ์–ด

C# ์‹œ๊ทธ๋‹ˆ์ฒ˜

dynamic UO.ShardPath();

ํ˜„์žฌ ํ”„๋กœํ•„์˜ ๊ฒฝ๋กœ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

string โ€” ๋ธŒ๋ฆฌ์ง€ ํ•„๋“œ์˜ ํ…์ŠคํŠธ.CurrentProfilePath; ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉด ๋นˆ ๋ฌธ์ž์—ด์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์—ฐ๊ฒฐ ๊ธฐํ˜ธ๊ฐ€ ์•„๋‹ˆ๋ฉฐ ์ˆซ์ž ID๋„ ์•„๋‹™๋‹ˆ๋‹ค.

๋™์ž‘

  • ExecuteClientApiCompatibility๋Š” ํ”„๋กœํ•„์ด๋‚˜ ์„œ๋ฒ„ ์„ ํƒ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๋ธŒ๋ฆฌ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.CurrentProfilePath.
  • ํ˜„์žฌ ๋กœ์ปฌ ์ƒํƒœ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค. ํŒจํ‚ค์ง€, ๋Œ€์ƒ ๋˜๋Š” ์ž๋™ ์—…๋ฐ์ดํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ์ฝ๊ธฐ์—์„œ๋Š” ๋‹ค๋ฅธ ์ƒํƒœ๊ฐ€ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋…๋ฆฝ ์‹คํ–‰ C# ์Šคํฌ๋ฆฝํŠธ

๊ฐ ์˜ˆ์ œ๋Š” ๋ณ„๋„์˜ ํŒŒ์ผ .csx๋กœ ์ €์žฅํ•˜๊ณ  IDE์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UO ๊ฐœ์ฒด์™€ ๋Œ€๊ธฐ ๊ธฐ๋Šฅ์€ ํ˜„์žฌ ๊ฒŒ์ž„ ์„ธ์…˜์˜ ํ˜ธ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ๋ชจ serial ์ด๋ฆ„, ์ขŒํ‘œ, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

๊ฐ„๋‹จํ•œ ์˜ˆ์ œ

์ด ์ฝ”๋“œ๋ฅผ ๋ณ„๋„์˜ .csx ํŒŒ์ผ๋กœ ์‹คํ–‰ํ•˜์„ธ์š”. ์ธ์ˆ˜๋Š” ํ˜ธ์ถœ์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ ์ด๋ฆ„, serial, ์ฃผ์†Œ๋ฅผ ์ž์‹ ์˜ ๊ฐ’์œผ๋กœ ๋ฐ”๊พธ์„ธ์š”.

ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์ €๋„์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž๋ฅผ bool๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฐ์—ด์ด๋ฉด ์š”์†Œ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

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

1. ์ง์ ‘ ํ†ตํ™” - ์ง์ ‘ ์Šคํฌ๋ฆฝํŠธ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ํ˜„์žฌ ํ”„๋กœํ•„์˜ ๊ฒฝ๋กœ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค.
var value = UO.ShardPath();
UO.Print(value);

2. ๋ช…์‹œ์  ์˜ต์…˜ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ExecuteClientApiCompatibility๋Š” ํ”„๋กœํ•„์ด๋‚˜ ์„œ๋ฒ„ ์„ ํƒ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๋ธŒ๋ฆฌ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.CurrentProfilePath.
return  RunScenario();
 object? RunScenario()
{
    var value = UO.ShardPath();
    if (Truth(Len(value) > 0))
    {
        UO.TextPrint(value);
    }

    return null;
}

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

3. ์ „์ฒด ๋„์šฐ๋ฏธ ๊ธฐ๋Šฅ - ์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์‹คํ–‰ ํ๋ฆ„:

  • ํ˜„์žฌ ๋กœ์ปฌ ์ƒํƒœ๋ฅผ ์ฝ์Šต๋‹ˆ๋‹ค. ํŒจํ‚ค์ง€, ๋Œ€์ƒ ๋˜๋Š” ์ž๋™ ์—…๋ฐ์ดํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ์ฝ๊ธฐ์—์„œ๋Š” ๋‹ค๋ฅธ ์ƒํƒœ๊ฐ€ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
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 before = UO.ShardPath();
        UO.Wait(500);
        var after = UO.ShardPath();
        UO.Print(before = after);
        return null;
    }
}

๋ช…๋ น ๊ตฌํ˜„

C#์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ UO ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์ˆซ์ž ํ”Œ๋ž˜๊ทธ๋Š” 0๊ณผ ๋น„๊ตํ•˜๊ณ  ๋ฐ˜ํ™˜ ํ˜•์‹์ด bool์ผ ๋•Œ๋งŒ bool์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

UO.ShardPath() โ€” UO.ShardPath()

๋งค๊ฐœ๋ณ€์ˆ˜: ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ: dynamic / Any.

ํ˜ธ์ถœ ์‹œ:

๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ์ด๋ฉฐ ๋…๋ฆฝ ์Šคํฌ๋ฆฝํŠธ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

case "shardpath":

                case "clientprofilepath": return new InjectionValue(bridge.CurrentProfilePath);
โš ๏ธ **GitHub.com Fallback** โš ๏ธ