Skip to content

Commit 6c98bf8

Browse files
committed
Started working on WebSocket Server
1 parent 7b77327 commit 6c98bf8

84 files changed

Lines changed: 2081 additions & 1934 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Console/Program.cs

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,59 @@
11
using EliteAPI;
2+
using EliteAPI.Documentation;
23
using EliteAPI.Utils;
34
using Newtonsoft.Json;
45

5-
Log.AddListener(log =>
6-
{
6+
// Log.AddListener(log =>
7+
// {
78

89

9-
ConsoleColor color = log.Level switch
10-
{
11-
Log.LogLevel.Debug => ConsoleColor.DarkGray,
12-
Log.LogLevel.Info => ConsoleColor.Blue,
13-
Log.LogLevel.Warning => ConsoleColor.Yellow,
14-
Log.LogLevel.Error => ConsoleColor.Red,
15-
_ => ConsoleColor.White
16-
};
10+
// ConsoleColor color = log.Level switch
11+
// {
12+
// Log.LogLevel.Debug => ConsoleColor.DarkGray,
13+
// Log.LogLevel.Info => ConsoleColor.Blue,
14+
// Log.LogLevel.Warning => ConsoleColor.Yellow,
15+
// Log.LogLevel.Error => ConsoleColor.Red,
16+
// _ => ConsoleColor.White
17+
// };
1718

18-
var previousColor = Console.ForegroundColor;
19-
Console.ForegroundColor = color;
20-
Console.WriteLine(log.Message);
21-
Console.ForegroundColor = previousColor;
22-
});
19+
// var previousColor = Console.ForegroundColor;
20+
// Console.ForegroundColor = color;
21+
// Console.WriteLine(log.Message);
22+
// Console.ForegroundColor = previousColor;
23+
// });
2324

2425
var api = new EliteDangerousApi();
2526

26-
api.OnKeybindingsChanged(bindings =>
27-
{
28-
foreach (var binding in bindings)
29-
{
30-
if (binding.Name != "LandingGearToggle")
31-
continue;
27+
// api.OnKeybindingsChanged(bindings =>
28+
// {
29+
// foreach (var binding in bindings)
30+
// {
31+
// if (binding.Name != "LandingGearToggle")
32+
// continue;
3233

33-
Log.Info(JsonConvert.SerializeObject(binding));
34-
}
35-
});
34+
// Log.Info(JsonConvert.SerializeObject(binding));
35+
// }
36+
// });
3637

3738
api.Start();
3839

40+
41+
// api.OnAllJson(handler =>
42+
// {
43+
// Console.WriteLine(handler.eventName);
44+
// Console.WriteLine(handler.json);
45+
// });
46+
3947
// api.OnAllJson(e =>
4048
// {
4149
// Console.WriteLine($"JSON Event: {e.eventName}");
4250
// });
4351

44-
await Task.Delay(-1);
52+
// await Task.Delay(-1);
53+
54+
55+
var server = new Server(api);
56+
await server.Initialize();
57+
58+
59+
Thread.Sleep(-1);

EliteAPI/Documentation/Command.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System;
2+
3+
namespace EliteAPI.Documentation;
4+
5+
public readonly struct Command
6+
{
7+
public DateTime Timestamp { get; init; }
8+
9+
public string Name { get; init; }
10+
}

EliteAPI/Documentation/Server.cs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using System.Net;
2+
using System.Text;
3+
using Newtonsoft.Json;
4+
using WatsonWebsocket;
5+
using System.Threading;
6+
using EliteAPI.Utils;
7+
using System;
8+
using System.Threading.Tasks;
9+
using System.Linq;
10+
using System.Collections.Generic;
11+
12+
namespace EliteAPI.Documentation;
13+
14+
public class Server
15+
{
16+
private readonly EliteDangerousApi _api;
17+
private readonly WatsonWsServer _server;
18+
// private readonly Timer _countdown;
19+
private List<Command> _commands = [];
20+
private List<Variable> _variables = [];
21+
// private VariableDocumentation[] _variables;
22+
23+
public Server(EliteDangerousApi api)
24+
{
25+
_api = api;
26+
_server = new WatsonWsServer(IPAddress.Loopback.ToString(), 51555);
27+
}
28+
29+
public async Task Initialize()
30+
{
31+
// send all recorded stuff...
32+
Log.Debug("Starting socket server");
33+
34+
_server.Logger += message => Log.Debug(message);
35+
36+
_server.ClientConnected += async (_, c) =>
37+
{
38+
Log.Debug("Client connected");
39+
40+
await SendToClient(c.IpPort, "commands", JsonConvert.SerializeObject(_commands));
41+
await SendToClient(c.IpPort, "variables", JsonConvert.SerializeObject(_variables));
42+
};
43+
44+
// send updated
45+
_api.OnAllJson(async handler =>
46+
{
47+
_commands.Add(new Command
48+
{
49+
Name = handler.eventName,
50+
Timestamp = DateTime.Now,
51+
});
52+
53+
_variables.Add(new Variable
54+
{
55+
Name = handler.eventName,
56+
Value = handler.json,
57+
Category = handler.eventContext.SourceFile,
58+
});
59+
60+
await SendToClients("commands", JsonConvert.SerializeObject(_commands));
61+
await SendToClients("variables", JsonConvert.SerializeObject(_variables));
62+
});
63+
64+
// _server.MessageReceived += (_, e) =>
65+
// {
66+
// var json = Encoding.UTF8.GetString(e.Data.ToArray());
67+
// Log.Info($"Invoking custom JSON: {JsonConvert.SerializeObject(json)}");
68+
// _api.Events.Invoke(json, new EventContext()
69+
// {
70+
// IsImplemented = true,
71+
// IsRaisedDuringCatchup = false,
72+
// SourceFile = "Invoked JSON"
73+
// });
74+
// };
75+
76+
77+
await _server.StartAsync();
78+
}
79+
80+
private async Task SendToClients(string type, string json)
81+
{
82+
foreach (var ipPort in _server.ListClients())
83+
{
84+
await SendToClient(ipPort, type, json);
85+
}
86+
}
87+
88+
private async Task SendToClient(string ipPort, string type, string json)
89+
{
90+
await _server.SendAsync(ipPort, type.ToUpper());
91+
await _server.SendAsync(ipPort, json);
92+
}
93+
}

EliteAPI/Documentation/Variable.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace EliteAPI.Documentation;
2+
3+
public readonly struct Variable
4+
{
5+
public string Category { get; init; }
6+
public string Name { get; init; }
7+
public string Value { get; init; }
8+
}

EliteAPI/EliteAPI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
</PackageReference>
3232
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
3333
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
34+
<PackageReference Include="WatsonWebsocket" Version="2.3.2.1" />
3435
</ItemGroup>
3536

3637
</Project>

EliteAPI/EliteDangerousApi.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ public class EliteDangerousApi
2020
private readonly StatusTracker _statusTracker = new();
2121

2222
private readonly List<Action<FileInfo>> _journalChangedHandlers = [];
23-
private readonly List<Action<IEvent>> _typedGlobalEventHandlers = [];
24-
private readonly List<Action<(string eventName, string json)>> _untypedGlobalEventHandlers = [];
23+
private readonly List<Action<(IEvent, EventContext)>> _typedGlobalEventHandlers = [];
24+
private readonly List<Action<(string eventName, string json, EventContext)>> _untypedGlobalEventHandlers = [];
2525
private readonly Dictionary<string, List<Action<IEvent>>> _typedEventHandlers = new(StringComparer.OrdinalIgnoreCase);
2626
private readonly Dictionary<string, Type> _eventTypes = typeof(IEvent)
2727
.Assembly
@@ -58,14 +58,14 @@ public void Start()
5858
_journalWatcher.OnContentChanged((json) =>
5959
{
6060
JournalUtils.PrepareLocalisations(json);
61-
Invoke(json);
61+
Invoke(json, new EventContext { SourceFile = _journalWatcher.CurrentFile.Name });
6262
});
6363
_journalWatcher.OnFileChanged(file =>
6464
{
6565
foreach (var handler in _journalChangedHandlers)
6666
SafeInvoke.Invoke("handling journal switch", handler, file);
6767
});
68-
_statusWatchers.ForEach(w => w.OnContentChanged(Invoke));
68+
_statusWatchers.ForEach(w => w.OnContentChanged(content => Invoke(content, new EventContext { SourceFile = w.CurrentFile.Name })));
6969
_bindingsPresetsWatcher.OnContentChanged(HandleBindingsPreset);
7070

7171
_statusWatchers.ForEach(w => w.StartWatching());
@@ -130,27 +130,27 @@ public void OnJson(string eventName, Action<(string eventName, string json)> han
130130
/// <summary>
131131
/// Listens for all events which are typed.
132132
/// </summary>
133-
public void OnAll(Action<IEvent> handler)
133+
public void OnAll(Action<(IEvent, EventContext)> handler)
134134
{
135135
_typedGlobalEventHandlers.Add(handler);
136136
}
137137

138138
/// <summary>
139139
/// Listens for all events with raw JSON
140140
/// </summary>
141-
public void OnAllJson(Action<(string eventName, string json)> handler)
141+
public void OnAllJson(Action<(string eventName, string json, EventContext eventContext)> handler)
142142
{
143143
_untypedGlobalEventHandlers.Add(handler);
144144
}
145145

146-
public void Invoke(IEvent @event)
146+
public void Invoke(IEvent @event, EventContext eventContext)
147147
{
148-
Invoke(JsonConvert.SerializeObject(@event, JsonUtils.SerializerSettings), @event);
148+
Invoke(JsonConvert.SerializeObject(@event, JsonUtils.SerializerSettings), @event, eventContext);
149149
}
150150

151-
public void Invoke(string json) => Invoke(json, null);
151+
public void Invoke(string json, EventContext eventContext) => Invoke(json, null, eventContext);
152152

153-
internal void Invoke(string json, IEvent? @event)
153+
internal void Invoke(string json, IEvent? @event, EventContext eventContext)
154154
{
155155
var eventName = JsonUtils.GetEventName(json);
156156
if (string.IsNullOrEmpty(eventName))
@@ -194,7 +194,7 @@ internal void Invoke(string json, IEvent? @event)
194194

195195
// invoke global untyped handlers
196196
foreach (var handler in _untypedGlobalEventHandlers)
197-
SafeInvoke.Invoke($"{eventName} hander", handler, (eventName, json));
197+
SafeInvoke.Invoke($"{eventName} hander", handler, (eventName, json, eventContext));
198198

199199
if (@event != null)
200200
{
@@ -207,7 +207,7 @@ internal void Invoke(string json, IEvent? @event)
207207

208208
// invoke global typed handlers
209209
foreach (var handler in _typedGlobalEventHandlers)
210-
SafeInvoke.Invoke($"{eventName} hander", handler, @event);
210+
SafeInvoke.Invoke($"{eventName} hander", handler, (@event, eventContext));
211211
}
212212

213213
// After Status event is processed and variables are set, invoke change events
@@ -230,7 +230,7 @@ internal void Invoke(string json, IEvent? @event)
230230

231231
// invoke global untyped handlers for synthetic event
232232
foreach (var handler in _untypedGlobalEventHandlers)
233-
SafeInvoke.Invoke($"{syntheticEventName} handler", handler, (syntheticEventName, syntheticJson));
233+
SafeInvoke.Invoke($"{syntheticEventName} handler", handler, (syntheticEventName, syntheticJson, eventContext));
234234
}
235235

236236
// Always update the tracker state, even if no fields changed

EliteAPI/Events/EventContext.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace EliteAPI.Events;
2+
3+
public readonly struct EventContext
4+
{
5+
/// <summary>
6+
/// Whether the event was raised while the API was catching up with the game session.
7+
/// </summary>
8+
public bool IsRaisedDuringCatchup { get; init; }
9+
10+
/// <summary>
11+
/// Whether the event is implemented in the API.
12+
/// </summary>
13+
14+
public bool IsImplemented { get; init; }
15+
16+
/// <summary>
17+
/// The source file of the event.
18+
/// </summary>
19+
public string SourceFile { get; init; }
20+
}

EliteAPI/Events/Game/ApproachSettlementEvent.cs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,39 @@ namespace EliteAPI.Events.Game;
55

66
public readonly struct ApproachSettlementEvent : IEvent
77
{
8-
[JsonProperty("timestamp")]
9-
public DateTime Timestamp { get; init; }
8+
[JsonProperty("timestamp")]
9+
public DateTime Timestamp { get; init; }
1010

11-
[JsonProperty("event")]
12-
public string Event { get; init; }
11+
[JsonProperty("event")]
12+
public string Event { get; init; }
1313

14-
[JsonProperty("Name")]
15-
public string Name { get; init; }
14+
[JsonProperty("Name")]
15+
public string Name { get; init; }
1616

17-
[JsonProperty("MarketID")]
18-
public string MarketId { get; init; }
17+
[JsonProperty("MarketID")]
18+
public string MarketId { get; init; }
1919

20-
[JsonProperty("SystemAddress")]
21-
public string SystemAddress { get; init; }
20+
[JsonProperty("SystemAddress")]
21+
public string SystemAddress { get; init; }
2222

23-
[JsonProperty("BodyID")]
24-
public string BodyId { get; init; }
23+
[JsonProperty("BodyID")]
24+
public string BodyId { get; init; }
2525

26-
[JsonProperty("BodyName")]
27-
public string BodyName { get; init; }
26+
[JsonProperty("BodyName")]
27+
public string BodyName { get; init; }
2828

29-
[JsonProperty("Latitude")]
30-
public double Latitude { get; init; }
29+
[JsonProperty("Latitude")]
30+
public double Latitude { get; init; }
3131

32-
[JsonProperty("Longitude")]
33-
public double Longitude { get; init; }
32+
[JsonProperty("Longitude")]
33+
public double Longitude { get; init; }
3434

35-
[JsonProperty("StationGovernment")]
36-
public string StationGovernment { get; init; }
35+
[JsonProperty("StationGovernment")]
36+
public string StationGovernment { get; init; }
3737

38-
[JsonProperty("StationAllegiance")]
39-
public string StationAllegiance { get; init; }
38+
[JsonProperty("StationAllegiance")]
39+
public string StationAllegiance { get; init; }
4040

41-
[JsonProperty("StationEconomy")]
42-
public string StationEconomy { get; init; }
41+
[JsonProperty("StationEconomy")]
42+
public string StationEconomy { get; init; }
4343
}

0 commit comments

Comments
 (0)