XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text;
using System.Text.Json;

namespace XFEEDToolBox.Plugin;

internal static unsafe partial class Navigation
{
    private sealed class CommerceCompletion(CommerceReadRequest work, byte[] body, uint capacity)
    {
        internal CommerceReadRequest work = work;
        internal readonly ulong generation = work.generation;
        internal readonly byte[] body = body;
        internal readonly uint capacity = capacity;
        internal string text = "";
        internal bool ready;
    }
    private static CommerceCompletion? commerceCompletion;

    // Only immutable response bytes reach this worker. No game objects or
    // original callbacks may be dereferenced outside the owning game thread.
    private static void PrepareCommerceCompletion(CommerceCompletion completion)
    {
        var work = completion.work;
        try
        {
            completion.text = Encoding.UTF8.GetString(completion.body);
            fixed (byte* body = completion.body)
            {
                var length = (nuint)completion.body.Length;
                if (work.kind == 1)
                {
                    work.serviceReplyVerified = ValidateCommerceMutationBody(work, body, length);
                    if (!work.serviceReplyVerified) { work.state = 4; work.error = 7; }
                }
                else if (work.kind == 0 && work.refreshClient)
                {
                    using var document = JsonDocument.Parse(completion.body);
                    work.profileValidated = CommerceProfileValues(document.RootElement, completion.capacity, out work.serverCredits, out work.serverCargo);
                    if (!work.profileValidated) { work.state = 4; work.error = 11; }
                }
                else if (work.kind >= 4 && !ValidateOriginalServiceMutation(work, body, length))
                { work.state = 4; work.error = 9; }
            }
        }
        catch { work.state = 4; work.error = work.kind == 0 ? 12u : work.kind == 1 ? 8u : 10u; }
        finally { completion.work = work; Volatile.Write(ref completion.ready, true); }
    }

    private static bool CommerceWorkCurrent(in Snapshot frame, ref CommerceReadRequest work)
    {
        work.error = 1;
        if (GetCurrentThreadId() != owningThread || !Enabled() || !inGame || !frame.valid || !frame.healthValid
            || frame.hullFraction<=0 || frame.healthEmergency || GetTickCount64() - frame.tick > 200)
        { work.state = 4; return false; }
        work.error = 2;
        if (work.entity != frame.entity || work.life != frame.life || work.epoch != controllerEpoch
            || work.expires <= GetTickCount64() || !CommerceDocked(frame, work.market))
        { work.state = 4; return false; }
        work.error = 0; return true;
    }

    private static void PollCommerceCompletion(in Snapshot frame, CommerceCompletion completion)
    {
        if (!Volatile.Read(ref completion.ready)) return;
        var work = completion.work;
        if (work.generation != commerceRead.generation) return;
        // A completed network response never authorizes a stale ship/menu.
        if (work.state == 3 && CommerceWorkCurrent(frame, ref work))
        {
            fixed (byte* body = completion.body)
            {
                var length = (nuint)completion.body.Length;
                try
                {
                    if (work.kind == 1 && !ApplyCommerceMutation(frame, ref work, body, length))
                    { work.state = 4; if (work.error == 0) work.error = 7; }
                    if (work.kind == 0 && work.refreshClient && !ApplyCommerceProfile(frame, ref work, body, length))
                    { work.state = 4; if (work.error == 0) work.error = 11; }
                    if (work.kind >= 4 && !ApplyOriginalServiceMutation(frame, ref work, body, length))
                    { work.state = 4; if (work.error == 0) work.error = 9; }
                }
                catch { work.state = 4; work.error = work.kind == 0 ? 12u : work.kind == 1 ? 8u : 10u; }
            }
        }
        if (work.state == 3) work.observed = GetTickCount64();
        commerceRead = work; commerceReadBody = completion.text;
        if ((work.kind == 1 || work.kind >= 4) && work.mutationSent && !work.clientApplied) commerceReconciliationRequired = true;
        CaptureServiceQuote(work, commerceReadBody);
        commerceCompletion = null;
    }

    private static bool CommerceNonBlockingFixture()
    {
        // The fixture caller holds commerceReadLock. A competing tick must
        // return while that lock is still held, without dispatching anything.
        var tick = Task.Run(() => PollCommerceRead(default));
        if (!tick.Wait(TimeSpan.FromSeconds(1))) return false;
        var work = new CommerceReadRequest { kind = 1, commodity = 128049172, delta = 192, before = 0, after = 192, creditsBefore = 2000000, price = 7241, state = 3 };
        var valid = new CommerceCompletion(work, "{\"credits\":609728,\"inventory\":[{\"commodity\":\"uranium\",\"qty\":192}]}"u8.ToArray(), 192);
        PrepareCommerceCompletion(valid);
        var invalid = new CommerceCompletion(work, "{\"credits\":609702,\"inventory\":[{\"commodity\":\"uranium\",\"qty\":192}]}"u8.ToArray(), 192);
        PrepareCommerceCompletion(invalid);
        return Volatile.Read(ref valid.ready) && valid.work.state == 3 && valid.work.serviceReplyVerified
            && Volatile.Read(ref invalid.ready) && invalid.work.state == 4 && !invalid.work.serviceReplyVerified;
    }
}