using System.Text.Json;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Navigation;
using XFEEDToolBox.Core.Data;
using XFEEDToolBox.Core.Execution;
using XFEEDToolBox.Core.Native;
internal static class NativeCommunityGoals
{
internal static async Task JoinTradeAsync(int pid,string directory)
{
var settings=ToolboxSettings.Load(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"XFEstudio","XFEEDToolBox","settings.json"));
await using var journal=new JournalMonitor(settings.JournalDirectory);await journal.StartAsync();var initial=journal.State;
await using var protection=await FlightTestProtectionScope.ArmAsync(pid);
var channel=new NativeCommerceChannel(pid);var hello=await channel.CallAsync(new{op="describe"},CancellationToken.None);
if(hello.GetProperty("gameSha256").GetString()!=NativeSystemLocationReader.GameSha256||!hello.GetProperty("nativeCommunityGoals").GetBoolean())
throw new InvalidOperationException("Verified original CG capability required.");
async Task Check(CancellationToken token)
{
token.ThrowIfCancellationRequested();var player=journal.State;
if(!player.InGame||!player.Docked||player.MarketId!=CommunityGoalCatalogue.HomerMarket||player.CurrentShipId!=5||string.IsNullOrWhiteSpace(initial.CommanderId)||player.CommanderId!=initial.CommanderId
||player.LoadGameAt!=initial.LoadGameAt||protection.Stopped||NavigationSafety.HasExternalThreat(player))
throw new InvalidOperationException("Actual Homer session or ship changed before CG signup.");
var health=await channel.CallAsync(new{op="health.read"},token);
if(!health.GetProperty("localPlayerShipVerified").GetBoolean()||!health.GetProperty("shipHealth").GetProperty("verified").GetBoolean()
||health.GetProperty("shipHealth").GetProperty("hullFraction").GetDouble()<.5)
throw new InvalidOperationException("Independent healthy main-ship observation required.");
}
using var timeout=new CancellationTokenSource(TimeSpan.FromSeconds(100));
var goal=await new NativeCommunityGoalClient(channel).EnsureTradeJoinedAsync(directory,Check,timeout.Token);
Console.WriteLine(JsonSerializer.Serialize(new{confirmed=true,goal,screenUse=false,rewardsClaimed=0}));
}
internal static async Task ReadAsync(int pid,bool mine,string report)
{
if(File.Exists(report))throw new IOException("Use a new CG response report.");
var pipe=new NavigationPipeClient(pid);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(40));
var hello=await pipe.CallAsync(new{op="describe"},stop.Token);
if(!hello.TryGetProperty("nativeCommunityGoals",out var capability)||capability.ValueKind!=JsonValueKind.True)
throw new NotSupportedException("Verified original CG API is not available in this plugin.");
var queued=await pipe.CallAsync(new{op=mine?"cg.read.mine":"cg.read",marketId=4210924803u},stop.Token);
var generation=queued.GetProperty("generation").GetUInt64();
while(true)
{
var result=await pipe.CallAsync(new{op="cg.status",generation},stop.Token);
if(result.GetProperty("state").GetInt32()>=3)
{
await File.WriteAllTextAsync(report,JsonSerializer.Serialize(new{at=DateTimeOffset.UtcNow,pid,mine,result,screenUse=false,ordersSubmitted=0},ToolboxSettings.JsonOptions));
Console.WriteLine(JsonSerializer.Serialize(new{state=result.GetProperty("state").GetInt32(),generation,responseLength=result.GetProperty("responseBody").GetString()!.Length,mutationsSent=result.GetProperty("mutationsSent").GetInt32()}));
if(result.GetProperty("state").GetInt32()!=3)throw new InvalidOperationException("Original CG read did not confirm a response.");
return;
}
await Task.Delay(80,stop.Token);
}
}
}
using System.Text.Json;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Navigation;
using XFEEDToolBox.Core.Data;
using XFEEDToolBox.Core.Execution;
using XFEEDToolBox.Core.Native;
internal static class NativeCommunityGoals
{
internal static async Task JoinTradeAsync(int pid,string directory)
{
var settings=ToolboxSettings.Load(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"XFEstudio","XFEEDToolBox","settings.json"));
await using var journal=new JournalMonitor(settings.JournalDirectory);await journal.StartAsync();var initial=journal.State;
await using var protection=await FlightTestProtectionScope.ArmAsync(pid);
var channel=new NativeCommerceChannel(pid);var hello=await channel.CallAsync(new{op="describe"},CancellationToken.None);
if(hello.GetProperty("gameSha256").GetString()!=NativeSystemLocationReader.GameSha256||!hello.GetProperty("nativeCommunityGoals").GetBoolean())
throw new InvalidOperationException("Verified original CG capability required.");
async Task Check(CancellationToken token)
{
token.ThrowIfCancellationRequested();var player=journal.State;
if(!player.InGame||!player.Docked||player.MarketId!=CommunityGoalCatalogue.HomerMarket||player.CurrentShipId!=5||string.IsNullOrWhiteSpace(initial.CommanderId)||player.CommanderId!=initial.CommanderId
||player.LoadGameAt!=initial.LoadGameAt||protection.Stopped||NavigationSafety.HasExternalThreat(player))
throw new InvalidOperationException("Actual Homer session or ship changed before CG signup.");
var health=await channel.CallAsync(new{op="health.read"},token);
if(!health.GetProperty("localPlayerShipVerified").GetBoolean()||!health.GetProperty("shipHealth").GetProperty("verified").GetBoolean()
||health.GetProperty("shipHealth").GetProperty("hullFraction").GetDouble()<.5)
throw new InvalidOperationException("Independent healthy main-ship observation required.");
}
using var timeout=new CancellationTokenSource(TimeSpan.FromSeconds(100));
var goal=await new NativeCommunityGoalClient(channel).EnsureTradeJoinedAsync(directory,Check,timeout.Token);
Console.WriteLine(JsonSerializer.Serialize(new{confirmed=true,goal,screenUse=false,rewardsClaimed=0}));
}
internal static async Task ReadAsync(int pid,bool mine,string report)
{
if(File.Exists(report))throw new IOException("Use a new CG response report.");
var pipe=new NavigationPipeClient(pid);using var stop=new CancellationTokenSource(TimeSpan.FromSeconds(40));
var hello=await pipe.CallAsync(new{op="describe"},stop.Token);
if(!hello.TryGetProperty("nativeCommunityGoals",out var capability)||capability.ValueKind!=JsonValueKind.True)
throw new NotSupportedException("Verified original CG API is not available in this plugin.");
var queued=await pipe.CallAsync(new{op=mine?"cg.read.mine":"cg.read",marketId=4210924803u},stop.Token);
var generation=queued.GetProperty("generation").GetUInt64();
while(true)
{
var result=await pipe.CallAsync(new{op="cg.status",generation},stop.Token);
if(result.GetProperty("state").GetInt32()>=3)
{
await File.WriteAllTextAsync(report,JsonSerializer.Serialize(new{at=DateTimeOffset.UtcNow,pid,mine,result,screenUse=false,ordersSubmitted=0},ToolboxSettings.JsonOptions));
Console.WriteLine(JsonSerializer.Serialize(new{state=result.GetProperty("state").GetInt32(),generation,responseLength=result.GetProperty("responseBody").GetString()!.Length,mutationsSent=result.GetProperty("mutationsSent").GetInt32()}));
if(result.GetProperty("state").GetInt32()!=3)throw new InvalidOperationException("Original CG read did not confirm a response.");
return;
}
await Task.Delay(80,stop.Token);
}
}
}