Compare commits

...
18 Commits
Author SHA1 Message Date
amacocian 86e3579383 Adjust CD pipeline triggers for the component projects (Closes #1038) (#1053) 2025-07-26 22:09:54 +02:00
amacocian ea39346678 Remove screenshots that are no longer available (#1052) 2025-07-26 22:09:54 +02:00
amacocian e4cdc4f939 Fix chart drawing (#1051)
* Reorder dependencies

* Fix visual bug with graphs
2025-07-26 22:09:54 +02:00
amacocian 5acac1ae7a Update dependencies (#1050)
* Update dependencies (Closes #940)

* Update dependencies

* Chart adjustment
2025-07-26 22:09:54 +02:00
amacocian 8c0e734c71 Fix aggregate exception due to concurrency issue on db initialization at startup (Closes #1029) (#1047) 2025-07-26 22:09:54 +02:00
amacocian a56eb20aa0 Fix updater HttpRequestException when connection cannot be established (Closes #1042) (#1046) 2025-07-26 22:09:54 +02:00
amacocian 482854801c Fix format exception popping up during build parse (Closes #1041) (#1045) 2025-07-26 22:09:54 +02:00
amacocian 1a37b8b08f Release 0.9.9.78 (#1044) 2025-07-26 22:09:54 +02:00
amacocian 40d8280ba6 Sort party members by profession when applying party loadout (Closes #1030) (#1036) 2025-06-30 11:09:16 +02:00
amacocian 9533ef0607 Fix builds not showing in FocusView due to locked skills (Closes #1031) (#1035) 2025-06-30 11:09:16 +02:00
amacocian ac963f60b5 Fix build codes not applying due to unescaped url characters (Closes #1032) (#1034) 2025-06-30 11:09:16 +02:00
amacocian 5b6ea99f79 Release 0.9.9.77 (#1033) 2025-06-30 11:09:16 +02:00
amacocian 83ddafea62 Aggregate custom metrics when enabled (Closes #1024) (#1027) 2025-06-29 17:32:52 +02:00
amacocian ab1b604aec Code cleanup (#1026)
* Resolve warnings and move shared props to Directory.Build.props and Directory.Packages.props

* Cleanup more messages

* Fix more messages

* Fix build issues
2025-06-29 17:32:52 +02:00
amacocian d445d0c5f2 Release 0.9.9.76 (#1025) 2025-06-29 17:32:52 +02:00
amacocian f5216020b6 Bugfix for LaunchButton (Closes #1020) (#1022) 2025-06-27 13:59:45 +02:00
amacocian 1b7654f70f Allow users to load and save builds from Focus View (Closes #1018) (#1021) 2025-06-27 13:59:45 +02:00
amacocian 06288ec2a2 Release 0.9.9.75 (#1019) 2025-06-27 13:59:45 +02:00
525 changed files with 3807 additions and 5701 deletions
+4
View File
@@ -12,6 +12,10 @@ on:
paths:
- "Daybreak/**"
- "Daybreak.Installer/**"
- "Daybreak.API/**"
- "Daybreak.7ZipExtractor/**"
- "Daybreak.Installer/**"
- "Daybreak.Shared/**"
workflow_dispatch:
jobs:
@@ -5,13 +5,11 @@
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Daybreak._7ZipExtractor</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>x64</Platforms>
<Version>0.9.9.73</Version>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SharpCompress" Version="0.40.0" />
<PackageReference Include="SharpCompress" />
</ItemGroup>
</Project>
+5
View File
@@ -21,6 +21,11 @@ var reader = archive.ExtractAllEntries();
while (reader.MoveToNextEntry())
{
var entry = reader.Entry;
if (entry.Key is null)
{
continue;
}
if (entry.IsDirectory)
{
var directoryName = Path.Combine(Path.GetFullPath(destinationDirectory), entry.Key);
@@ -5,18 +5,8 @@ public static class WebApplicationBuilderExtensions
public static WebApplicationBuilder WithConfiguration(this WebApplicationBuilder builder)
{
var config = BuildInfo.Configuration;
var appSettingsStream = GetManifestResourceStream($"Daybreak.API.Configuration.appsettings.json");
if (appSettingsStream is null)
{
throw new InvalidOperationException("Failed to load appsettings.json");
}
var appSettingsConfigStream = GetManifestResourceStream($"Daybreak.API.Configuration.appsettings.{config}.json");
if (appSettingsConfigStream is null)
{
throw new InvalidOperationException($"Failed to load appsettings.{config}.json");
}
var appSettingsStream = GetManifestResourceStream($"Daybreak.API.Configuration.appsettings.json") ?? throw new InvalidOperationException("Failed to load appsettings.json");
var appSettingsConfigStream = GetManifestResourceStream($"Daybreak.API.Configuration.appsettings.{config}.json") ?? throw new InvalidOperationException($"Failed to load appsettings.{config}.json");
builder.Configuration
.AddJsonStream(appSettingsStream)
.AddJsonStream(appSettingsConfigStream)
@@ -99,4 +99,16 @@ public sealed class MainPlayerController(
var titleInfo = await this.mainPlayerService.GetTitleInfo(cancellationToken);
return titleInfo is not null ? Results.Ok(titleInfo) : Results.StatusCode(StatusCodes.Status503ServiceUnavailable);
}
[GenerateGet("build-context")]
[EndpointName("GetMainPlayerBuildContext")]
[EndpointSummary("Get the current build context")]
[EndpointDescription("Get the current build context. Returns a json serialized MainPlayerBuildContext object")]
[ProducesResponseType<BuildEntry>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status503ServiceUnavailable)]
public async Task<IResult> GetMainPlayerBuildContext(CancellationToken cancellationToken)
{
var context = await this.mainPlayerService.GetMainPlayerBuildContext(cancellationToken);
return context is not null ? Results.Ok(context) : Results.StatusCode(StatusCodes.Status503ServiceUnavailable);
}
}
+25 -19
View File
@@ -8,9 +8,7 @@
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<StripSymbols>true</StripSymbols>
<InteropExports>true</InteropExports>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator>
<Version>0.9.9.73</Version>
<PublishAot>true</PublishAot>
<SelfContained>true</SelfContained>
@@ -22,6 +20,14 @@
<Platforms>x86</Platforms>
</PropertyGroup>
<PropertyGroup>
<!--Ignore trim warnings. NativeAOT support is still experimental so it should be tested with a Publish build generated from Daybreak build-->
<NoWarn>IL2104</NoWarn>
<NoWarn>IL3053</NoWarn>
<!--MinHook.NET does not contain sources for .NET, only .Net Framework. This has no impact on the functionality of the project-->
<NoWarn>NU1701</NoWarn>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Configuration\appsettings.Debug.json" />
<EmbeddedResource Include="Configuration\appsettings.json" />
@@ -33,23 +39,23 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.6" />
<PackageReference Include="MinHook.NET" Version="1.1.1" />
<PackageReference Include="Net.Sdk.Web.Extensions" Version="0.8.10" />
<PackageReference Include="Net.Sdk.Web.Extensions.SourceGenerators" Version="0.9.3" />
<PackageReference Include="PeNet" Version="5.1.0" />
<PackageReference Include="Serilog" Version="4.3.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="9.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="9.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="9.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.1" />
<PackageReference Include="System.Private.Uri" Version="4.3.2" />
<PackageReference Include="SystemExtensions.NetStandard.Generators" Version="0.1.5" PrivateAssets="all" />
<PackageReference Include="ZLinq" Version="1.4.12" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
<PackageReference Include="MinHook.NET" />
<PackageReference Include="Net.Sdk.Web.Extensions" />
<PackageReference Include="Net.Sdk.Web.Extensions.SourceGenerators" />
<PackageReference Include="PeNet" />
<PackageReference Include="Serilog" />
<PackageReference Include="Serilog.Extensions.Logging" />
<PackageReference Include="Serilog.Settings.Configuration" />
<PackageReference Include="Serilog.Sinks.Console" />
<PackageReference Include="Serilog.Sinks.File" />
<PackageReference Include="Swashbuckle.AspNetCore" />
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" />
<PackageReference Include="System.Private.Uri" />
<PackageReference Include="SystemExtensions.NetStandard.Generators" PrivateAssets="all" />
<PackageReference Include="ZLinq" />
</ItemGroup>
<ItemGroup>
+12 -4
View File
@@ -1,4 +1,5 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Extensions.Core;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
@@ -23,6 +24,8 @@ public class EntryPoint
private static readonly CancellationTokenSource CancellationTokenSource = new();
[UnmanagedCallersOnly(EntryPoint = "ThreadInit"), STAThread]
[RequiresUnreferencedCode("The handler uses a static method that gets referenced, so there's no unreferenced code to worry about")]
[RequiresDynamicCode("The handler uses a static method, so there's no dynamic code to worry about")]
public static int ThreadInit(IntPtr _, int __)
{
Environment.SetEnvironmentVariable("ASPNETCORE_HOSTINGSTARTUPASSEMBLIES", null, EnvironmentVariableTarget.Process);
@@ -37,7 +40,7 @@ public class EntryPoint
var healthCheck = app.Services.GetRequiredService<HealthCheckService>();
var sw = Stopwatch.StartNew();
var healthy = false;
while(sw.Elapsed < InitializationTimeout)
while (sw.Elapsed < InitializationTimeout)
{
var status = Task.Run(() => healthCheck.CheckHealthAsync()).Result;
scopedLogger.LogWarning("HealthCheck status: {status} in {duration}. Report: {report}", status.Status, status.TotalDuration, string.Join("\n", status.Entries.Select(e => $"{e.Key}: {e.Value.Status}")));
@@ -65,9 +68,11 @@ public class EntryPoint
}
}
[RequiresUnreferencedCode("The handler uses a static method that gets referenced, so there's no unreferenced code to worry about")]
[RequiresDynamicCode("The handler uses a static method, so there's no dynamic code to worry about")]
private static WebApplication CreateApplication(int port)
{
var app = WebApplication.CreateBuilder()
var builder = WebApplication.CreateBuilder()
.WithConfiguration()
.WithHosting(port)
.WithSwagger()
@@ -76,8 +81,11 @@ public class EntryPoint
.WithDaybreakServices()
.WithWebSocketRoutes()
.WithRoutes()
.WithHealthChecks()
.Build();
.WithHealthChecks();
builder.Services.AddOpenApi();
var app = builder.Build();
app.UseWebSockets(new WebSocketOptions { KeepAliveInterval = TimeSpan.FromSeconds(30) });
-1
View File
@@ -51,7 +51,6 @@ public enum LivingAgentEffects : uint
Bleeding = 0x0001,
Conditioned = 0x0002,
Crippled1 = 0x0008, // Part of the Crippled check
Crippled2 = 0x0002, // Part of the Crippled check
Crippled = 0x000A, // Combined flag for crippled (0x0008 | 0x0002)
Dead = 0x0010,
DeepWound = 0x0020,
@@ -47,6 +47,6 @@ public readonly unsafe struct GuildWarsArray<T> : IEnumerable<T>
object IEnumerator.Current => this.Current;
public void Reset() => this.index = -1;
public void Dispose() { }
public readonly void Dispose() { }
}
}
@@ -11,8 +11,6 @@ namespace Daybreak.API.Serialization;
[JsonSerializable(typeof(uint))]
[JsonSerializable(typeof(nuint))]
[JsonSerializable(typeof(bool))]
[JsonSerializable(typeof(Task<IResult>))]
[JsonSerializable(typeof(Task))]
[JsonSerializable(typeof(Dictionary<string, string>))]
[JsonSerializable(typeof(List<string>))]
[JsonSerializable(typeof(JsonElement))]
@@ -35,6 +33,7 @@ namespace Daybreak.API.Serialization;
[JsonSerializable(typeof(InstanceInfo))]
[JsonSerializable(typeof(TitleInfo))]
[JsonSerializable(typeof(LoginInfo))]
[JsonSerializable(typeof(MainPlayerBuildContext))]
public partial class ApiJsonSerializerContext : JsonSerializerContext
{
}
@@ -1,9 +1,7 @@
using Daybreak.Shared.Models.Interop;
using PeNet;
using PeNet;
using PeNet.Header.Pe;
using System.Core.Extensions;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Extensions.Core;
using System.Globalization;
using System.Runtime.InteropServices;
@@ -11,31 +9,13 @@ using System.Text;
namespace Daybreak.API.Services.Interop;
public sealed unsafe class MemoryScanningService
public sealed unsafe class MemoryScanningService(
ILogger<MemoryScanningService> logger)
{
private readonly ILogger<MemoryScanningService> logger;
private readonly ILogger<MemoryScanningService> logger = logger.ThrowIfNull();
private readonly (nuint BaseAddress, ImageSectionHeader Section) textSection = GetSectionHeader(".text");
private readonly (nuint BaseAddress, ImageSectionHeader Section) dataSection = GetSectionHeader(".rdata");
public MemoryScanningService(
ILogger<MemoryScanningService> logger)
{
this.logger = logger.ThrowIfNull();
}
public T? ReadPointer<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(GuildwarsPointer<T> ptr)
where T : struct
{
var scopedLogger = this.logger.CreateScopedLogger();
scopedLogger.LogInformation("Reading pointer: 0x{ptr:X8}", ptr.Address);
if (ptr.Address is 0)
{
return default;
}
return Marshal.PtrToStructure<T>((nint)ptr.Address);
}
public nuint FunctionFromNearCall(nuint callInstructionAddress, bool checkValidPtr = true)
{
var scopedLogger = this.logger.CreateScopedLogger();
@@ -366,7 +366,6 @@ public sealed class UIContextService
{
*pState |= 0x200u; // set “hidden”
}
}
private static unsafe void SetFrameDisabledInternal(WrappedPointer<Frame> frame, bool disabled)
@@ -428,6 +428,52 @@ public sealed class MainPlayerService : IDisposable
}, cancellationToken);
}
public Task<MainPlayerBuildContext?> GetMainPlayerBuildContext(CancellationToken cancellationToken)
{
var scopedLogger = this.logger.CreateScopedLogger();
return this.gameThreadService.QueueOnGameThread(() =>
{
unsafe
{
if (this.instanceContextService.GetInstanceType() is InstanceType.Loading)
{
scopedLogger.LogError("Not loaded");
return default;
}
var gameContext = this.gameContextService.GetGameContext();
if (gameContext.IsNull ||
gameContext.Pointer->AccountContext is null ||
gameContext.Pointer->WorldContext is null)
{
this.logger.LogError("Game context is not initialized");
return default;
}
var playerAgentId = this.agentContextService.GetPlayerAgentId();
if (playerAgentId is 0x0)
{
scopedLogger.LogError("Failed to get player agent id");
return default;
}
var agentProfession = gameContext.Pointer->WorldContext->Professions.AsValueEnumerable().FirstOrDefault(p => p.AgentId == playerAgentId);
if (agentProfession.AgentId != playerAgentId)
{
scopedLogger.LogError("Failed to find agent profession for player agent id {agentId}", playerAgentId);
return default;
}
return new MainPlayerBuildContext(
PrimaryProfessionId: (uint)agentProfession.CurrentPrimary,
UnlockedProfessions: agentProfession.UnlockedProfessionsFlags,
UnlockedAccountSkills: gameContext.Pointer->AccountContext->UnlockedAccountSkills.AsValueEnumerable().ToArray(),
UnlockedCharacterSkills: gameContext.Pointer->WorldContext->UnlockedCharacterSkills.AsValueEnumerable().ToArray());
}
}, cancellationToken);
}
public CallbackRegistration RegisterMainStateConsumer(TimeSpan frequency, Action<ReadOnlySpan<byte>> onUpdate)
{
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(frequency, TimeSpan.Zero);
+1 -2
View File
@@ -9,7 +9,6 @@ using Daybreak.Shared.Services.BuildTemplates;
using System.Core.Extensions;
using System.Extensions;
using System.Extensions.Core;
using System.Windows.Navigation;
using ZLinq;
using InstanceType = Daybreak.API.Interop.GuildWars.InstanceType;
@@ -234,7 +233,7 @@ public sealed class PartyService(
{
var scopedLogger = this.logger.CreateScopedLogger();
scopedLogger.LogDebug("Spawning {heroCount} heroes for party loadout", partyLoadout.Entries.AsValueEnumerable().Count(c => c.HeroId != 0));
foreach (var entry in partyLoadout.Entries)
foreach (var entry in partyLoadout.Entries.AsValueEnumerable().OrderBy(e => e.Build.Primary))
{
if (entry.HeroId != 0 &&
Hero.TryParse(entry.HeroId, out var hero))
-1
View File
@@ -81,7 +81,6 @@ public sealed class UIService(
{
await this.Keypress(uiAction, null, CancellationToken.None);
}
}, CancellationToken.None);
});
}
@@ -10,7 +10,6 @@
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<PublishAot>true</PublishAot>
<StripSymbols>true</StripSymbols>
<Version>0.9.9.73</Version>
</PropertyGroup>
</Project>
@@ -1,5 +1,4 @@
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class AttributeJsonConverter : JsonConverter
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media.Effects;
@@ -1,5 +1,4 @@
using System;
using System.Extensions;
using System.Extensions;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
@@ -22,7 +21,7 @@ public sealed class BooleanToGridLengthConverter : IValueConverter
throw new NotImplementedException();
}
private object GetVisibility(object value)
private GridLength GetVisibility(object value)
{
if (value is not bool)
{
@@ -1,5 +1,4 @@
using System;
using System.Extensions;
using System.Extensions;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
@@ -38,12 +37,12 @@ public class BooleanToVisibilityConverter : IValueConverter
}
var objValue = value.Cast<bool>();
if (objValue && this.TriggerValue && this.IsHidden || !objValue && !this.TriggerValue && this.IsHidden)
if ((objValue && this.TriggerValue && this.IsHidden) || (!objValue && !this.TriggerValue && this.IsHidden))
{
return Visibility.Hidden;
}
if (objValue && this.TriggerValue && !this.IsHidden || !objValue && !this.TriggerValue && !this.IsHidden)
if ((objValue && this.TriggerValue && !this.IsHidden) || (!objValue && !this.TriggerValue && !this.IsHidden))
{
return Visibility.Collapsed;
}
@@ -1,6 +1,5 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class CampaignJsonConverter : JsonConverter
@@ -1,6 +1,5 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class ContinentJsonConverter : JsonConverter
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
@@ -1,9 +1,7 @@
using Daybreak.Shared.Models.Guildwars;
using Daybreak.Shared.Services.Events;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
@@ -1,7 +1,5 @@
using Daybreak.Shared.Models;
using Daybreak.Shared.Models.Guildwars;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
+3 -4
View File
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
@@ -9,7 +8,7 @@ public class HiddenWhenNull : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return this.GetVerticalAlignment(value);
return GetVerticalAlignment(value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
@@ -17,7 +16,7 @@ public class HiddenWhenNull : IValueConverter
throw new NotImplementedException();
}
private object GetVerticalAlignment(object value)
private static object GetVerticalAlignment(object value)
{
if (value is null)
{
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
@@ -1,5 +1,4 @@
using System;
using System.Windows.Data;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
@@ -1,6 +1,5 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class ItemBaseJsonConverter : JsonConverter
@@ -18,7 +17,7 @@ public sealed class ItemBaseJsonConverter : JsonConverter
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is not string ||
if (name is null ||
!ItemBase.TryParse(name, out var namedItem))
{
return default;
@@ -1,5 +1,4 @@
using Daybreak.Shared.Models.Guildwars;
using System;
using System.Globalization;
using System.Windows.Data;
@@ -1,5 +1,4 @@
using Daybreak.Shared.Models.Guildwars;
using System;
using System.Globalization;
using System.Windows.Data;
@@ -1,6 +1,5 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class MapJsonConverter : JsonConverter
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
@@ -1,7 +1,5 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
using System.Linq;
namespace Daybreak.Shared.Converters;
public sealed class NpcJsonConverter : JsonConverter
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows.Data;
using System.Windows;
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
@@ -1,6 +1,5 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class ProfessionJsonConverter : JsonConverter
@@ -1,6 +1,5 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class QuestJsonConverter : JsonConverter
@@ -1,6 +1,5 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class RegionJsonConverter : JsonConverter
@@ -1,6 +1,5 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class SkillJsonConverter : JsonConverter
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
@@ -10,7 +9,7 @@ public sealed class TimeSinceDateTimeConverter : IValueConverter
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return this.GetTimeString(value);
return GetTimeString(value) ?? string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
@@ -18,11 +17,11 @@ public sealed class TimeSinceDateTimeConverter : IValueConverter
throw new NotImplementedException();
}
private object GetTimeString(object value)
private static string? GetTimeString(object value)
{
if (value is not DateTime dateTime)
{
return default!;
return default;
}
var difference = DateTime.Now - dateTime;
@@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
@@ -1,6 +1,5 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class TitleJsonConverter : JsonConverter
@@ -1,19 +1,13 @@
using Daybreak.Shared.Models.Trade;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
namespace Daybreak.Shared.Converters;
public sealed class TradeAlertConverter : JsonConverter<ITradeAlert>
{
public override ITradeAlert? ReadJson(JsonReader reader, Type objectType, ITradeAlert? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
var jObject = JObject.Load(reader).ToObject<dynamic>();
if (jObject is null)
{
throw new InvalidOperationException($"Unable to deserialize {nameof(ITradeAlert)}");
}
var jObject = JObject.Load(reader).ToObject<dynamic>() ?? throw new InvalidOperationException($"Unable to deserialize {nameof(ITradeAlert)}");
if (jObject[nameof(TradeAlert.MessageCheck)] is null)
{
return new QuoteAlert
@@ -51,10 +45,12 @@ public sealed class TradeAlertConverter : JsonConverter<ITradeAlert>
return;
}
var jObject = new JObject();
jObject[nameof(ITradeAlert.Name)] = value.Name;
jObject[nameof(ITradeAlert.Enabled)] = value.Enabled;
jObject[nameof(ITradeAlert.Id)] = value.Id;
var jObject = new JObject
{
[nameof(ITradeAlert.Name)] = value.Name,
[nameof(ITradeAlert.Enabled)] = value.Enabled,
[nameof(ITradeAlert.Id)] = value.Id
};
if (value is TradeAlert tradeAlert)
{
jObject[nameof(TradeAlert.MessageCheck)] = tradeAlert.MessageCheck;
@@ -1,5 +1,4 @@
using Daybreak.Shared.Models.Trade;
using System;
using System.Globalization;
using System.Windows.Data;
+15 -15
View File
@@ -9,23 +9,23 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MeaMod.DNS" Version="1.0.71" />
<PackageReference Include="MemoryPack" Version="1.21.4" />
<PackageReference Include="MemoryPack.Generator" Version="1.21.4">
<PackageReference Include="MeaMod.DNS" />
<PackageReference Include="MemoryPack" />
<PackageReference Include="MemoryPack.Generator">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.6" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3296.44" />
<PackageReference Include="Slim" Version="1.9.2" />
<PackageReference Include="System.Linq.Async" Version="6.0.3" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Reflection.Metadata" Version="9.0.6" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.6" />
<PackageReference Include="System.Text.Json" Version="9.0.6" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="SystemExtensions.NetCore" Version="1.6.12" />
<PackageReference Include="SystemExtensions.NetStandard.DependencyInjection" Version="1.6.9" />
<PackageReference Include="SystemExtensions.NetStandard.Generators" Version="0.1.5" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Http" />
<PackageReference Include="Microsoft.Web.WebView2" />
<PackageReference Include="Slim" />
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="System.Net.Http" />
<PackageReference Include="System.Reflection.Metadata" />
<PackageReference Include="System.Text.Encoding.CodePages" />
<PackageReference Include="System.Text.Json" />
<PackageReference Include="System.Text.RegularExpressions" />
<PackageReference Include="SystemExtensions.NetCore" />
<PackageReference Include="SystemExtensions.NetStandard.DependencyInjection" />
<PackageReference Include="SystemExtensions.NetStandard.Generators" PrivateAssets="all" />
</ItemGroup>
<Target Name="RemoveDuplicateAnalyzers" BeforeTargets="CoreCompile">
@@ -1,6 +1,4 @@
using System;
namespace Daybreak.Shared.Exceptions;
namespace Daybreak.Shared.Exceptions;
public sealed class CredentialsNotFoundException : Exception
{
@@ -1,6 +1,4 @@
using System;
namespace Daybreak.Shared.Exceptions;
namespace Daybreak.Shared.Exceptions;
public sealed class ExecutableNotFoundException : Exception
{
+1 -3
View File
@@ -1,6 +1,4 @@
using System;
namespace Daybreak.Shared.Exceptions;
namespace Daybreak.Shared.Exceptions;
public sealed class FatalException : Exception
{
+1 -2
View File
@@ -1,5 +1,4 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Daybreak")]
+1 -3
View File
@@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Api;
namespace Daybreak.Shared.Models.Api;
public sealed record BuildEntry(int Primary, int Secondary, List<AttributeEntry> Attributes, List<uint> Skills)
{
}
@@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Api;
namespace Daybreak.Shared.Models.Api;
public sealed record CharacterSelectInformation(CharacterSelectEntry? CurrentCharacter, List<CharacterSelectEntry> CharacterNames)
{
+1 -1
View File
@@ -7,6 +7,6 @@ public enum HeroBehavior
{
Fight,
Guard,
AvoidCombat,
Avoid,
Undefined
}
@@ -0,0 +1,4 @@
namespace Daybreak.Shared.Models.Api;
public sealed record MainPlayerBuildContext(uint PrimaryProfessionId, uint UnlockedProfessions, uint[] UnlockedCharacterSkills, uint[] UnlockedAccountSkills)
{
}
+1 -3
View File
@@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Api;
namespace Daybreak.Shared.Models.Api;
public sealed record PartyLoadout(List<PartyLoadoutEntry> Entries)
{
}
@@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Api;
namespace Daybreak.Shared.Models.Api;
public sealed record QuestLogInformation(uint CurrentQuestId, IReadOnlyList<QuestInformation> Quests)
{
}
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace Daybreak.Shared.Models;
@@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Browser;
namespace Daybreak.Shared.Models.Browser;
public sealed class BrowserHistory
{
public List<string> History { get; set; } = [];
@@ -5,26 +5,23 @@ namespace Daybreak.Shared.Models.Builds;
public sealed class AttributeEntry : INotifyPropertyChanged
{
private Attribute? attribute;
private int points;
public event PropertyChangedEventHandler? PropertyChanged;
public Attribute? Attribute
{
get => this.attribute;
get;
set
{
this.attribute = value;
field = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Attribute)));
}
}
public int Points
{
get => this.points;
get;
set
{
this.points = value;
field = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Points)));
}
}
+1 -4
View File
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Builds;
namespace Daybreak.Shared.Models.Builds;
public interface IBuildEntry
{
public DateTimeOffset CreationTime { get; set; }
@@ -0,0 +1,10 @@
using Daybreak.Shared.Models.Api;
using Daybreak.Shared.Models.Guildwars;
namespace Daybreak.Shared.Models.Builds;
public sealed class PartyMemberEntry
{
public required SingleBuildEntry Build { get; init; }
public required Hero? Hero { get; init; }
public required HeroBehavior Behavior { get; init; }
}
@@ -1,8 +1,5 @@
using Daybreak.Shared.Models.Guildwars;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Attribute = Daybreak.Shared.Models.Guildwars.Attribute;
namespace Daybreak.Shared.Models.Builds;
@@ -190,7 +187,7 @@ public sealed class SingleBuildEntry : BuildEntryBase, IBuildEntry, INotifyPrope
attributesToAdd.AddRange(this.Primary.Attributes);
attributesToAdd.AddRange(this.Secondary.Attributes);
this.Attributes = attributesToAdd.Distinct().Select(attribute =>
this.Attributes = [.. attributesToAdd.Distinct().Select(attribute =>
{
if (this.Attributes.FirstOrDefault(attributeEntry => attributeEntry.Attribute == attribute) is AttributeEntry attributeEntry)
{
@@ -198,7 +195,7 @@ public sealed class SingleBuildEntry : BuildEntryBase, IBuildEntry, INotifyPrope
}
return new AttributeEntry { Attribute = attribute };
}).ToList();
})];
}
private void UpdateSkills()
@@ -1,7 +1,4 @@
using Daybreak.Shared.Models.Guildwars;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Builds;
public sealed class TeamBuildEntry : BuildEntryBase, IEquatable<TeamBuildEntry>
+1 -2
View File
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Windows.Media;
using System.Windows.Media;
namespace Daybreak.Shared.Models;
public static class ColorPalette
+1 -3
View File
@@ -1,6 +1,4 @@
using System;
namespace Daybreak.Shared.Models;
namespace Daybreak.Shared.Models;
public readonly struct DaybreakAPIContext(Uri apiUri)
{
public readonly Uri ApiUri = apiUri;
@@ -1,5 +1,4 @@
using MeaMod.DNS.Multicast;
using System;
namespace Daybreak.Shared.Models;
public readonly struct DnsRegistrationToken : IDisposable
+1 -3
View File
@@ -1,6 +1,4 @@
using System;
namespace Daybreak.Shared.Models;
namespace Daybreak.Shared.Models;
public sealed class ElevationRequest
{
+3 -5
View File
@@ -4,17 +4,15 @@ namespace Daybreak.Shared.Models;
public sealed class ExecutablePath : INotifyPropertyChanged
{
private string path = string.Empty;
public event PropertyChangedEventHandler? PropertyChanged;
public string Path
{
get => this.path;
get;
set
{
this.path = value;
field = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Path)));
}
}
} = string.Empty;
}
@@ -0,0 +1,9 @@
namespace Daybreak.Shared.Models.FocusView;
public sealed class BuildComponentContext
{
public required bool IsInOutpost { get; init; }
public required uint PrimaryProfessionId { get; init; }
public required uint UnlockedProfessions { get; init; }
public required uint[] CharacterUnlockedSkills { get; init; }
public required uint[] AccountUnlockedSkills { get; init; }
}
@@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.FocusView;
namespace Daybreak.Shared.Models.FocusView;
public sealed class CharacterComponentContext
{
public required uint CurrentExperience { get; init; }
@@ -1,6 +1,4 @@
using System;
namespace Daybreak.Shared.Models.FocusView;
namespace Daybreak.Shared.Models.FocusView;
public sealed class CharacterSelectComponentEntry : IEquatable<CharacterSelectComponentEntry>
{
public required string DisplayName { get; init; }
@@ -1,5 +1,4 @@
using Daybreak.Shared.Models.Guildwars;
using System.Collections.Generic;
namespace Daybreak.Shared.Models.FocusView;
public sealed class QuestLogComponentContext
@@ -1,5 +1,4 @@
using Daybreak.Shared.Models.Progress;
using System.Threading;
namespace Daybreak.Shared.Models;
public sealed class GuildWarsUpdateRequest
@@ -1,8 +1,5 @@
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
+1 -2
View File
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using Daybreak.Shared.Models.Builds;
using Daybreak.Shared.Models.Builds;
namespace Daybreak.Shared.Models.Guildwars;
@@ -1,7 +1,5 @@
using Daybreak.Shared.Models.Builds;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace Daybreak.Shared.Models.Guildwars;
@@ -111,7 +109,7 @@ public abstract class BuildEntryBase : INotifyPropertyChanged, IBuildEntry
set
{
this.Metadata ??= [];
this.Metadata[nameof(PartyCompositionMetadataEntry)] = value is null
this.Metadata[nameof(this.PartyComposition)] = value is null
? string.Empty
: JsonConvert.SerializeObject(value, Formatting.None);
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.PartyComposition)));
@@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class BuildMetadata
{
+21 -24
View File
@@ -1,8 +1,5 @@
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
@@ -14,11 +11,11 @@ public sealed class Campaign
Id = 0,
Name = "Core",
WikiUrl = "https://wiki.guildwars.com/wiki/Guild_Wars_Core",
Continents = new List<Continent>
{
Continents =
[
Continent.TheBattleIsles,
Continent.TheMists
}
]
};
public static Campaign Prophecies { get; } = new()
@@ -26,10 +23,10 @@ public sealed class Campaign
Id = 1,
Name = "Prophecies",
WikiUrl = "https://wiki.guildwars.com/wiki/Guild_Wars_Prophecies",
Continents = new List<Continent>
{
Continents =
[
Continent.Tyria
}
]
};
public static Campaign Factions { get; } = new()
@@ -37,10 +34,10 @@ public sealed class Campaign
Id = 2,
Name = "Factions",
WikiUrl = "https://wiki.guildwars.com/wiki/Guild_Wars_Factions",
Continents = new List<Continent>
{
Continents =
[
Continent.Cantha
}
]
};
public static Campaign Nightfall { get; } = new()
@@ -48,11 +45,11 @@ public sealed class Campaign
Id = 3,
Name = "Nightfall",
WikiUrl = "https://wiki.guildwars.com/wiki/Guild_Wars_Nightfall",
Continents = new List<Continent>
{
Continents =
[
Continent.Elona,
Continent.RealmOfTorment
}
]
};
public static Campaign EyeOfTheNorth { get; } = new()
@@ -60,10 +57,10 @@ public sealed class Campaign
Id = 4,
Name = "Eye of the North",
WikiUrl = "https://wiki.guildwars.com/wiki/Guild_Wars_Eye_of_the_North",
Continents = new List<Continent>
{
Continents =
[
Continent.Tyria
}
]
};
public static Campaign BonusMissionPack { get; } = new()
@@ -71,23 +68,23 @@ public sealed class Campaign
Id = 5,
Name = "Bonus Mission Pack",
WikiUrl = "https://wiki.guildwars.com/wiki/Guild_Wars_Bonus_Mission_Pack",
Continents = new List<Continent>
{
Continents =
[
Continent.Tyria,
Continent.Elona,
Continent.Cantha
}
]
};
public static IReadOnlyList<Campaign> Campaigns { get; } = new List<Campaign>
{
public static IReadOnlyList<Campaign> Campaigns { get; } =
[
Core,
Prophecies,
Factions,
Nightfall,
EyeOfTheNorth,
BonusMissionPack
};
];
public static bool TryParse(int id, out Campaign campaign)
{
+21 -24
View File
@@ -1,8 +1,5 @@
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
@@ -14,8 +11,8 @@ public sealed class Continent
Id = 0,
Name = "Tyria",
WikiUrl = "https://wiki.guildwars.com/wiki/Tyria",
Regions = new List<Region>
{
Regions =
[
Region.Ascalon,
Region.PresearingAscalon,
Region.CrystalDesert,
@@ -29,7 +26,7 @@ public sealed class Continent
Region.TarnishedCoast,
Region.TheFlightNorth,
Region.TheRiseOfTheWhiteMantle
}
]
};
public static Continent TheMists { get; } = new Continent
@@ -37,10 +34,10 @@ public sealed class Continent
Id = 1,
Name = "The Mists",
WikiUrl = "https://wiki.guildwars.com/wiki/The_Mists",
Regions = new List<Region>
{
Regions =
[
Region.HeroesAscent
}
]
};
public static Continent Cantha { get; } = new Continent
@@ -48,14 +45,14 @@ public sealed class Continent
Id = 2,
Name = "Cantha",
WikiUrl = "https://wiki.guildwars.com/wiki/Cantha",
Regions = new List<Region>
{
Regions =
[
Region.ShingJeaIsland,
Region.KainengCity,
Region.EchovaldForest,
Region.TheJadeSea,
Region.TheTenguAccords
}
]
};
public static Continent TheBattleIsles { get; } = new Continent
@@ -63,10 +60,10 @@ public sealed class Continent
Id = 3,
Name = "The Battle Isles",
WikiUrl = "https://wiki.guildwars.com/wiki/The_Battle_Isles",
Regions = new List<Region>
{
Regions =
[
Region.TheBattleIsles,
}
]
};
public static Continent Elona { get; } = new Continent
@@ -74,14 +71,14 @@ public sealed class Continent
Id = 4,
Name = "Elona",
WikiUrl = "https://wiki.guildwars.com/wiki/Elona",
Regions = new List<Region>
{
Regions =
[
Region.Istan,
Region.Kourna,
Region.Vabbi,
Region.TheDesolation,
Region.TheBattleOfJahai
}
]
};
public static Continent RealmOfTorment { get; } = new Continent
@@ -89,21 +86,21 @@ public sealed class Continent
Id = 5,
Name = "Realm of Torment",
WikiUrl = "https://wiki.guildwars.com/wiki/Realm_of_Torment",
Regions = new List<Region>
{
Regions =
[
Region.RealmOfTorment
}
]
};
public static IReadOnlyList<Continent> Continents { get; } = new List<Continent>
{
public static IReadOnlyList<Continent> Continents { get; } =
[
Tyria,
TheMists,
Cantha,
TheBattleIsles,
Elona,
RealmOfTorment
};
];
public static bool TryParse(int id, out Continent continent)
{
+1 -4
View File
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
/// <summary>
/// Seasonal holidays and in-game events, as retrieved from https://www.guildwars.com/en/events.
+1 -5
View File
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class Hero : IWikiEntity
{
public static readonly Hero None = new() { Id = 0, Profession = Profession.None, Name = string.Empty, WikiUrl = string.Empty };
@@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class Inscription : ItemBase, IWikiEntity, IIconUrlEntity
{
@@ -1,8 +1,5 @@
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
+3 -6
View File
@@ -1,8 +1,5 @@
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
@@ -716,8 +713,8 @@ public sealed class Map : IWikiEntity
public static readonly Map AshfordCatacombs1070AE = new() { Id = 876, Name = "Ashford Catacombs 1070AE", WikiUrl = "https://wiki.guildwars.com/wiki/Ashford_Catacombs:_1070_AE" };
public static readonly Map Count = new() { Id = 877, Name = "Count", WikiUrl = "" };
public static IEnumerable<Map> Maps { get; } = new List<Map>
{
public static IEnumerable<Map> Maps { get; } =
[
None,
GladiatorsArena,
DEVTestArena1v1,
@@ -1419,7 +1416,7 @@ public sealed class Map : IWikiEntity
LakesideCounty1070AE,
AshfordCatacombs1070AE,
Count,
};
];
public static bool TryParse(int id, out Map map)
{
+10 -12
View File
@@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class Material : ItemBase, IWikiEntity
{
@@ -42,8 +40,8 @@ public sealed class Material : ItemBase, IWikiEntity
public static readonly Material TemperedGlassVial = new() { Id = 939, Name = "Tempered Glass Vial", Multiple = "Tempered Glass Vials", WikiUrl = "https://wiki.guildwars.com/wiki/Tempered_Glass_Vial" };
public static readonly Material VialOfInk = new() { Id = 944, Name = "Vial of Ink", Multiple = "Vials of Ink", WikiUrl = "https://wiki.guildwars.com/wiki/Vial_of_Ink" };
public static IReadOnlyList<Material> Common { get; } = new List<Material>
{
public static IReadOnlyList<Material> Common { get; } =
[
Bone,
BoltOfCloth,
PileOfGlitteringDust,
@@ -55,9 +53,9 @@ public sealed class Material : ItemBase, IWikiEntity
Scale,
ChitinFragment,
GraniteSlab
};
public static IReadOnlyList<Material> Rare { get; } = new List<Material>
{
];
public static IReadOnlyList<Material> Rare { get; } =
[
AmberChunk,
BoltOfDamask,
BoltOfLinen,
@@ -83,9 +81,9 @@ public sealed class Material : ItemBase, IWikiEntity
SteelIngot,
TemperedGlassVial,
VialOfInk
};
public static IReadOnlyList<Material> All { get; } = new List<Material>
{
];
public static IReadOnlyList<Material> All { get; } =
[
Bone,
BoltOfCloth,
PileOfGlitteringDust,
@@ -122,7 +120,7 @@ public sealed class Material : ItemBase, IWikiEntity
SteelIngot,
TemperedGlassVial,
VialOfInk
};
];
public string? Multiple { get; init; }
public string? WikiUrl { get; init; }
File diff suppressed because it is too large Load Diff
@@ -1,8 +1,5 @@
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
@@ -110,8 +107,8 @@ public sealed class Profession : IWikiEntity
PrimaryAttribute = Attribute.Mysticism,
Attributes = [Attribute.EarthPrayers, Attribute.ScytheMastery, Attribute.WindPrayers]
};
public static IEnumerable<Profession> Professions = new List<Profession>
{
public static readonly IEnumerable<Profession> Professions =
[
None,
Warrior,
Ranger,
@@ -123,7 +120,7 @@ public sealed class Profession : IWikiEntity
Ritualist,
Paragon,
Dervish
};
];
public static bool TryParse(int id, out Profession profession)
{
profession = Professions.Where(prof => prof.Id == id).FirstOrDefault()!;
+3 -6
View File
@@ -1,8 +1,5 @@
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
@@ -1413,8 +1410,8 @@ public sealed class Quest : IWikiEntity
public static readonly Quest PilgrimagetotheHallofHeroes = new() { Id = 1439, Name = "Pilgrimage to the Hall of Heroes", WikiUrl = "https://wiki.guildwars.com/wiki/Pilgrimage_to_the_Hall_of_Heroes" };
public static readonly Quest CrossingTheDesolation = new() { Id = 686, Name = "Crossing The Desolation", WikiUrl = "https://wiki.guildwars.com/wiki/Crossing_the_Desolation" };
public static IEnumerable<Quest> Quests { get; } = new List<Quest>
{
public static IEnumerable<Quest> Quests { get; } =
[
TheAscalonSettlement,
TheVillainyofGalrath,
BanditTrouble,
@@ -2814,7 +2811,7 @@ public sealed class Quest : IWikiEntity
TakeMySisterPlease,
PilgrimagetotheHallofHeroes,
CrossingTheDesolation
};
];
public static bool TryParse(int id, out Quest quest)
{
+81 -84
View File
@@ -1,8 +1,5 @@
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
@@ -14,8 +11,8 @@ public sealed class Region : IWikiEntity
Id = 0,
Name = "Kryta",
WikiUrl = "https://wiki.guildwars.com/wiki/Kryta",
Maps = new List<Map>
{
Maps =
[
Map.LionsArchCanthanNewYearOutpost,
Map.LionsArchHalloweenOutpost,
Map.LionsArchOutpost,
@@ -45,15 +42,15 @@ public sealed class Region : IWikiEntity
Map.TheBlackCurtain,
Map.TwinSerpentLakes,
Map.WatchtowerCoast
}
]
};
public static readonly Region MaguumaJungle = new()
{
Id = 1,
Name = "Maguuma Jungle",
WikiUrl = "https://wiki.guildwars.com/wiki/Maguuma_Jungle",
Maps = new List<Map>
{
Maps =
[
Map.HengeOfDenraviOutpost,
Map.DruidsOverlookOutpost,
Map.MaguumaStadeOutpost,
@@ -72,15 +69,15 @@ public sealed class Region : IWikiEntity
Map.Silverwood,
Map.TangleRoot,
Map.TheFalls
}
]
};
public static readonly Region Ascalon = new()
{
Id = 2,
Name = "Ascalon",
WikiUrl = "https://wiki.guildwars.com/wiki/Ascalon",
Maps = new List<Map>
{
Maps =
[
Map.AscalonCityOutpost,
Map.AscalonCityWintersdayOutpost,
Map.FrontierGateOutpost,
@@ -105,15 +102,15 @@ public sealed class Region : IWikiEntity
Map.PockmarkFlats,
Map.RegentValley,
Map.TheBreach
}
]
};
public static readonly Region ShiverpeakMountains = new()
{
Id = 3,
Name = "Shiverpeak Mountains",
WikiUrl = "https://wiki.guildwars.com/wiki/Shiverpeak_Mountains",
Maps = new List<Map>
{
Maps =
[
Map.BeaconsPerchOutpost,
Map.IceToothCaveOutpost,
Map.YaksBendOutpost,
@@ -154,15 +151,15 @@ public sealed class Region : IWikiEntity
Map.TalusChute,
Map.TascasDemise,
Map.WitmansFolly
}
]
};
public static readonly Region HeroesAscent = new()
{
Id = 4,
Name = "Heroes' Ascent",
WikiUrl = "https://wiki.guildwars.com/wiki/Heroes%27_Ascent",
Maps = new List<Map>
{
Maps =
[
Map.BurialMoundsMission,
Map.FetidRiverMission,
Map.TheUnderworldArenaMission,
@@ -176,15 +173,15 @@ public sealed class Region : IWikiEntity
Map.SacredTemplesMission,
Map.ScarredEarth,
Map.ScarredEarth2
}
]
};
public static readonly Region CrystalDesert = new()
{
Id = 5,
Name = "Crystal Desert",
WikiUrl = "https://wiki.guildwars.com/wiki/Crystal_Desert",
Maps = new List<Map>
{
Maps =
[
Map.TheAmnoonOasisOutpost,
Map.DestinysGorgeOutpost,
Map.HeroesAudienceOutpost,
@@ -204,30 +201,30 @@ public sealed class Region : IWikiEntity
Map.TheAridSea,
Map.TheScar,
Map.VultureDrifts
}
]
};
public static readonly Region RingOfFireIslands = new()
{
Id = 6,
Name = "Ring of Fire Islands",
WikiUrl = "https://wiki.guildwars.com/wiki/Ring_of_Fire_Islands",
Maps = new List<Map>
{
Maps =
[
Map.EmberLightCampOutpost,
Map.AbaddonsMouth,
Map.HellsPrecipice,
Map.RingOfFire,
Map.PerditionRock,
Map.TheFissureofWoe
}
]
};
public static readonly Region PresearingAscalon = new()
{
Id = 7,
Name = "Pre Searing Ascalon",
WikiUrl = "https://wiki.guildwars.com/wiki/Ascalon_(pre-Searing)",
Maps = new List<Map>
{
Maps =
[
Map.AscalonCityPresearing,
Map.AshfordAbbeyOutpost,
Map.AshfordCatacombs1070AE,
@@ -242,15 +239,15 @@ public sealed class Region : IWikiEntity
Map.TheCatacombs,
Map.TheNorthlands,
Map.WizardsFolly
}
]
};
public static readonly Region KainengCity = new()
{
Id = 8,
Name = "Kaineng City",
WikiUrl = "https://wiki.guildwars.com/wiki/Kaineng_City",
Maps = new List<Map>
{
Maps =
[
Map.KainengCenterOutpost,
Map.KainengCenterCanthanNewYearOutpost,
Map.KainengCenterSunspearsInCantha,
@@ -291,15 +288,15 @@ public sealed class Region : IWikiEntity
Map.WajjunBazaarWindsOfChangeMinistryOfOppression,
Map.WajjunBazaarWindsOfChangeViolenceInTheStreets,
Map.XaquangSkyway
}
]
};
public static readonly Region EchovaldForest = new()
{
Id = 9,
Name = "Echovald Forest",
WikiUrl = "https://wiki.guildwars.com/wiki/Echovald_Forest",
Maps = new List<Map>
{
Maps =
[
Map.HouseZuHeltzerOutpost,
Map.AspenwoodGateKurzickOutpost,
Map.BrauerAcademyOutpost,
@@ -326,15 +323,15 @@ public sealed class Region : IWikiEntity
Map.MelandrusHope,
Map.MorostavTrail,
Map.MourningVeilFalls
}
]
};
public static readonly Region TheJadeSea = new()
{
Id = 10,
Name = "The Jade Sea",
WikiUrl = "https://wiki.guildwars.com/wiki/The_Jade_Sea",
Maps = new List<Map>
{
Maps =
[
Map.CavalonOutpost,
Map.AspenwoodGateLuxonOutpost,
Map.BaiPaasuReachOutpost,
@@ -362,15 +359,15 @@ public sealed class Region : IWikiEntity
Map.MountQinkai,
Map.RheasCrater,
Map.SilentSurf
}
]
};
public static readonly Region ShingJeaIsland = new()
{
Id = 11,
Name = "Shing Jea Island",
WikiUrl = "https://wiki.guildwars.com/wiki/Shing_Jea_Island",
Maps = new List<Map>
{
Maps =
[
Map.ShingJeaArena,
Map.ShingJeaArenaMission,
Map.ShingJeaMonasteryCanthanNewYearOutpost,
@@ -403,15 +400,15 @@ public sealed class Region : IWikiEntity
Map.PanjiangPeninsula,
Map.SaoshangTrail,
Map.SunquaVale
}
]
};
public static readonly Region Kourna = new()
{
Id = 12,
Name = "Kourna",
WikiUrl = "https://wiki.guildwars.com/wiki/Kourna",
Maps = new List<Map>
{
Maps =
[
Map.SunspearSanctuaryOutpost,
Map.CampHojanuOutpost,
Map.WehhanTerracesOutpost,
@@ -435,15 +432,15 @@ public sealed class Region : IWikiEntity
Map.TheFloodplainOfMahnkelon,
Map.TuraisProcession,
Map.NightfallenCoast
}
]
};
public static readonly Region Vabbi = new()
{
Id = 13,
Name = "Vabbi",
WikiUrl = "https://wiki.guildwars.com/wiki/Vabbi",
Maps = new List<Map>
{
Maps =
[
Map.TheKodashBazaarOutpost,
Map.BasaltGrottoOutpost,
Map.ChantryOfSecretsOutpost,
@@ -468,15 +465,15 @@ public sealed class Region : IWikiEntity
Map.VehtendiValley,
Map.WildernessOfBahdza,
Map.YatendiCanyons
}
]
};
public static readonly Region TheDesolation = new()
{
Id = 14,
Name = "TheDesolation",
WikiUrl = "https://wiki.guildwars.com/wiki/The_Desolation",
Maps = new List<Map>
{
Maps =
[
Map.BonePalaceOutpost,
Map.LairOfTheForgottenOutpost,
Map.TheMouthOfTormentOutpost,
@@ -490,15 +487,15 @@ public sealed class Region : IWikiEntity
Map.TheRupturedHeart,
Map.TheShatteredRavines,
Map.TheSulfurousWastes
}
]
};
public static readonly Region Istan = new()
{
Id = 15,
Name = "Istan",
WikiUrl = "https://wiki.guildwars.com/wiki/Istan",
Maps = new List<Map>
{
Maps =
[
Map.KamadanJewelOfIstanCanthanNewYearOutpost,
Map.KamadanJewelOfIstanExplorable,
Map.KamadanJewelOfIstanHalloweenOutpost,
@@ -529,15 +526,15 @@ public sealed class Region : IWikiEntity
Map.PlainsOfJarin,
Map.SunDocks,
Map.ZehlonReach
}
]
};
public static readonly Region RealmOfTorment = new()
{
Id = 16,
Name = "Realm of Torment",
WikiUrl = "https://wiki.guildwars.com/wiki/Realm_of_Torment",
Maps = new List<Map>
{
Maps =
[
Map.DomainOfAnguish,
Map.GateOfTormentOutpost,
Map.GateOfFearOutpost,
@@ -556,15 +553,15 @@ public sealed class Region : IWikiEntity
Map.NightfallenGarden,
Map.NightfallenJahai,
Map.ThroneOfSecrets
}
]
};
public static readonly Region TarnishedCoast = new()
{
Id = 17,
Name = "Tarnished Coast",
WikiUrl = "https://wiki.guildwars.com/wiki/Tarnished_Coast",
Maps = new List<Map>
{
Maps =
[
Map.RataSumOutpost,
Map.GaddsEncampmentOutpost,
Map.TarnishedHavenOutpost,
@@ -587,15 +584,15 @@ public sealed class Region : IWikiEntity
Map.RivenEarth,
Map.SparkflySwamp,
Map.VerdantCascades
}
]
};
public static readonly Region DepthsOfTyria = new()
{
Id = 18,
Name = "Depths Of Tyria",
WikiUrl = "https://wiki.guildwars.com/wiki/Depths_of_Tyria",
Maps = new List<Map>
{
Maps =
[
Map.CentralTransferChamberOutpost,
Map.DestructionsDepthsMission,
Map.DestructionsDepthsLevel1,
@@ -657,15 +654,15 @@ public sealed class Region : IWikiEntity
Map.VloxenExcavationsLevel1,
Map.VloxenExcavationsLevel2,
Map.VloxenExcavationsLevel3
}
]
};
public static readonly Region FarShiverpeaks = new()
{
Id = 19,
Name = "Far Shiverpeaks",
WikiUrl = "https://wiki.guildwars.com/wiki/Far_Shiverpeaks",
Maps = new List<Map>
{
Maps =
[
Map.GunnarsHoldOutpost,
Map.BorealStationOutpost,
Map.EyeOfTheNorthOutpost,
@@ -693,15 +690,15 @@ public sealed class Region : IWikiEntity
Map.NorrhartDomains,
Map.PolymockGlacier,
Map.VarajarFells
}
]
};
public static readonly Region CharrHomelands = new()
{
Id = 20,
Name = "Charr Homelands",
WikiUrl = "https://wiki.guildwars.com/wiki/Charr_Homelands",
Maps = new List<Map>
{
Maps =
[
Map.DoomloreShrineOutpost,
Map.AgainstTheCharr,
Map.AgainstTheCharrMission,
@@ -715,15 +712,15 @@ public sealed class Region : IWikiEntity
Map.GrothmarWardowns,
Map.PolymockCrossing,
Map.SacnothValley
}
]
};
public static readonly Region TheBattleIsles = new()
{
Id = 21,
Name = "The Battle Isles",
WikiUrl = "https://wiki.guildwars.com/wiki/The_Battle_Isles",
Maps = new List<Map>
{
Maps =
[
Map.GreatTempleOfBalthazarOutpost,
Map.IsleOfTheDeadGuildHall,
Map.IsleOfTheDeadGuildHallMission,
@@ -773,53 +770,53 @@ public sealed class Region : IWikiEntity
Map.UnchartedIsle,
Map.UnchartedIsleMission,
Map.UnchartedIsleOutpost
}
]
};
public static readonly Region TheBattleOfJahai = new()
{
Id = 22,
Name = "The Battle Of Jahai",
WikiUrl = "https://wiki.guildwars.com/wiki/The_Battle_of_Jahai",
Maps = new List<Map>
{
Maps =
[
Map.TheBattleOfJahai
}
]
};
public static readonly Region TheFlightNorth = new()
{
Id = 23,
Name = "The Flight North",
WikiUrl = "https://wiki.guildwars.com/wiki/The_Flight_North",
Maps = new List<Map>
{
Maps =
[
Map.TheFlightNorth
}
]
};
public static readonly Region TheTenguAccords = new()
{
Id = 24,
Name = "The Tengu Accords",
WikiUrl = "https://wiki.guildwars.com/wiki/The_Tengu_Accords",
Maps = new List<Map>
{
Maps =
[
Map.TheTenguAccords
}
]
};
public static readonly Region TheRiseOfTheWhiteMantle = new()
{
Id = 25,
Name = "The Rise Of The White Mantle",
WikiUrl = "https://wiki.guildwars.com/wiki/The_Rise_of_the_White_Mantle",
Maps = new List<Map>
{
Maps =
[
Map.TheRiseOfTheWhiteMantle
}
]
};
public static readonly Region Swat = new() { Id = 26 };
public static readonly Region DevRegion = new() { Id = 27 };
public static IReadOnlyList<Region> Regions { get; } = new List<Region>()
{
public static IReadOnlyList<Region> Regions { get; } =
[
Kryta,
MaguumaJungle,
Ascalon,
@@ -847,7 +844,7 @@ public sealed class Region : IWikiEntity
TheRiseOfTheWhiteMantle,
Swat,
DevRegion
};
];
public static bool TryParse(int id, out Region region)
{
+1 -3
View File
@@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class Rune : ItemBase, IWikiEntity, IIconUrlEntity, IItemModHash
{
public static readonly Rune KnightsInsignia = new() { Id = 19152, Name = "Knight's Insignia", Modifiers = [0x25B80000, 0x240801F9, 0xA53003F2, 0xA7F80300, 0xC0000000], ModHash = "25B80000240801F9A53003F2A7F80300C0000000", WikiUrl = "https://wiki.guildwars.com/wiki/Knight's_Insignia", IconUrl = "https://wiki.guildwars.com/images/7/79/Knight%27s_Insignia.png" };
+2 -5
View File
@@ -1,8 +1,5 @@
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
@@ -1494,7 +1491,7 @@ public sealed class Skill
public static readonly Skill WeaponsofThreeForges = new() { Id = 3429, Name = "Weapons of Three Forges", Profession = Profession.Ritualist };
public static readonly Skill VowofRevolution = new() { Id = 3430, Name = "Vow of Revolution", Profession = Profession.Dervish };
public static readonly Skill HeroicRefrain = new() { Id = 3431, Name = "Heroic Refrain", Profession = Profession.Paragon };
public static readonly IReadOnlyCollection<Skill> Skills = new List<Skill>
public static readonly IReadOnlyCollection<Skill> Skills = [.. new List<Skill>
{
NoSkill,
ResurrectionSignet,
@@ -2981,7 +2978,7 @@ public sealed class Skill
WeaponsofThreeForges,
VowofRevolution,
HeroicRefrain,
}.OrderBy(s => s.Name).ToList();
}.OrderBy(s => s.Name)];
public static bool TryParse(int id, out Skill skill)
{
+3 -6
View File
@@ -1,8 +1,5 @@
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
@@ -56,8 +53,8 @@ public sealed class Title : IWikiEntity
public static readonly Title Wisdom = new() { Id = 46, Name = "Wisdom", WikiUrl = "https://wiki.guildwars.com/wiki/Wisdom", Tiers = ["Seeker of Wisdom", "Collector of Wisdom", "Devotee of Wisdom", "Devourer of Wisdom", "Font of Wisdom", "Oracle of Wisdom", "Source of Wisdom"] };
public static readonly Title Codex = new() { Id = 47, Name = "Codex", WikiUrl = "https://wiki.guildwars.com/wiki/Codex_Title", Tiers = ["Codex Initiate", "Codex Acolyte", "Codex Disciple", "Codex Zealot", "Codex Stalwart", "Codex Adept", "Codex Exemplar", "Codex Prodigy", "Codex Champion", "Codex Paragon", "Codex Master", "Codex Grandmaster"] };
public static readonly IEnumerable<Title> Titles = new List<Title>
{
public static readonly IEnumerable<Title> Titles =
[
None,
Hero,
TyrianCartographer,
@@ -104,7 +101,7 @@ public sealed class Title : IWikiEntity
TreasureHunter,
Wisdom,
Codex
};
];
public static bool TryParse(int id, out Title title)
{
@@ -1,6 +1,4 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class VialOfDye : ItemBase, IItemModHash, IWikiEntity, IIconUrlEntity
{
@@ -1,58 +0,0 @@
using System.Runtime.InteropServices;
namespace Daybreak.Shared.Models.Interop;
[StructLayout(LayoutKind.Explicit)]
public readonly struct AreaContext
{
[FieldOffset(0x0000)]
public readonly uint Campaign;
[FieldOffset(0x0004)]
public readonly uint Continent;
[FieldOffset(0x0008)]
public readonly uint RegionId;
[FieldOffset(0x000C)]
public readonly uint RegionType;
[FieldOffset(0x0010)]
public readonly uint Flags;
[FieldOffset(0x0018)]
public readonly uint MinPartySize;
[FieldOffset(0x001C)]
public readonly uint MaxPartySize;
[FieldOffset(0x0020)]
public readonly uint MinPlayerSize;
[FieldOffset(0x0024)]
public readonly uint MaxPlayerSize;
[FieldOffset(0x0028)]
public readonly uint ControlledOutpostId;
[FieldOffset(0x0030)]
public readonly uint MinLevel;
[FieldOffset(0x0034)]
public readonly uint MaxLevel;
[FieldOffset(0x003C)]
public readonly uint MissionMapsTo;
[FieldOffset(0x0040)]
public readonly uint IconPositionX;
[FieldOffset(0x0044)]
public readonly uint IconPositionY;
[FieldOffset(0x0074)]
public readonly uint NameId;
[FieldOffset(0x0078)]
public readonly uint DescriptionId;
}
@@ -1,47 +0,0 @@
using System.Runtime.InteropServices;
namespace Daybreak.Shared.Models.Interop;
[StructLayout(LayoutKind.Explicit)]
public readonly struct AreaInfoContext
{
[FieldOffset(0x0000)]
public readonly uint CampaignId;
[FieldOffset(0x0004)]
public readonly uint ContinentId;
[FieldOffset(0x0008)]
public readonly uint RegionId;
[FieldOffset(0x000C)]
public readonly RegionType RegionType;
[FieldOffset(0x0010)]
public readonly uint Flags;
[FieldOffset(0x0018)]
public readonly uint MinPartySize;
[FieldOffset(0x001C)]
public readonly uint MaxPartySize;
[FieldOffset(0x0020)]
public readonly uint MinPlayerSize;
[FieldOffset(0x0024)]
public readonly uint MaxPlayerSize;
[FieldOffset(0x0030)]
public readonly uint MinLevel;
[FieldOffset(0x0034)]
public readonly uint MaxLevel;
[FieldOffset(0x0040)]
public readonly uint IconPositionX;
[FieldOffset(0x0044)]
public readonly uint IconPositionY;
[FieldOffset(0x0048)]
public readonly uint IconStartX;
[FieldOffset(0x004C)]
public readonly uint IconStartY;
[FieldOffset(0x0050)]
public readonly uint IconEndX;
[FieldOffset(0x0054)]
public readonly uint IconEndY;
public bool HasEnterButton => (this.Flags & 0x100) != 0 || (this.Flags & 0x40000) != 0;
public bool IsOnWorldMap => (this.Flags & 0x20) == 0;
public bool IsPvp => (this.Flags & 0x1) != 0;
public bool IsGuildHall => (this.Flags & 0x800000) != 0;
}
@@ -1,14 +0,0 @@
namespace Daybreak.Shared.Models.Interop;
public readonly struct AttributeContext
{
public readonly uint Id;
public readonly uint BaseLevel;
public readonly uint ActualLevel;
public readonly uint DecrementPoints;
public readonly uint IncrementPoints;
}
-25
View File
@@ -1,25 +0,0 @@
using System.Runtime.InteropServices;
namespace Daybreak.Shared.Models.Interop;
[StructLayout(LayoutKind.Explicit)]
public readonly struct BagInfo
{
[FieldOffset(0x0000)]
public readonly uint Type;
[FieldOffset(0x0004)]
public readonly uint Index;
[FieldOffset(0x0008)]
public readonly uint Id;
[FieldOffset(0x000C)]
public readonly uint Container;
[FieldOffset(0x0010)]
public readonly uint ItemsCount;
[FieldOffset(0x0018)]
public readonly GuildwarsPointerArray<ItemInfo> Items;
}

Some files were not shown because too many files have changed in this diff Show More