Lingara Lingara لارښود لارښودونه API کتابتونونه اپلیکیشنونه جوړول ځای پر ځای کول ویب اپلیکیشن
ژبه: پښتو

Godot

دا پاڼه له انګلیسي ژبې ژباړل شوې ده. که دواړه سره توپیر ولري، انګلیسي پاڼه سمه ده. انګلیسي پاڼه ولولئ

Godot دوه ژبې وړاندې کوي، او Lingara د هرې یوې لپاره یو کیټ لري. د GDScript لوبه د Lingara اډان کاروي. د Godot C# لوبه Lingara.Embed کاروي، هماغه کڅوړه چې د Unity لوبه یې کاروي. په یوه پروژه کې له دې دوو څخه یو وکاروئ، هېڅکله دواړه نه. لاندې ټبونه هر یو ښيي.

نصبول

GDScript. د Lingara اډان د Godot Asset Library څخه نصب کړئ، بیا یې د Project Settings، Plugins لاندې فعال کړئ. د فعالولو سره یو autoload ور زیاتېږي چې نوم یې Lingara دی، او هره صحنه یې په /root/Lingara کې رسي.

C#. Lingara.Embed خپلې پروژې ته د کڅوړې د حوالې په توګه ور زیات کړئ. لاندې نمونه نوډ، LingaraEmbedNode، د کڅوړې برخه نه ده: د هغه سرچینه خپلې پروژې ته ور زیاته کړئ او په یوه صحنه کې یې کېږدئ.

ټوکنونه له خپل سرور څخه واخلئ

هېڅ یو کیټ راز نه ساتي. کله چې هسته ټوکن ته اړتیا ولري، ستاسو له خپل سرور څخه یې غواړي، چې د یوه سرور کیټ په مرسته یو ټوکن جوړوي او د ټوکن او د هغه د پای ته رسېدو د وخت په لېږلو ځواب ورکوي.

د اډان سره، د خپل سرور د ټوکن لاره د Project Settings لاندې وټاکئ او Lingara یې په خپل جلا تار کې کال کوي. که لاره د لوبغاړي ناستې ته اړتیا ولري، پر ځای یې د چلېدو پر مهال وټاکئ، ځکه چې د پروژې تنظیمات ستاسو د export دننه لېږدول کېږي. یا token_needed وصل کړئ او هرې غوښتنې ته پخپله ځواب ورکړئ. د C# سره، نمونه نوډ هر ځل چې کلاینټ ټوکن وغواړي ستاسو د ټوکن لارې ته غوښتنه لېږي. په هره توګه، ناکامي د token_unavailable یا TokenUnavailable په مرسته راپور کړئ، ترڅو هغه کالونه چې انتظار باسي سمدستي ناکام شي.

پېښې په هر چوکاټ کې پروسس کړئ

هسته د شبکې خپل I/O په خپل جلا تار کې چلوي. د اډان autoload هغه په هر چوکاټ کې یو ځل خالي کوي او د هرې پېښې لپاره یو سیګنال خپروي، نو تاسو هغه سیګنالونه وصلوئ چې ستاسو لوبه یې اړتیا لري او هېڅکله پخپله هېڅ شی نه خالي کوئ. د C# نوډ په _process کې خالي کوي، په یوه چوکاټ کې تر 256 پېښو پورې، او هره یوه بیا د Godot د یوه سیګنال په توګه خپروي.

هماغه سیګنالونه د NPC هغه ځوابونه هم وړي چې په برخو کې راځي (وګورئ د NPC خبرې اترې) او د تمرین تازه معلومات (وګورئ د تمرین پایلې).

<PackageReference Include="Lingara.Embed" Version="0.1.0-alpha.6" />
د کوډ بېلګې ژبه

Godot C#

// Your own server mints the token: never put a client secret in a game. The
// continuation may run off the main thread, which the client allows.
private async Task FetchToken()
{
    try
    {
        using var response = await Http.PostAsync(TokenUrl, new StringContent("{}"));
        response.EnsureSuccessStatusCode();
        using var body = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
        Client?.ProvideToken(body.RootElement.GetProperty("token").GetString(), body.RootElement.GetProperty("expires_at").GetString());
    }
    catch (Exception e) when (e is HttpRequestException || e is JsonException || e is KeyNotFoundException)
    {
        Client?.TokenUnavailable(e.Message); // fail the waiting calls now
    }
}

GDScript

# The common case: set Project Settings > lingara/token_url to your server's
# token route, which answers exactly {"token", "expires_at"}. Lingara POSTs to
# it on its own thread whenever it needs a token. If the route needs the
# player's session, set it at run time instead (never in ProjectSettings,
# which ships inside the export):
func use_my_session(session_cookie: String) -> void:
	lingara.set_token_endpoint("https://game.example.com/lingara-token", {"cookie": session_cookie})


# Or answer each token_needed yourself, with whatever login your game has.
func _on_token_needed(_request: int, _reason: String) -> void:
	var http := HTTPRequest.new()
	add_child(http)
	http.request("https://game.example.com/lingara-token", [], HTTPClient.METHOD_POST, "{}")
	var reply: Array = await http.request_completed
	http.queue_free()
	var body: Variant = JSON.parse_string((reply[3] as PackedByteArray).get_string_from_utf8())
	if reply[1] == 200 and body is Dictionary:
		lingara.provide_token(body["token"], body["expires_at"])
	else:
		lingara.token_unavailable("the token route answered %d" % reply[1])
د کوډ بېلګې ژبه

Godot C#

public override void _Process(double delta)
{
    if (Client == null) return;
    events.Clear();
    Client.Drain(events); // at most 256 a frame; the rest wait for the next
    foreach (var e in events)
    {
        switch (e)
        {
            case EmbedEvent.TokenNeeded _: _ = FetchToken(); break;
            case EmbedEvent.NpcTurn { Update: NpcTurnUpdate.Fragment f } t:
                EmitSignal(SignalName.NpcTurnFragment, t.Dialogue.Value, t.Request.Value, f.Text); break;
            case EmbedEvent.NpcTurn { Update: NpcTurnUpdate.Finished f } t:
                EmitSignal(SignalName.NpcTurnFinished, t.Dialogue.Value, t.Request.Value, f.Text); break;
            case EmbedEvent.Practice p: EmitSignal(SignalName.PracticeChanged, p.Session.Value, p.Snapshot.Phase.ToString()); break;
            case EmbedEvent.Failed f: EmitSignal(SignalName.Failed, f.Error.KindName, f.Error.Message, f.Error.Request?.Value ?? 0); break;
            case EmbedEvent.Log log: GD.Print($"[lingara] {log.Level} {log.Target}: {log.Message}"); break;
        }
    }
}

GDScript

# The Lingara autoload the plugin adds, reached by path and typed, so every
# call and signal below is checked against LingaraEmbed.
@onready var lingara: LingaraEmbed = get_node("/root/Lingara")

# Enable the plugin (Project > Project Settings > Plugins): it adds the
# Lingara autoload, which drains the core once per frame and emits one signal
# per event. Connect the signals your game needs; you never call drain.
func _ready() -> void:
	lingara.token_needed.connect(_on_token_needed)
	lingara.event_received.connect(_on_event)
	lingara.error_raised.connect(func(error: Dictionary) -> void: push_warning(error.message))
	lingara.practice_changed.connect(_on_practice_changed)
	lingara.practice_finished.connect(_on_practice_finished)
	mei.replied.connect(_on_mei_replied)


func _on_event(_id: String, event_type: String, _created_at: String, data: Dictionary) -> void:
	if event_type == "lesson_plan.ready":
		print("a plan is ready: ", data.get("plan_id"))