Skip to content

Commit

Permalink
Support for bots changing location
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexMacocian committed Aug 14, 2024
1 parent ecc0207 commit 8d4a4d8
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 41 deletions.
13 changes: 11 additions & 2 deletions GuildWarsPartySearch/Endpoints/LiveFeed.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using GuildWarsPartySearch.Server.Extensions;
using GuildWarsPartySearch.Server.Models.Endpoints;
using GuildWarsPartySearch.Server.Services.BotStatus;
using GuildWarsPartySearch.Server.Services.Feed;
using GuildWarsPartySearch.Server.Services.PartySearch;
using System.Core.Extensions;
Expand All @@ -9,15 +10,18 @@ namespace GuildWarsPartySearch.Server.Endpoints;

public sealed class LiveFeed : WebSocketRouteBase<LiveFeedRequest, PartySearchList>
{
private readonly IBotStatusService botStatusService;
private readonly IPartySearchService partySearchService;
private readonly ILiveFeedService liveFeedService;
private readonly ILogger<LiveFeed> logger;

public LiveFeed(
IBotStatusService botStatusService,
IPartySearchService partySearchService,
ILiveFeedService liveFeedService,
ILogger<LiveFeed> logger)
{
this.botStatusService = botStatusService.ThrowIfNull();
this.partySearchService = partySearchService.ThrowIfNull();
this.liveFeedService = liveFeedService.ThrowIfNull();
this.logger = logger.ThrowIfNull();
Expand All @@ -30,10 +34,11 @@ public override async Task ExecuteAsync(LiveFeedRequest? message, CancellationTo
return;
}

var bots = await this.botStatusService.GetBots(cancellationToken);
var searches = await this.partySearchService.GetAllPartySearches(cancellationToken);
await this.SendMessage(new PartySearchList
{
Searches = searches
Searches = searches.Where(u => bots.Any(b => b.Map == u.Map && b.District == u.District)).ToList() // Filter searches by current active locations
}, cancellationToken);
}

Expand All @@ -51,7 +56,11 @@ public override async Task SocketAccepted(CancellationToken cancellationToken)
scopedLogger.LogDebug("Client accepted to livefeed");
scopedLogger.LogDebug("Sending all party searches");
var updates = await this.partySearchService.GetAllPartySearches(cancellationToken);
await this.SendMessage(new PartySearchList { Searches = updates }, cancellationToken);
var bots = await this.botStatusService.GetBots(cancellationToken);
await this.SendMessage(new PartySearchList
{
Searches = updates.Where(u => bots.Any(b => b.Map == u.Map && b.District == u.District)).ToList() // Filter searches by current active locations
}, cancellationToken);
}

public override Task SocketClosed()
Expand Down
17 changes: 7 additions & 10 deletions GuildWarsPartySearch/Endpoints/PostPartySearch.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GuildWarsPartySearch.Server.Filters;
using GuildWarsPartySearch.Common.Models.GuildWars;
using GuildWarsPartySearch.Server.Filters;
using GuildWarsPartySearch.Server.Models;
using GuildWarsPartySearch.Server.Models.Endpoints;
using GuildWarsPartySearch.Server.Services.BotStatus;
Expand Down Expand Up @@ -78,7 +79,9 @@ public override async Task ExecuteAsync(PostPartySearchRequest? message, Cancell
throw new InvalidOperationException("Unable to extract user agent on client disconnect");
}

await this.botStatusService.RecordBotUpdateActivity(userAgent, this.Context.RequestAborted);
var currentBot = await this.botStatusService.GetBot(userAgent, cancellationToken);
var allBots = await this.botStatusService.GetBots(cancellationToken);
await this.botStatusService.RecordBotUpdateActivity(userAgent, message?.Map ?? Map.None, message?.District ?? -1, this.Context.RequestAborted);
var result = await this.partySearchService.PostPartySearch(message, cancellationToken);
var response = await result.Switch<Task<PostPartySearchResponse>>(
onSuccess: async parsedResult =>
Expand All @@ -98,17 +101,11 @@ await this.liveFeedService.PushUpdate(new PartySearch
var response = Success.Result;
if (parsedResult?.GetFullList is true)
{
var currentBot = await this.botStatusService.GetBot(userAgent, cancellationToken);
if (currentBot is null)
{
scopedLogger.LogError($"Failed to find bot for id {userAgent}");
}

var party_searches = await this.partySearchService.GetAllPartySearches(cancellationToken);

// Return all party searches besides the current one
response.PartySearches = party_searches
.Where(p => p.Map != currentBot?.Map || p.District != currentBot?.District)
.Where(p => p.Map != currentBot?.Map || p.District != currentBot?.District) // Return all party searches besides current one
.Where(p => allBots.Any(b => b.Map == p.Map && b.District == p.District)) // Filter by active locations
.Select(p => new PartySearch { Map = p.Map, District = p.District }).ToList();
}
return response;
Expand Down
32 changes: 7 additions & 25 deletions GuildWarsPartySearch/Services/BotStatus/BotStatusService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,7 @@ public async Task<bool> AddBot(string botId, WebSocket client, CancellationToken
return false;
}

var tokens = botId.Split('-');
if (tokens.Length != 3)
{
scopedLogger.LogInformation($"Unable to add bot. Malformed id");
return false;
}

if (!int.TryParse(tokens[1], out var mapId) ||
!Map.TryParse(mapId, out var map))
{
scopedLogger.LogInformation($"Unable to add bot. Malformed mapid");
return false;
}

if (!int.TryParse(tokens[2], out var district))
{
scopedLogger.LogInformation($"Unable to add bot. Malformed district");
return false;
}

var bot = new Bot { Name = tokens[0], Map = map, District = district, WebSocket = client };
var bot = new Bot { Name = botId, WebSocket = client };
if (this.connectedBots.TryRemove(botId, out var existingBot))
{
scopedLogger.LogInformation("Bot has a dangling connection. Closing old connection");
Expand Down Expand Up @@ -159,7 +139,7 @@ public async Task<IEnumerable<BotActivityResponse>> GetAllActivities(Cancellatio

public Task<IEnumerable<Models.BotStatus>> GetBots(CancellationToken cancellationToken)
{
return Task.FromResult(this.connectedBots.Select(b => new Models.BotStatus { Id = b.Key, Name = b.Value.Name, District = b.Value.District, Map = b.Value.Map, LastSeen = b.Value.LastSeen }));
return Task.FromResult(this.connectedBots.Select(b => new Models.BotStatus { Id = b.Key, Name = b.Value.Name, District = b.Value.District ?? -1, Map = b.Value.Map, LastSeen = b.Value.LastSeen }));
}

public Task<Models.BotStatus?> GetBot(string botId, CancellationToken cancellationToken)
Expand All @@ -169,10 +149,10 @@ public async Task<IEnumerable<BotActivityResponse>> GetAllActivities(Cancellatio
return Task.FromResult<Models.BotStatus?>(default);
}

return Task.FromResult<Models.BotStatus?>(new Models.BotStatus { Id = botId, Name = bot.Name, District = bot.District, Map = bot.Map, LastSeen = bot.LastSeen });
return Task.FromResult<Models.BotStatus?>(new Models.BotStatus { Id = botId, Name = bot.Name, District = bot.District ?? -1, Map = bot.Map, LastSeen = bot.LastSeen });
}

public async Task<bool> RecordBotUpdateActivity(string botId, CancellationToken cancellationToken)
public async Task<bool> RecordBotUpdateActivity(string botId, Map map, int district, CancellationToken cancellationToken)
{
var scopedLogger = this.logger.CreateScopedLogger(nameof(this.RecordBotUpdateActivity), botId);
if (!this.connectedBots.TryGetValue(botId, out var bot))
Expand All @@ -182,6 +162,8 @@ public async Task<bool> RecordBotUpdateActivity(string botId, CancellationToken
}

bot.LastSeen = DateTime.Now;
bot.Map = map;
bot.District = district;
await this.database.RecordBotActivity(bot, Database.Models.BotActivity.ActivityType.Update, cancellationToken);
return true;
}
Expand All @@ -205,7 +187,7 @@ public async Task<bool> RemoveBot(string botId, CancellationToken cancellationTo
await this.database.RecordBotActivity(bot, Database.Models.BotActivity.ActivityType.Disconnect, cancellationToken);
await this.liveFeedService.PushUpdate(new Server.Models.PartySearch
{
District = bot.District,
District = bot.District ?? -1,
Map = bot.Map,
PartySearchEntries = []
}, cancellationToken);
Expand Down
5 changes: 3 additions & 2 deletions GuildWarsPartySearch/Services/BotStatus/IBotStatusService.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using GuildWarsPartySearch.Server.Models.Endpoints;
using GuildWarsPartySearch.Common.Models.GuildWars;
using GuildWarsPartySearch.Server.Models.Endpoints;
using System.Net.WebSockets;

namespace GuildWarsPartySearch.Server.Services.BotStatus;

public interface IBotStatusService
{
Task<bool> RecordBotUpdateActivity(string botId, CancellationToken cancellationToken);
Task<bool> RecordBotUpdateActivity(string botId, Map map, int district, CancellationToken cancellationToken);
Task<bool> AddBot(string botId, WebSocket client, CancellationToken cancellationToken);
Task<bool> RemoveBot(string botId, CancellationToken cancellationToken);
Task<IEnumerable<BotActivityResponse>> GetAllActivities(CancellationToken cancellationToken);
Expand Down
4 changes: 2 additions & 2 deletions GuildWarsPartySearch/Services/BotStatus/Models/Bot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ namespace GuildWarsPartySearch.Server.Services.BotStatus.Models;
public sealed class Bot
{
public string Name { get; init; } = default!;
public Map Map { get; init; } = default!;
public int District { get; init; } = default!;
public Map Map { get; set; } = Map.None;
public int? District { get; set; } = default!;
public WebSocket WebSocket { get; init; } = default!;
public DateTime LastSeen { get; set; } = DateTime.Now;
}

0 comments on commit 8d4a4d8

Please sign in to comment.