Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/cd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ on:
paths:
- "Daybreak/**"
- "Daybreak.Installer/**"
- "Daybreak.API/**"
- "Daybreak.7ZipExtractor/**"
- "Daybreak.Installer/**"
- "Daybreak.Shared/**"
workflow_dispatch:

jobs:
Expand Down
15 changes: 11 additions & 4 deletions Daybreak.Shared/Services/BuildTemplates/BuildTemplateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -558,10 +558,17 @@ private async Task<Result<IBuildEntry, Exception>> LoadBuildFromFile(string path
}
else
{
build.Metadata =
JsonConvert.DeserializeObject<Dictionary<string, string>>(
Encoding.UTF8.GetString(
Convert.FromBase64String(content[1])));
try
{
build.Metadata =
JsonConvert.DeserializeObject<Dictionary<string, string>>(
Encoding.UTF8.GetString(
Convert.FromBase64String(content[1])));
}
catch(Exception ex)
{
return new InvalidOperationException("Failed to parse build metadata", ex);
}
}
}

Expand Down
15 changes: 2 additions & 13 deletions Daybreak/Services/Charts/LiveChartInitializer.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using Daybreak.Shared.Models.Metrics;
using Daybreak.Shared.Models.Trade;
using LiveChartsCore;
using LiveChartsCore.Kernel;
using LiveChartsCore;
using LiveChartsCore.SkiaSharpView;
using System.Windows.Extensions.Services;

Expand All @@ -19,14 +16,6 @@ public void OnStartup()
config.AddSkiaSharp()
.AddDefaultMappers()
.AddDarkTheme()
.AddLightTheme()
.HasMap<Metric>((metric, index) =>
{
return new Coordinate(metric.Timestamp.Ticks, Convert.ToDouble(metric.Measurement));
})
.HasMap<TraderQuote>((quote, point) =>
{
return new Coordinate(quote.Timestamp?.Ticks ?? 0, ((double)quote.Price) / 20d);
}));
.AddLightTheme());
}
}
1 change: 0 additions & 1 deletion Daybreak/Services/Guildwars/Utils/GuildwarsFileStream.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Daybreak.Services.Guildwars.Models;
using Daybreak.Services.Guildwars.Utils;
using System.ComponentModel.DataAnnotations;
using System.Core.Extensions;
using System.IO;

Expand Down
36 changes: 23 additions & 13 deletions Daybreak/Services/Notifications/NotificationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
using Daybreak.Shared.Models.Notifications.Handling;
using Daybreak.Shared.Services.Notifications;
using Daybreak.Shared.Utils;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Slim;
using System.Collections.Concurrent;
using System.Core.Extensions;
using System.Extensions;
using System.Extensions.Core;
using System.Runtime.CompilerServices;

namespace Daybreak.Services.Notifications;
Expand Down Expand Up @@ -72,27 +74,35 @@ async Task INotificationProducer.OpenNotification(Notification notification, boo
{
if (storeNotification)
{
await this.storage.OpenNotification(new NotificationDTO
try
{
Title = notification.Title,
Description = notification.Description,
Id = notification.Id,
Level = (int)notification.Level,
MetaData = notification.Metadata,
HandlerType = notification.HandlingType?.AssemblyQualifiedName,
ExpirationTime = notification.ExpirationTime.ToSafeDateTimeOffset().ToUnixTimeMilliseconds(),
CreationTime = notification.CreationTime.ToSafeDateTimeOffset().ToUnixTimeMilliseconds(),
Closed = true
}, cancellationToken);
await this.storage.OpenNotification(new NotificationDTO
{
Title = notification.Title,
Description = notification.Description,
Id = notification.Id,
Level = (int)notification.Level,
MetaData = notification.Metadata,
HandlerType = notification.HandlingType?.AssemblyQualifiedName,
ExpirationTime = notification.ExpirationTime.ToSafeDateTimeOffset().ToUnixTimeMilliseconds(),
CreationTime = notification.CreationTime.ToSafeDateTimeOffset().ToUnixTimeMilliseconds(),
Closed = true
}, cancellationToken);
}
catch (Exception ex)
{
this.logger.CreateScopedLogger().LogError(ex, "Failed to open notification");
return;
}
}

if (notification.HandlingType is null)
{
return;
}

var handler = this.serviceManager.GetService(notification.HandlingType) as INotificationHandler;
handler?.OpenNotification(notification);
var handler = (INotificationHandler)this.serviceManager.GetRequiredService(notification.HandlingType);
handler.OpenNotification(notification);
}

async Task INotificationProducer.RemoveNotification(Notification notification, CancellationToken cancellationToken)
Expand Down
86 changes: 69 additions & 17 deletions Daybreak/Services/Notifications/NotificationStorage.cs
Original file line number Diff line number Diff line change
@@ -1,53 +1,105 @@
using Daybreak.Services.Notifications.Models;
using Microsoft.Extensions.Logging;
using System.Core.Extensions;
using System.Extensions.Core;

namespace Daybreak.Services.Notifications;

internal sealed class NotificationStorage(
NotificationsDbContext liteCollection) : INotificationStorage
NotificationsDbContext liteCollection,
ILogger<NotificationStorage> logger) : INotificationStorage
{
private List<NotificationDTO>? notificationsCache;
private readonly NotificationsDbContext liteCollection = liteCollection.ThrowIfNull();
private readonly ILogger<NotificationStorage> logger = logger.ThrowIfNull();

public async ValueTask<IEnumerable<NotificationDTO>> GetPendingNotifications(CancellationToken cancellationToken)
{
this.notificationsCache ??= await this.liteCollection.FindAll(cancellationToken).ToListAsync(cancellationToken);
return this.notificationsCache
.Where(dto => dto.Closed == false && dto.ExpirationTime < DateTimeOffset.Now.ToUnixTimeMilliseconds());
try
{
this.notificationsCache ??= await this.liteCollection.FindAll(cancellationToken).ToListAsync(cancellationToken);
return this.notificationsCache
.Where(dto => dto.Closed == false && dto.ExpirationTime < DateTimeOffset.Now.ToUnixTimeMilliseconds());
}
catch (Exception ex)
{
this.logger.CreateScopedLogger().LogError(ex, "Failed to get pending notifications");
throw;
}
}

public async ValueTask<IEnumerable<NotificationDTO>> GetNotifications(CancellationToken cancellationToken)
{
this.notificationsCache ??= await this.liteCollection.FindAll(cancellationToken).ToListAsync(cancellationToken);
return this.notificationsCache;
try
{
this.notificationsCache ??= await this.liteCollection.FindAll(cancellationToken).ToListAsync(cancellationToken);
return this.notificationsCache;
}
catch (Exception ex)
{
this.logger.CreateScopedLogger().LogError(ex, "Failed to get notifications");
throw;
}
}

public async ValueTask StoreNotification(NotificationDTO notification, CancellationToken cancellationToken)
{
notification.ThrowIfNull();
await this.liteCollection.Insert(notification, cancellationToken);
this.notificationsCache ??= await this.liteCollection.FindAll(cancellationToken).ToListAsync(cancellationToken);
this.notificationsCache.Add(notification);
try
{
await this.liteCollection.Insert(notification, cancellationToken);
this.notificationsCache ??= await this.liteCollection.FindAll(cancellationToken).ToListAsync(cancellationToken);
this.notificationsCache.Add(notification);
}
catch (Exception ex)
{
this.logger.CreateScopedLogger().LogError(ex, "Failed to store notification");
throw;
}
}

public async ValueTask OpenNotification(NotificationDTO notificationDTO, CancellationToken cancellationToken)
{
notificationDTO.ThrowIfNull();
notificationDTO.Closed = true;
await this.liteCollection.Update(notificationDTO, cancellationToken);
this.notificationsCache = await this.liteCollection.FindAll(cancellationToken).ToListAsync(cancellationToken);
try
{
notificationDTO.Closed = true;
await this.liteCollection.Update(notificationDTO, cancellationToken);
this.notificationsCache = await this.liteCollection.FindAll(cancellationToken).ToListAsync(cancellationToken);
}
catch (Exception ex)
{
this.logger.CreateScopedLogger().LogError(ex, "Failed to open notification");
throw;
}
}

public async ValueTask RemoveNotification(NotificationDTO notificationDTO, CancellationToken cancellationToken)
{
await this.liteCollection.Delete(notificationDTO.Id, cancellationToken);
this.notificationsCache ??= await this.liteCollection.FindAll(cancellationToken).ToListAsync(cancellationToken);
this.notificationsCache.Remove(notificationDTO);
try
{
await this.liteCollection.Delete(notificationDTO.Id, cancellationToken);
this.notificationsCache ??= await this.liteCollection.FindAll(cancellationToken).ToListAsync(cancellationToken);
this.notificationsCache.Remove(notificationDTO);
}
catch (Exception ex)
{
this.logger.CreateScopedLogger().LogError(ex, "Failed to remove notification");
throw;
}
}

public async ValueTask RemoveAllNotifications(CancellationToken cancellationToken)
{
await this.liteCollection.DeleteAll(cancellationToken);
this.notificationsCache = default;
try
{
await this.liteCollection.DeleteAll(cancellationToken);
this.notificationsCache = default;
}
catch (Exception ex)
{
this.logger.CreateScopedLogger().LogError(ex, "Failed to remove all notifications");
throw;
}
}
}
74 changes: 1 addition & 73 deletions Daybreak/Services/Screenshots/Models/Location.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,6 @@ internal sealed class Location
IdFormat = "D2",
StartIndex = 1,
Count = 10
},
new Entry
{
Map = Map.GreenHillsCounty,
Url = "https://media.discordapp.net/attachments/279231165045407744/1053453780580044940/image.png?ex=656a6c49&is=6557f749&hm=beab3433db2cac2d519fc8158978a949e06a57df50b587f41afe3718dc4dad20&=&format=webp&width=954&height=521",
Credit = "",
IdFormat = "D2",
StartIndex = 1,
Count = 1
}
]);
public static readonly Location Ascalon = new(
Expand Down Expand Up @@ -262,15 +253,6 @@ internal sealed class Location
IdFormat = "D2",
StartIndex = 1,
Count = 1
},
new Entry
{
Map = Map.TheGreatNorthernWall,
Url = "https://media.discordapp.net/attachments/279231165045407744/853784390357876746/gw005.jpg?ex=656d152d&is=655aa02d&hm=03e8464e9fc60f8c832eebc246a4fff422ebb865d27dc189b727f22aacab6fb2&=&format=webp&width=954&height=380",
Credit = "https://discordapp.com/users/Chrono#6655",
IdFormat = "D2",
StartIndex = 1,
Count = 1
}
]);
public static readonly Location NorthernShiverpeaks = new(
Expand Down Expand Up @@ -365,15 +347,6 @@ internal sealed class Location
IdFormat = "D2",
StartIndex = 1,
Count = 7
},
new Entry
{
Map = Map.IronHorseMine,
Url = "https://media.discordapp.net/attachments/279231165045407744/927936695230414888/gw064.jpg?ex=656f3864&is=655cc364&hm=75456e75a3a77e0dcbc8b0f1d3dfa292e477b535e90c7a8f40566e0ffa52cb64&=&format=webp&width=903&height=564",
Credit = "https://discordapp.com/users/Pekka#4619",
IdFormat = "D2",
StartIndex = 1,
Count = 1
}
]);
public static readonly Location Kryta = new(
Expand Down Expand Up @@ -1025,15 +998,6 @@ internal sealed class Location
IdFormat = "D2",
StartIndex = 1,
Count = 60
},
new Entry
{
Map = Map.TombOfThePrimevalKings,
Url = "https://cdn.discordapp.com/attachments/279231165045407744/1137832214151843930/gw079.jpg?ex=656cd953&is=655a6453&hm=af57440037882d84e959b950945b738e611d976a2f0beb24d9b1a0fcd626086d&",
Credit = "https://discordapp.com/users/Soldrand#2252",
IdFormat = "D2",
StartIndex = 1,
Count = 1
}
]);
public static readonly Location SouthernShiverpeaks = new(
Expand Down Expand Up @@ -1264,25 +1228,7 @@ internal sealed class Location
IdFormat = "D2",
StartIndex = 1,
Count = 1
},
new Entry
{
Map = Map.TalusChute,
Url = "https://cdn.discordapp.com/attachments/279231165045407744/1079051027753480232/gw500.jpg?ex=656b4294&is=6558cd94&hm=95afe18ecddc81d5cedc9865e5db76986dc4ee2fe34f4832ffcc35854298f371&",
Credit = "https://discordapp.com/users/miragee#4827",
IdFormat = "D2",
StartIndex = 1,
Count = 1
},
new Entry
{
Map = Map.TalusChute,
Url = "https://cdn.discordapp.com/attachments/279231165045407744/1079051028000948345/gw507.jpg?ex=656b4294&is=6558cd94&hm=9e85f4560d8184fbb3a575515a72bdfb1d5812a64b57e486acb9f2a1ce658b4a&",
Credit = "https://discordapp.com/users/miragee#4827",
IdFormat = "D2",
StartIndex = 1,
Count = 1
},
}
]);
public static readonly Location RingOfFireIslandChain = new(
Region.RingOfFireIslands,
Expand Down Expand Up @@ -2484,15 +2430,6 @@ internal sealed class Location
IdFormat = "D2",
StartIndex = 1,
Count = 2
},
new Entry
{
Map = Map.SunquaVale,
Url = "https://media.discordapp.net/attachments/279231165045407744/859817527739547678/gw010.jpg?ex=657092f9&is=655e1df9&hm=b77dd201214212cfc6dd68db2218f550136878f6a2dca37830cc0dcad4201363&=&format=webp&width=954&height=479",
Credit = "https://discordapp.com/users/Sara#2170",
IdFormat = "D2",
StartIndex = 1,
Count = 1
}
]);
public static readonly Location KainengCity = new(
Expand Down Expand Up @@ -4204,15 +4141,6 @@ internal sealed class Location
IdFormat = "D2",
StartIndex = 1,
Count = 5
},
new Entry
{
Map = Map.TheSulfurousWastes,
Url = "https://media.discordapp.net/attachments/279231165045407744/1037396920001372240/unknown.png?ex=65709bab&is=655e26ab&hm=8329f7f07e635c9493c12f53054d090908b8643d0932313d49f2b2ff79601a36&=&format=webp",
Credit = "https://discordapp.com/users/Planewalker#5903",
IdFormat = "D2",
StartIndex = 1,
Count = 5
}
]);
public static readonly Location GateOfTorment = new(
Expand Down
Loading
Loading