-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
111 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,76 +1,108 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using GuildWars2; | ||
using GuildWars2.Exploration.Maps; | ||
using GuildWars2.Mumble; | ||
using GuildWars2.Specializations; | ||
using Microsoft.Extensions.Hosting; | ||
using Microsoft.Extensions.Logging; | ||
|
||
public class GameReporter : IObserver<Snapshot> | ||
namespace Mumble; | ||
|
||
public class GameReporter : BackgroundService | ||
{ | ||
public Dictionary<int, Map> Maps { get; } = new(); | ||
private readonly Gw2Client gw2; | ||
|
||
public Dictionary<int, Specialization> Specializations { get; } = new(); | ||
private readonly ILogger<GameReporter> logger; | ||
|
||
public void OnNext(Snapshot snapshot) | ||
public GameReporter(ILogger<GameReporter> logger, Gw2Client gw2) | ||
{ | ||
var pos = snapshot.AvatarPosition; | ||
this.logger = logger; | ||
this.gw2 = gw2; | ||
} | ||
|
||
if (!snapshot.TryGetIdentity(out var identity, MissingMemberBehavior.Error)) | ||
protected override async Task ExecuteAsync(CancellationToken stoppingToken) | ||
{ | ||
if (!GameLink.IsSupported()) | ||
{ | ||
return; | ||
throw new NotSupportedException(); | ||
} | ||
|
||
if (!snapshot.TryGetContext(out var context)) | ||
{ | ||
return; | ||
} | ||
// BackgroundService starts synchronously, i.e. app startup is delayed until the first await | ||
await Task.Yield(); | ||
|
||
var specialization = "no specialization"; | ||
if (Specializations.TryGetValue(identity.SpecializationId, out var found)) | ||
{ | ||
specialization = found.Name; | ||
} | ||
// Initialize the shared memory link | ||
using var gameLink = GameLink.Open(); | ||
|
||
var map = Maps[identity.MapId]; | ||
var activity = "traveling"; | ||
if (!context.UiState.HasFlag(UiState.GameHasFocus)) | ||
{ | ||
activity = "afk-ing"; | ||
} | ||
else if (context.UiState.HasFlag(UiState.TextboxHasFocus)) | ||
{ | ||
activity = "typing"; | ||
} | ||
else if (context.UiState.HasFlag(UiState.IsMapOpen)) | ||
{ | ||
activity = "looking at the map"; | ||
} | ||
else if (context.UiState.HasFlag(UiState.IsInCombat)) | ||
{ | ||
activity = "in combat"; | ||
} | ||
// The game link emits the current player's map ID and specialization ID | ||
// Additional information about those can be retrieved from the API | ||
var maps = await gw2.Maps.GetMaps(cancellationToken: stoppingToken); | ||
var mapsDictionary = maps.Value.ToDictionary(map => map.Id); | ||
|
||
Console.WriteLine( | ||
"[{0}] {1}, the {2} {3} ({4}) is {5} on {6} in {7}, Position: {{ Right = {8}, Up = {9}, Front = {10} }}", | ||
snapshot.UiTick, | ||
identity.Name, | ||
identity.Race, | ||
identity.Profession, | ||
specialization, | ||
activity, | ||
context.IsMounted ? context.GetMount() : "foot", | ||
map.Name, | ||
pos[0], | ||
pos[1], | ||
pos[2] | ||
); | ||
} | ||
var specializations = | ||
await gw2.Specializations.GetSpecializations(cancellationToken: stoppingToken); | ||
var specializationsDictionary = | ||
specializations.Value.ToDictionary(specialization => specialization.Id); | ||
|
||
public void OnError(Exception error) | ||
{ | ||
} | ||
gameLink.Subscribe( | ||
snapshot => | ||
{ | ||
var pos = snapshot.AvatarPosition; | ||
|
||
public void OnCompleted() | ||
{ | ||
if (!snapshot.TryGetIdentity(out var identity, MissingMemberBehavior.Error)) | ||
{ | ||
return; | ||
} | ||
|
||
if (!snapshot.TryGetContext(out var context)) | ||
{ | ||
return; | ||
} | ||
|
||
var specialization = "no specialization"; | ||
if (specializationsDictionary.TryGetValue(identity.SpecializationId, out var found)) | ||
{ | ||
specialization = found.Name; | ||
} | ||
|
||
var map = mapsDictionary[identity.MapId]; | ||
var activity = "traveling"; | ||
if (!context.UiState.HasFlag(UiState.GameHasFocus)) | ||
{ | ||
activity = "afk-ing"; | ||
} | ||
else if (context.UiState.HasFlag(UiState.TextboxHasFocus)) | ||
{ | ||
activity = "typing"; | ||
} | ||
else if (context.UiState.HasFlag(UiState.IsMapOpen)) | ||
{ | ||
activity = "looking at the map"; | ||
} | ||
else if (context.UiState.HasFlag(UiState.IsInCombat)) | ||
{ | ||
activity = "in combat"; | ||
} | ||
|
||
logger.LogInformation( | ||
"[{UiTick}] {Name}, the {Race} {Profession} ({Specialization}) is {Activity} on {Transport} in {Map}, Position: {{ Right = {Pos0}, Up = {Pos1}, Front = {Pos2} }}", | ||
snapshot.UiTick, | ||
identity.Name, | ||
identity.Race, | ||
identity.Profession, | ||
specialization, | ||
activity, | ||
context.IsMounted ? context.GetMount() : "foot", | ||
map.Name, | ||
pos[0], | ||
pos[1], | ||
pos[2] | ||
); | ||
}, | ||
stoppingToken | ||
); | ||
|
||
// Wait indefinitely until the application is stopped | ||
await Task.Delay(Timeout.InfiniteTimeSpan, stoppingToken); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters