Compare commits

...

39 Commits
v4.3 ... master

Author SHA1 Message Date
d239a6e4b0
API 10 2024-07-06 13:26:39 +02:00
9d5e4a797b
Update Dockerfile 2024-07-06 13:20:17 +02:00
3e2f917c14
API 10 2024-07-06 13:14:59 +02:00
2fdf9b1e4d
Remove GitInfo dependency 2024-01-16 11:41:13 +01:00
18ffd66086
Update icon URL 2024-01-16 07:03:56 +01:00
64e576a004
Render: Ensure RenderElement is null if we don't recreate it 2023-11-30 14:01:59 +01:00
0d1882d97f
Render: Performance fix 2023-11-26 22:14:04 +01:00
964119cfd2
Render: Use enabled instead of color for showing/hiding elements 2023-11-26 20:13:17 +01:00
309edfcd17
Bump version/recompile 2023-11-14 20:21:40 +01:00
8fbd3fbc0d
Update docker build 2023-11-11 01:56:09 +01:00
ce9be45e8f
Update docker build 2023-11-11 01:54:43 +01:00
8def5e28a4
Update dependencies 2023-11-11 01:41:15 +01:00
ba06576c2d
Update dependencies 2023-11-11 01:39:17 +01:00
f259f03534
Update server submodule structure 2023-11-11 01:39:10 +01:00
cf3a24afe8
Update header icon logic for Dalamud changes 2023-11-09 11:32:32 +01:00
2a180345eb
Update submodule URL 2023-10-14 00:02:21 +02:00
345c9c59a3
Add LLib, remove outdated info, add config window constraints 2023-10-11 03:56:18 +02:00
5c4e9f30e0
API 9 2023-10-03 22:05:19 +02:00
d337413b82 Update docker-build.sh 2023-10-03 17:54:53 +00:00
5a5d7fecfd
Change nuget lib path 2023-10-03 11:10:43 +02:00
1ee86d378f
API 9 2023-10-03 11:08:38 +02:00
cd52192d15
Setup server/test submodules 2023-09-17 22:28:37 +02:00
6260f35b61 Update repo location 2023-07-31 02:58:24 +02:00
79ad7fbc39 Update README 2023-07-30 23:53:47 +02:00
1bdcc7179c Update image location 2023-07-30 23:26:15 +02:00
5ba18477b4 Update repo url 2023-07-30 23:22:33 +02:00
5f506bda8a Update server url 2023-07-30 22:32:39 +02:00
bbec57c3ad Update actions 2023-07-30 21:49:14 +02:00
58404b9728 Fix floor change regex (for pomanders)
Not sure how or why that even broke, the string doesn't seem to have changed in the LogMessage sheet.

Fixes #18.
2023-04-13 09:17:06 +02:00
8042aee951 Use file-scoped namespaces 2023-03-30 22:02:51 +02:00
0b07e8b8f6 Code cleanup 2023-03-27 20:00:30 +02:00
7e73430179 Add palace service tests, remove standalone client 2023-03-27 18:02:18 +02:00
cec3597629 Update dependencies 2023-03-26 15:57:50 +02:00
ae29eaa52f Update ECommons 2023-03-26 15:49:52 +02:00
b81ced33e8 Code style tweaks 2023-03-26 15:47:43 +02:00
87806397d1 Configure GHA caching 2023-03-26 14:26:12 +02:00
d645aa9ea7 Configure GHA dotnet test timeout 2023-03-26 13:55:30 +02:00
4288440e6c Add export tests 2023-03-26 03:11:01 +02:00
36b328c29e Add simple account test 2023-03-25 19:14:32 +01:00
101 changed files with 5442 additions and 5251 deletions

View File

@ -4,4 +4,6 @@
.gitignore .gitignore
Dockerfile Dockerfile
.dockerignore .dockerignore
docker-build.sh
.vs/ .vs/
.idea/

31
.editorconfig Normal file
View File

@ -0,0 +1,31 @@
root = true
[*]
indent_style = space
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[{*.cs}]
charset = utf-8-bom
indent_size = 4
dotnet_sort_system_directives_first = true
csharp_style_implicit_object_creation_when_type_is_apparent = true
csharp_trailing_comma_in_multiline_lists = true
csharp_place_simple_embedded_block_on_same_line = false
csharp_place_attribute_on_same_line = false
resharper_indent_text = ZeroIndent
# methods
csharp_style_expression_bodied_methods = true
# namespaces
csharp_style_namespace_declarations = file_scoped
# braces
csharp_prefer_braces = when_multiline
[{*.resx,*.Designer.cs,packages.lock.json}]
generated_code = true
ij_formatter_enabled = false

View File

@ -1,32 +0,0 @@
name: dotnet build
on:
push:
paths-ignore:
- '**.md'
- 'Dockerfile'
jobs:
build:
runs-on: windows-latest
env:
DOTNET_CLI_TELEMETRY_OPTOUT: 'true'
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Setup .NET SDK
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0
- name: Download Dalamud
run: |
Invoke-WebRequest -Uri https://goatcorp.github.io/dalamud-distrib/latest.zip -OutFile latest.zip
Expand-Archive -Force latest.zip "$env:AppData\XIVLauncher\addon\Hooks\dev\"
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore

View File

@ -1,31 +0,0 @@
name: docker build
on:
push:
branches:
- master
paths:
- '.github/workflows/server.yml'
- 'Pal.Common/**'
- 'Pal.Server/**'
- 'Dockerfile'
workflow_dispatch: {}
permissions:
packages: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Login to GitHub Package Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
push: true
tags: ghcr.io/${{ github.repository_owner }}/palace-pal:latest

View File

@ -1,24 +0,0 @@
name: Upload to Crowdin
on:
push:
branches:
- master
paths:
- 'Pal.Client/Properties/*.resx'
- 'crowdin.yml'
workflow_dispatch: {}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Crowdin Action
uses: crowdin/github-action@1.4.9
with:
upload_sources: true
upload_translations: true
download_translations: false
crowdin_branch_name: ${{ github.ref_name }}
env:
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}

6
.gitmodules vendored
View File

@ -1,3 +1,9 @@
[submodule "vendor/ECommons"] [submodule "vendor/ECommons"]
path = vendor/ECommons path = vendor/ECommons
url = https://github.com/NightmareXIV/ECommons url = https://github.com/NightmareXIV/ECommons
[submodule "vendor/LLib"]
path = vendor/LLib
url = https://git.carvel.li/liza/LLib.git
[submodule "Server"]
path = Server
url = https://git.carvel.li/liza/PalacePal.Server.git

View File

@ -1,13 +1,19 @@
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build-env FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
ARG TARGETARCH
WORKDIR /build WORKDIR /build
COPY Pal.Common/Pal.Common.csproj Pal.Common/ COPY Pal.Common/Pal.Common.csproj Pal.Common/
COPY Pal.Server/Pal.Server.csproj Pal.Server/ COPY Server/Server/Pal.Server.csproj Server/Server/
RUN dotnet restore Pal.Server/Pal.Server.csproj RUN dotnet restore Server/Server/Pal.Server.csproj -a $TARGETARCH
COPY . ./ COPY . ./
RUN dotnet publish Pal.Server/Pal.Server.csproj --configuration Release --no-restore -o /dist RUN dotnet publish Server/Server/Pal.Server.csproj -a $TARGETARCH --no-restore -o /dist
FROM mcr.microsoft.com/dotnet/aspnet:8.0
# fix later
ENV DOTNET_ROLL_FORWARD=Major
ENV DOTNET_ROLL_FORWARD_PRE_RELEASE=1
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
EXPOSE 5415 EXPOSE 5415
ENV DOTNET_ENVIRONMENT=Production ENV DOTNET_ENVIRONMENT=Production
ENV ASPNETCORE_URLS= ENV ASPNETCORE_URLS=

View File

@ -1,10 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Pal.Client.Commands namespace Pal.Client.Commands;
{
public interface ISubCommand public interface ISubCommand
{ {
IReadOnlyDictionary<string, Action<string>> GetHandlers(); IReadOnlyDictionary<string, Action<string>> GetHandlers();
} }
}

View File

@ -3,8 +3,8 @@ using System.Collections.Generic;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Client.Windows; using Pal.Client.Windows;
namespace Pal.Client.Commands namespace Pal.Client.Commands;
{
internal class PalConfigCommand : ISubCommand internal class PalConfigCommand : ISubCommand
{ {
private readonly IPalacePalConfiguration _configuration; private readonly IPalacePalConfiguration _configuration;
@ -37,4 +37,3 @@ namespace Pal.Client.Commands
_configWindow.Toggle(); _configWindow.Toggle();
} }
} }
}

View File

@ -1,22 +1,22 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Dalamud.Game.ClientState; using Dalamud.Plugin.Services;
using Pal.Client.DependencyInjection; using Pal.Client.DependencyInjection;
using Pal.Client.Extensions; using Pal.Client.Extensions;
using Pal.Client.Floors; using Pal.Client.Floors;
using Pal.Client.Rendering; using Pal.Client.Rendering;
namespace Pal.Client.Commands namespace Pal.Client.Commands;
{
internal sealed class PalNearCommand : ISubCommand internal sealed class PalNearCommand : ISubCommand
{ {
private readonly Chat _chat; private readonly Chat _chat;
private readonly ClientState _clientState; private readonly IClientState _clientState;
private readonly TerritoryState _territoryState; private readonly TerritoryState _territoryState;
private readonly FloorService _floorService; private readonly FloorService _floorService;
public PalNearCommand(Chat chat, ClientState clientState, TerritoryState territoryState, public PalNearCommand(Chat chat, IClientState clientState, TerritoryState territoryState,
FloorService floorService) FloorService floorService)
{ {
_chat = chat; _chat = chat;
@ -50,7 +50,7 @@ namespace Pal.Client.Commands
var nearbyMarkers = state.Locations var nearbyMarkers = state.Locations
.Where(m => predicate(m)) .Where(m => predicate(m))
.Where(m => m.RenderElement != null && m.RenderElement.Color != RenderData.ColorInvisible) .Where(m => m.RenderElement != null && m.RenderElement.Enabled)
.Select(m => new { m, distance = (playerPosition.Value - m.Position).Length() }) .Select(m => new { m, distance = (playerPosition.Value - m.Position).Length() })
.OrderBy(m => m.distance) .OrderBy(m => m.distance)
.Take(5) .Take(5)
@ -60,4 +60,3 @@ namespace Pal.Client.Commands
$"{nearbyMarker.distance:F2} - {nearbyMarker.m.Type} {nearbyMarker.m.NetworkId?.ToPartialId(length: 8)} - {nearbyMarker.m.Position}"); $"{nearbyMarker.distance:F2} - {nearbyMarker.m.Type} {nearbyMarker.m.NetworkId?.ToPartialId(length: 8)} - {nearbyMarker.m.Position}");
} }
} }
}

View File

@ -2,8 +2,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using Pal.Client.DependencyInjection; using Pal.Client.DependencyInjection;
namespace Pal.Client.Commands namespace Pal.Client.Commands;
{
internal sealed class PalStatsCommand : ISubCommand internal sealed class PalStatsCommand : ISubCommand
{ {
private readonly StatisticsService _statisticsService; private readonly StatisticsService _statisticsService;
@ -22,4 +22,3 @@ namespace Pal.Client.Commands
private void Execute() private void Execute()
=> _statisticsService.ShowGlobalStatistics(); => _statisticsService.ShowGlobalStatistics();
} }
}

View File

@ -3,8 +3,8 @@ using System.Collections.Generic;
using ECommons.Schedulers; using ECommons.Schedulers;
using Pal.Client.Windows; using Pal.Client.Windows;
namespace Pal.Client.Commands namespace Pal.Client.Commands;
{
internal sealed class PalTestConnectionCommand : ISubCommand internal sealed class PalTestConnectionCommand : ISubCommand
{ {
private readonly ConfigWindow _configWindow; private readonly ConfigWindow _configWindow;
@ -27,4 +27,3 @@ namespace Pal.Client.Commands
var _ = new TickScheduler(() => _configWindow.TestConnection()); var _ = new TickScheduler(() => _configWindow.TestConnection());
} }
} }
}

View File

@ -4,15 +4,12 @@ using System.Security.Cryptography;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace Pal.Client.Configuration namespace Pal.Client.Configuration;
{
public sealed class AccountConfigurationV7 : IAccountConfiguration public sealed class AccountConfigurationV7 : IAccountConfiguration
{ {
private const int DefaultEntropyLength = 16; private const int DefaultEntropyLength = 16;
private static readonly ILogger _logger =
DependencyInjectionContext.LoggerProvider.CreateLogger<AccountConfigurationV7>();
[JsonConstructor] [JsonConstructor]
public AccountConfigurationV7() public AccountConfigurationV7()
{ {
@ -75,9 +72,8 @@ namespace Pal.Client.Configuration
byte[] guidBytes = ProtectedData.Unprotect(Convert.FromBase64String(EncryptedId), Entropy, DataProtectionScope.CurrentUser); byte[] guidBytes = ProtectedData.Unprotect(Convert.FromBase64String(EncryptedId), Entropy, DataProtectionScope.CurrentUser);
return new Guid(guidBytes); return new Guid(guidBytes);
} }
catch (Exception e) catch (Exception)
{ {
_logger.LogTrace(e, "Could not load account id {Id}", EncryptedId);
return null; return null;
} }
} }
@ -146,4 +142,3 @@ namespace Pal.Client.Configuration
ProtectedDataUnsupported = 3, ProtectedDataUnsupported = 3,
} }
} }
}

View File

@ -3,19 +3,17 @@ using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace Pal.Client.Configuration namespace Pal.Client.Configuration;
{
internal static class ConfigurationData internal static class ConfigurationData
{ {
private static readonly ILogger _logger =
DependencyInjectionContext.LoggerProvider.CreateLogger(typeof(ConfigurationData));
[Obsolete("for V1 import")] [Obsolete("for V1 import")]
internal static readonly byte[] FixedV1Entropy = { 0x22, 0x4b, 0xe7, 0x21, 0x44, 0x83, 0x69, 0x55, 0x80, 0x38 }; internal static readonly byte[] FixedV1Entropy = { 0x22, 0x4b, 0xe7, 0x21, 0x44, 0x83, 0x69, 0x55, 0x80, 0x38 };
public const string ConfigFileName = "palace-pal.config.json"; public const string ConfigFileName = "palace-pal.config.json";
private static bool? _supportsDpapi = null; private static bool? _supportsDpapi;
public static bool SupportsDpapi public static bool SupportsDpapi
{ {
get get
@ -34,11 +32,9 @@ namespace Pal.Client.Configuration
{ {
_supportsDpapi = false; _supportsDpapi = false;
} }
_logger.LogTrace("DPAPI support: {Supported}", _supportsDpapi);
} }
return _supportsDpapi.Value; return _supportsDpapi.Value;
} }
} }
} }
}

View File

@ -13,17 +13,17 @@ using Pal.Client.Configuration.Legacy;
using Pal.Client.Database; using Pal.Client.Database;
using NJson = Newtonsoft.Json; using NJson = Newtonsoft.Json;
namespace Pal.Client.Configuration namespace Pal.Client.Configuration;
{
internal sealed class ConfigurationManager internal sealed class ConfigurationManager
{ {
private readonly ILogger<ConfigurationManager> _logger; private readonly ILogger<ConfigurationManager> _logger;
private readonly DalamudPluginInterface _pluginInterface; private readonly IDalamudPluginInterface _pluginInterface;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
public event EventHandler<IPalacePalConfiguration>? Saved; public event EventHandler<IPalacePalConfiguration>? Saved;
public ConfigurationManager(ILogger<ConfigurationManager> logger, DalamudPluginInterface pluginInterface, public ConfigurationManager(ILogger<ConfigurationManager> logger, IDalamudPluginInterface pluginInterface,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
{ {
_logger = logger; _logger = logger;
@ -87,7 +87,9 @@ namespace Pal.Client.Configuration
dbContext.Imports.Add(new ImportHistory dbContext.Imports.Add(new ImportHistory
{ {
Id = importHistory.Id, Id = importHistory.Id,
RemoteUrl = importHistory.RemoteUrl?.Replace(".μ.tv", ".liza.sh"), RemoteUrl = importHistory.RemoteUrl
?.Replace(".μ.tv", ".liza.sh")
.Replace("pal.liza.sh", "connect.palacepal.com"),
ExportedAt = importHistory.ExportedAt, ExportedAt = importHistory.ExportedAt,
ImportedAt = importHistory.ImportedAt ImportedAt = importHistory.ImportedAt
}); });
@ -98,6 +100,17 @@ namespace Pal.Client.Configuration
File.Move(_pluginInterface.ConfigFile.FullName, _pluginInterface.ConfigFile.FullName + ".old", true); File.Move(_pluginInterface.ConfigFile.FullName, _pluginInterface.ConfigFile.FullName + ".old", true);
} }
IPalacePalConfiguration? currentConfig = Load();
IAccountConfiguration? legacyAccount = currentConfig?.FindAccount("https://pal.liza.sh");
if (currentConfig != null && legacyAccount != null)
{
IAccountConfiguration newAccount = currentConfig.CreateAccount("https://connect.palacepal.com", legacyAccount.AccountId);
newAccount.CachedRoles = legacyAccount.CachedRoles;
currentConfig.RemoveAccount(legacyAccount.Server);
Save(currentConfig, false);
}
} }
private ConfigurationV7 MigrateToV7(ConfigurationV1 v1) private ConfigurationV7 MigrateToV7(ConfigurationV1 v1)
@ -141,7 +154,9 @@ namespace Pal.Client.Configuration
if (string.IsNullOrEmpty(accountId)) if (string.IsNullOrEmpty(accountId))
continue; continue;
string serverName = server.Replace(".μ.tv", ".liza.sh"); string serverName = server
.Replace(".μ.tv", ".liza.sh")
.Replace("pal.liza.sh", "connect.palacepal.com");
IAccountConfiguration newAccount = v7.CreateAccount(serverName, accountId); IAccountConfiguration newAccount = v7.CreateAccount(serverName, accountId);
newAccount.CachedRoles = oldAccount.CachedRoles.ToList(); newAccount.CachedRoles = oldAccount.CachedRoles.ToList();
} }
@ -153,4 +168,3 @@ namespace Pal.Client.Configuration
#pragma warning restore CS0618 #pragma warning restore CS0618
#pragma warning restore CS0612 #pragma warning restore CS0612
} }
}

View File

@ -2,8 +2,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Pal.Client.Configuration namespace Pal.Client.Configuration;
{
public sealed class ConfigurationV7 : IPalacePalConfiguration, IConfigurationInConfigDirectory public sealed class ConfigurationV7 : IPalacePalConfiguration, IConfigurationInConfigDirectory
{ {
public int Version { get; set; } = 7; public int Version { get; set; } = 7;
@ -51,4 +51,3 @@ namespace Pal.Client.Configuration
return account == null || account.CachedRoles.Contains(role); return account == null || account.CachedRoles.Contains(role);
} }
} }
}

View File

@ -1,5 +1,5 @@
namespace Pal.Client.Configuration namespace Pal.Client.Configuration;
{
public enum EMode public enum EMode
{ {
/// <summary> /// <summary>
@ -8,8 +8,7 @@
Online = 1, Online = 1,
/// <summary> /// <summary>
/// Only shows traps found by yourself uisng a pomander of sight. /// Only shows traps found by yourself using a pomander of sight.
/// </summary> /// </summary>
Offline = 2, Offline = 2,
} }
}

View File

@ -1,5 +1,5 @@
namespace Pal.Client.Configuration namespace Pal.Client.Configuration;
{
public enum ERenderer public enum ERenderer
{ {
/// <see cref="Rendering.SimpleRenderer"/> /// <see cref="Rendering.SimpleRenderer"/>
@ -8,4 +8,3 @@
/// <see cref="Rendering.SplatoonRenderer"/> /// <see cref="Rendering.SplatoonRenderer"/>
Splatoon = 1, Splatoon = 1,
} }
}

View File

@ -4,8 +4,8 @@ using System.Numerics;
using ImGuiNET; using ImGuiNET;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Pal.Client.Configuration namespace Pal.Client.Configuration;
{
public interface IVersioned public interface IVersioned
{ {
int Version { get; set; } int Version { get; set; }
@ -108,4 +108,3 @@ namespace Pal.Client.Configuration
public int MinimumBackupsToKeep { get; set; } = 3; public int MinimumBackupsToKeep { get; set; } = 3;
public int DaysToDeleteAfter { get; set; } = 21; public int DaysToDeleteAfter { get; set; } = 21;
} }
}

View File

@ -8,8 +8,8 @@ using Dalamud.Plugin;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Pal.Client.Configuration.Legacy namespace Pal.Client.Configuration.Legacy;
{
[Obsolete] [Obsolete]
public sealed class ConfigurationV1 public sealed class ConfigurationV1
{ {
@ -50,7 +50,7 @@ namespace Pal.Client.Configuration.Legacy
public string BetaKey { get; set; } = ""; public string BetaKey { get; set; } = "";
#endregion #endregion
public void Migrate(DalamudPluginInterface pluginInterface, ILogger<ConfigurationV1> logger) public void Migrate(IDalamudPluginInterface pluginInterface, ILogger<ConfigurationV1> logger)
{ {
if (Version == 1) if (Version == 1)
{ {
@ -137,7 +137,7 @@ namespace Pal.Client.Configuration.Legacy
} }
} }
public void Save(DalamudPluginInterface pluginInterface) public void Save(IDalamudPluginInterface pluginInterface)
{ {
File.WriteAllText(pluginInterface.ConfigFile.FullName, JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings File.WriteAllText(pluginInterface.ConfigFile.FullName, JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings
{ {
@ -164,4 +164,3 @@ namespace Pal.Client.Configuration.Legacy
public DateTime ImportedAt { get; set; } public DateTime ImportedAt { get; set; }
} }
} }
}

View File

@ -7,8 +7,8 @@ using System.Text.Json;
using Pal.Client.Extensions; using Pal.Client.Extensions;
using Pal.Common; using Pal.Common;
namespace Pal.Client.Configuration.Legacy namespace Pal.Client.Configuration.Legacy;
{
/// <summary> /// <summary>
/// Legacy JSON file for marker locations. /// Legacy JSON file for marker locations.
/// </summary> /// </summary>
@ -19,7 +19,6 @@ namespace Pal.Client.Configuration.Legacy
private const int CurrentVersion = 4; private const int CurrentVersion = 4;
private static string _pluginConfigDirectory = null!; private static string _pluginConfigDirectory = null!;
private static readonly EMode _mode = EMode.Online; // might not be true, but this is 'less strict filtering' for migrations
internal static void SetContextProperties(string pluginConfigDirectory) internal static void SetContextProperties(string pluginConfigDirectory)
{ {
@ -36,11 +35,6 @@ namespace Pal.Client.Configuration.Legacy
private void ApplyFilters() private void ApplyFilters()
{ {
if (_mode == EMode.Offline)
Markers = new ConcurrentBag<JsonMarker>(Markers.Where(x => x.Seen || (x.WasImported && x.Imports.Count > 0)));
else
// ensure old import markers are removed if they are no longer part of a "current" import
// this MAY remove markers the server sent you (and that you haven't seen), but this should be fixed the next time you enter the zone
Markers = new ConcurrentBag<JsonMarker>(Markers.Where(x => x.Seen || !x.WasImported || x.Imports.Count > 0)); Markers = new ConcurrentBag<JsonMarker>(Markers.Where(x => x.Seen || !x.WasImported || x.Imports.Count > 0));
} }
@ -165,4 +159,3 @@ namespace Pal.Client.Configuration.Legacy
public HashSet<JsonMarker> Markers { get; set; } = new(); public HashSet<JsonMarker> Markers { get; set; } = new();
} }
} }
}

View File

@ -2,8 +2,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Numerics; using System.Numerics;
namespace Pal.Client.Configuration.Legacy namespace Pal.Client.Configuration.Legacy;
{
[Obsolete] [Obsolete]
public class JsonMarker public class JsonMarker
{ {
@ -23,4 +23,3 @@ namespace Pal.Client.Configuration.Legacy
Debug = 3, Debug = 3,
} }
} }
}

View File

@ -12,8 +12,8 @@ using Microsoft.Extensions.Logging;
using Pal.Client.Database; using Pal.Client.Database;
using Pal.Common; using Pal.Common;
namespace Pal.Client.Configuration.Legacy namespace Pal.Client.Configuration.Legacy;
{
/// <summary> /// <summary>
/// Imports legacy territoryType.json files into the database if it exists, and no markers for that territory exist. /// Imports legacy territoryType.json files into the database if it exists, and no markers for that territory exist.
/// </summary> /// </summary>
@ -21,10 +21,10 @@ namespace Pal.Client.Configuration.Legacy
{ {
private readonly ILogger<JsonMigration> _logger; private readonly ILogger<JsonMigration> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly DalamudPluginInterface _pluginInterface; private readonly IDalamudPluginInterface _pluginInterface;
public JsonMigration(ILogger<JsonMigration> logger, IServiceScopeFactory serviceScopeFactory, public JsonMigration(ILogger<JsonMigration> logger, IServiceScopeFactory serviceScopeFactory,
DalamudPluginInterface pluginInterface) IDalamudPluginInterface pluginInterface)
{ {
_logger = logger; _logger = logger;
_serviceScopeFactory = serviceScopeFactory; _serviceScopeFactory = serviceScopeFactory;
@ -144,4 +144,3 @@ namespace Pal.Client.Configuration.Legacy
} }
#pragma warning restore CS0612 #pragma warning restore CS0612
} }
}

View File

@ -6,8 +6,8 @@ using Microsoft.Extensions.Logging;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Common; using Pal.Common;
namespace Pal.Client.Database namespace Pal.Client.Database;
{
internal sealed class Cleanup internal sealed class Cleanup
{ {
private readonly ILogger<Cleanup> _logger; private readonly ILogger<Cleanup> _logger;
@ -64,4 +64,3 @@ namespace Pal.Client.Database
return o => o.Source != ClientLocation.ESource.Download; return o => o.Source != ClientLocation.ESource.Download;
} }
} }
}

View File

@ -1,8 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace Pal.Client.Database namespace Pal.Client.Database;
{
internal sealed class ClientLocation internal sealed class ClientLocation
{ {
[Key] public int LocalId { get; set; } [Key] public int LocalId { get; set; }
@ -56,4 +56,3 @@ namespace Pal.Client.Database
Download = 4, Download = 4,
} }
} }
}

View File

@ -1,8 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Pal.Client.Database namespace Pal.Client.Database;
{
internal sealed class ImportHistory internal sealed class ImportHistory
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
@ -12,4 +12,3 @@ namespace Pal.Client.Database
public List<ClientLocation> ImportedLocations { get; set; } = new(); public List<ClientLocation> ImportedLocations { get; set; } = new();
} }
}

View File

@ -1,7 +1,7 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace Pal.Client.Database namespace Pal.Client.Database;
{
internal class PalClientContext : DbContext internal class PalClientContext : DbContext
{ {
public DbSet<ClientLocation> Locations { get; set; } = null!; public DbSet<ClientLocation> Locations { get; set; } = null!;
@ -21,4 +21,3 @@ namespace Pal.Client.Database
.UsingEntity(o => o.ToTable("LocationImports")); .UsingEntity(o => o.ToTable("LocationImports"));
} }
} }
}

View File

@ -2,8 +2,8 @@
using Pal.Client.Extensions; using Pal.Client.Extensions;
using Pal.Client.Net; using Pal.Client.Net;
namespace Pal.Client.Database namespace Pal.Client.Database;
{
/// <summary> /// <summary>
/// To avoid sending too many requests to the server, we cache which locations have been seen /// To avoid sending too many requests to the server, we cache which locations have been seen
/// locally. These never expire, and locations which have been seen with a specific account /// locally. These never expire, and locations which have been seen with a specific account
@ -38,4 +38,3 @@ namespace Pal.Client.Database
AccountId = accountId.ToPartialId(); AccountId = accountId.ToPartialId();
} }
} }
}

View File

@ -19,8 +19,8 @@ using Pal.Client.DependencyInjection;
using Pal.Client.Floors; using Pal.Client.Floors;
using Pal.Client.Windows; using Pal.Client.Windows;
namespace Pal.Client namespace Pal.Client;
{
/// <summary> /// <summary>
/// Takes care of async plugin init - this is mostly everything that requires either the config or the database to /// Takes care of async plugin init - this is mostly everything that requires either the config or the database to
/// be available. /// be available.
@ -84,7 +84,7 @@ namespace Pal.Client
private async Task RemoveOldBackups() private async Task RemoveOldBackups()
{ {
await using var scope = _serviceProvider.CreateAsyncScope(); await using var scope = _serviceProvider.CreateAsyncScope();
var pluginInterface = scope.ServiceProvider.GetRequiredService<DalamudPluginInterface>(); var pluginInterface = scope.ServiceProvider.GetRequiredService<IDalamudPluginInterface>();
var configuration = scope.ServiceProvider.GetRequiredService<IPalacePalConfiguration>(); var configuration = scope.ServiceProvider.GetRequiredService<IPalacePalConfiguration>();
var paths = Directory.GetFiles(pluginInterface.GetPluginConfigDirectory(), "backup-*.data.sqlite3", var paths = Directory.GetFiles(pluginInterface.GetPluginConfigDirectory(), "backup-*.data.sqlite3",
@ -136,7 +136,7 @@ namespace Pal.Client
{ {
await using var scope = _serviceProvider.CreateAsyncScope(); await using var scope = _serviceProvider.CreateAsyncScope();
var pluginInterface = scope.ServiceProvider.GetRequiredService<DalamudPluginInterface>(); var pluginInterface = scope.ServiceProvider.GetRequiredService<IDalamudPluginInterface>();
string backupPath = Path.Join(pluginInterface.GetPluginConfigDirectory(), string backupPath = Path.Join(pluginInterface.GetPluginConfigDirectory(),
$"backup-{DateTime.Now.ToUniversalTime():yyyy-MM-dd}.data.sqlite3"); $"backup-{DateTime.Now.ToUniversalTime():yyyy-MM-dd}.data.sqlite3");
string sourcePath = Path.Join(pluginInterface.GetPluginConfigDirectory(), string sourcePath = Path.Join(pluginInterface.GetPluginConfigDirectory(),
@ -193,4 +193,3 @@ namespace Pal.Client
await dbContext.SaveChangesAsync(); await dbContext.SaveChangesAsync();
} }
} }
}

View File

@ -1,15 +1,16 @@
using Dalamud.Game.Gui; using Dalamud.Game.Text;
using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Plugin.Services;
using ECommons.DalamudServices.Legacy;
using Pal.Client.Properties; using Pal.Client.Properties;
namespace Pal.Client.DependencyInjection namespace Pal.Client.DependencyInjection;
{
internal sealed class Chat internal sealed class Chat
{ {
private readonly ChatGui _chatGui; private readonly IChatGui _chatGui;
public Chat(ChatGui chatGui) public Chat(IChatGui chatGui)
{ {
_chatGui = chatGui; _chatGui = chatGui;
} }
@ -35,4 +36,3 @@ namespace Pal.Client.DependencyInjection
public void UnformattedMessage(string message) public void UnformattedMessage(string message)
=> _chatGui.Print(message); => _chatGui.Print(message);
} }
}

View File

@ -1,25 +1,25 @@
using System; using System;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Dalamud.Data;
using Dalamud.Game.Gui;
using Dalamud.Game.Text; using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Plugin.Services;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Client.Floors; using Pal.Client.Floors;
namespace Pal.Client.DependencyInjection namespace Pal.Client.DependencyInjection;
{
internal sealed class ChatService : IDisposable internal sealed class ChatService : IDisposable
{ {
private readonly ChatGui _chatGui; private readonly IChatGui _chatGui;
private readonly TerritoryState _territoryState; private readonly TerritoryState _territoryState;
private readonly IPalacePalConfiguration _configuration; private readonly IPalacePalConfiguration _configuration;
private readonly DataManager _dataManager; private readonly IDataManager _dataManager;
private readonly LocalizedChatMessages _localizedChatMessages; private readonly LocalizedChatMessages _localizedChatMessages;
public ChatService(ChatGui chatGui, TerritoryState territoryState, IPalacePalConfiguration configuration, public ChatService(IChatGui chatGui, TerritoryState territoryState, IPalacePalConfiguration configuration,
DataManager dataManager) IDataManager dataManager)
{ {
_chatGui = chatGui; _chatGui = chatGui;
_territoryState = territoryState; _territoryState = territoryState;
@ -34,7 +34,7 @@ namespace Pal.Client.DependencyInjection
public void Dispose() public void Dispose()
=> _chatGui.ChatMessage -= OnChatMessage; => _chatGui.ChatMessage -= OnChatMessage;
private void OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString seMessage, private void OnChatMessage(XivChatType type, int senderId, ref SeString sender, ref SeString seMessage,
ref bool isHandled) ref bool isHandled)
{ {
if (_configuration.FirstUse) if (_configuration.FirstUse)
@ -82,14 +82,21 @@ namespace Pal.Client.DependencyInjection
HoardNotOnCurrentFloor = GetLocalizedString(7273), HoardNotOnCurrentFloor = GetLocalizedString(7273),
HoardCofferOpened = GetLocalizedString(7274), HoardCofferOpened = GetLocalizedString(7274),
FloorChanged = FloorChanged =
new Regex("^" + GetLocalizedString(7270).Replace("\u0002 \u0003\ufffd\u0002\u0003", @"(\d+)") + new Regex("^" + GetLocalizedString(7270, true).Replace("\u0002 \u0003\ufffd\u0002\u0003", @"(\d+)") +
"$"), "$"),
}; };
} }
private string GetLocalizedString(uint id) private string GetLocalizedString(uint id, bool asRawData = false)
{ {
return _dataManager.GetExcelSheet<LogMessage>()?.GetRow(id)?.Text?.ToString() ?? "Unknown"; var text = _dataManager.GetExcelSheet<LogMessage>()?.GetRow(id)?.Text;
if (text == null)
return "Unknown";
if (asRawData)
return Encoding.UTF8.GetString(text.RawData);
else
return text.ToString();
} }
private sealed class LocalizedChatMessages private sealed class LocalizedChatMessages
@ -107,4 +114,3 @@ namespace Pal.Client.DependencyInjection
new(@"This isn't a game message, but will be replaced"); // new Regex(@"^Floor (\d+)$"); new(@"This isn't a game message, but will be replaced"); // new Regex(@"^Floor (\d+)$");
} }
} }
}

View File

@ -1,7 +1,7 @@
using System; using System;
namespace Pal.Client.DependencyInjection namespace Pal.Client.DependencyInjection;
{
internal sealed class DebugState internal sealed class DebugState
{ {
public string? DebugMessage { get; set; } public string? DebugMessage { get; set; }
@ -12,4 +12,3 @@ namespace Pal.Client.DependencyInjection
public void Reset() public void Reset()
=> DebugMessage = null; => DebugMessage = null;
} }
}

View File

@ -4,16 +4,17 @@ using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Hooking; using Dalamud.Hooking;
using Dalamud.Memory; using Dalamud.Memory;
using Dalamud.Plugin.Services;
using Dalamud.Utility.Signatures; using Dalamud.Utility.Signatures;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Pal.Client.Floors; using Pal.Client.Floors;
namespace Pal.Client.DependencyInjection namespace Pal.Client.DependencyInjection;
{
internal sealed unsafe class GameHooks : IDisposable internal sealed unsafe class GameHooks : IDisposable
{ {
private readonly ILogger<GameHooks> _logger; private readonly ILogger<GameHooks> _logger;
private readonly ObjectTable _objectTable; private readonly IObjectTable _objectTable;
private readonly TerritoryState _territoryState; private readonly TerritoryState _territoryState;
private readonly FrameworkService _frameworkService; private readonly FrameworkService _frameworkService;
@ -24,7 +25,7 @@ namespace Pal.Client.DependencyInjection
private Hook<ActorVfxCreateDelegate> ActorVfxCreateHook { get; init; } = null!; private Hook<ActorVfxCreateDelegate> ActorVfxCreateHook { get; init; } = null!;
#pragma warning restore CS0649 #pragma warning restore CS0649
public GameHooks(ILogger<GameHooks> logger, ObjectTable objectTable, TerritoryState territoryState, FrameworkService frameworkService) public GameHooks(ILogger<GameHooks> logger, IObjectTable objectTable, TerritoryState territoryState, FrameworkService frameworkService, IGameInteropProvider gameInteropProvider)
{ {
_logger = logger; _logger = logger;
_objectTable = objectTable; _objectTable = objectTable;
@ -32,7 +33,7 @@ namespace Pal.Client.DependencyInjection
_frameworkService = frameworkService; _frameworkService = frameworkService;
_logger.LogDebug("Initializing game hooks"); _logger.LogDebug("Initializing game hooks");
SignatureHelper.Initialise(this); gameInteropProvider.InitializeFromAttributes(this);
ActorVfxCreateHook.Enable(); ActorVfxCreateHook.Enable();
_logger.LogDebug("Game hooks initialized"); _logger.LogDebug("Game hooks initialized");
@ -80,7 +81,7 @@ namespace Pal.Client.DependencyInjection
_chat.PalPrint($"{vfxPath} on {obj}"); _chat.PalPrint($"{vfxPath} on {obj}");
*/ */
if (obj is BattleChara bc && (bc.NameId == /* potd */ 5042 || bc.NameId == /* hoh */ 7395)) if (obj is IBattleChara bc && (bc.NameId == /* potd */ 5042 || bc.NameId == /* hoh */ 7395))
{ {
if (vfxPath == "vfx/common/eff/dk05th_stdn0t.avfx" || vfxPath == "vfx/common/eff/dk05ht_ipws0t.avfx") if (vfxPath == "vfx/common/eff/dk05th_stdn0t.avfx" || vfxPath == "vfx/common/eff/dk05ht_ipws0t.avfx")
{ {
@ -103,4 +104,3 @@ namespace Pal.Client.DependencyInjection
ActorVfxCreateHook.Dispose(); ActorVfxCreateHook.Dispose();
} }
} }
}

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Numerics; using System.Numerics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Account; using Export;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Pal.Client.Database; using Pal.Client.Database;
@ -12,8 +12,8 @@ using Pal.Client.Floors;
using Pal.Client.Floors.Tasks; using Pal.Client.Floors.Tasks;
using Pal.Common; using Pal.Common;
namespace Pal.Client.DependencyInjection namespace Pal.Client.DependencyInjection;
{
internal sealed class ImportService internal sealed class ImportService
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
@ -163,4 +163,3 @@ namespace Pal.Client.DependencyInjection
} }
} }
} }
}

View File

@ -6,19 +6,17 @@ using Microsoft.Extensions.Logging;
using Pal.Client.Extensions; using Pal.Client.Extensions;
using Pal.Client.Properties; using Pal.Client.Properties;
namespace Pal.Client.DependencyInjection namespace Pal.Client.DependencyInjection;
{
internal sealed class RepoVerification internal sealed class RepoVerification
{ {
public RepoVerification(ILogger<RepoVerification> logger, DalamudPluginInterface pluginInterface, Chat chat) public RepoVerification(ILogger<RepoVerification> logger, IDalamudPluginInterface pluginInterface, Chat chat)
{ {
logger.LogInformation("Install source: {Repo}", pluginInterface.SourceRepository); logger.LogInformation("Install source: {Repo}", pluginInterface.SourceRepository);
if (!pluginInterface.IsDev if (!pluginInterface.IsDev && pluginInterface.SourceRepository.TrimEnd('/') != "https://plugins.carvel.li")
&& !pluginInterface.SourceRepository.StartsWith("https://raw.githubusercontent.com/carvelli/")
&& !pluginInterface.SourceRepository.StartsWith("https://github.com/carvelli/"))
{ {
chat.Error(string.Format(Localization.Error_WrongRepository, chat.Error(string.Format(Localization.Error_WrongRepository,
"https://github.com/carvelli/Dalamud-Plugins")); "https://plugins.carvel.li"));
throw new RepoVerificationFailedException(); throw new RepoVerificationFailedException();
} }
} }
@ -27,4 +25,3 @@ namespace Pal.Client.DependencyInjection
{ {
} }
} }
}

View File

@ -9,8 +9,8 @@ using Pal.Client.Net;
using Pal.Client.Properties; using Pal.Client.Properties;
using Pal.Client.Windows; using Pal.Client.Windows;
namespace Pal.Client.DependencyInjection namespace Pal.Client.DependencyInjection;
{
internal sealed class StatisticsService internal sealed class StatisticsService
{ {
private readonly IPalacePalConfiguration _configuration; private readonly IPalacePalConfiguration _configuration;
@ -72,4 +72,3 @@ namespace Pal.Client.DependencyInjection
} }
} }
} }
}

View File

@ -10,6 +10,7 @@ using Dalamud.Game.Command;
using Dalamud.Game.Gui; using Dalamud.Game.Gui;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -25,37 +26,40 @@ using Pal.Client.Rendering;
using Pal.Client.Scheduled; using Pal.Client.Scheduled;
using Pal.Client.Windows; using Pal.Client.Windows;
namespace Pal.Client namespace Pal.Client;
{
/// <summary> /// <summary>
/// DI-aware Plugin. /// DI-aware Plugin.
/// </summary> /// </summary>
internal sealed class DependencyInjectionContext : IDisposable internal sealed class DependencyInjectionContext : IDisposable
{ {
public const string DatabaseFileName = "palace-pal.data.sqlite3"; public const string DatabaseFileName = "palace-pal.data.sqlite3";
public static DalamudLoggerProvider LoggerProvider { get; } = new(typeof(Plugin).Assembly);
/// <summary> /// <summary>
/// Initialized as temporary logger, will be overriden once context is ready with a logger that supports scopes. /// Initialized as temporary logger, will be overriden once context is ready with a logger that supports scopes.
/// </summary> /// </summary>
private ILogger _logger = LoggerProvider.CreateLogger<DependencyInjectionContext>(); private ILogger _logger;
private readonly string _sqliteConnectionString; private readonly string _sqliteConnectionString;
private readonly ServiceCollection _serviceCollection = new(); private readonly ServiceCollection _serviceCollection = new();
private ServiceProvider? _serviceProvider; private ServiceProvider? _serviceProvider;
public DependencyInjectionContext( public DependencyInjectionContext(
DalamudPluginInterface pluginInterface, IDalamudPluginInterface pluginInterface,
ClientState clientState, IClientState clientState,
GameGui gameGui, IGameGui gameGui,
ChatGui chatGui, IChatGui chatGui,
ObjectTable objectTable, IObjectTable objectTable,
Framework framework, IFramework framework,
Condition condition, ICondition condition,
CommandManager commandManager, ICommandManager commandManager,
DataManager dataManager, IDataManager dataManager,
IGameInteropProvider gameInteropProvider,
IPluginLog pluginLog,
Plugin plugin) Plugin plugin)
{ {
var loggerProvider = new DalamudLoggerProvider(pluginLog);
_logger = loggerProvider.CreateLogger<DependencyInjectionContext>();
_logger.LogInformation("Building dalamud service container for {Assembly}", _logger.LogInformation("Building dalamud service container for {Assembly}",
typeof(DependencyInjectionContext).Assembly.FullName); typeof(DependencyInjectionContext).Assembly.FullName);
@ -70,7 +74,7 @@ namespace Pal.Client
.AddFilter("Microsoft.EntityFrameworkCore.Database", LogLevel.Warning) .AddFilter("Microsoft.EntityFrameworkCore.Database", LogLevel.Warning)
.AddFilter("Grpc", LogLevel.Debug) .AddFilter("Grpc", LogLevel.Debug)
.ClearProviders() .ClearProviders()
.AddDalamudLogger(plugin)); .AddDalamudLogger(pluginLog));
// dalamud // dalamud
_serviceCollection.AddSingleton<IDalamudPlugin>(plugin); _serviceCollection.AddSingleton<IDalamudPlugin>(plugin);
@ -84,6 +88,7 @@ namespace Pal.Client
_serviceCollection.AddSingleton(condition); _serviceCollection.AddSingleton(condition);
_serviceCollection.AddSingleton(commandManager); _serviceCollection.AddSingleton(commandManager);
_serviceCollection.AddSingleton(dataManager); _serviceCollection.AddSingleton(dataManager);
_serviceCollection.AddSingleton(gameInteropProvider);
_serviceCollection.AddSingleton(new WindowSystem(typeof(DependencyInjectionContext).AssemblyQualifiedName)); _serviceCollection.AddSingleton(new WindowSystem(typeof(DependencyInjectionContext).AssemblyQualifiedName));
_sqliteConnectionString = _sqliteConnectionString =
@ -187,4 +192,3 @@ namespace Pal.Client
SqliteConnection.ClearPool(sqliteConnection); SqliteConnection.ClearPool(sqliteConnection);
} }
} }
}

View File

@ -1,7 +1,7 @@
using System; using System;
namespace Pal.Client.Extensions namespace Pal.Client.Extensions;
{
public static class GuidExtensions public static class GuidExtensions
{ {
public static string ToPartialId(this Guid g, int length = 13) public static string ToPartialId(this Guid g, int length = 13)
@ -10,4 +10,3 @@ namespace Pal.Client.Extensions
public static string ToPartialId(this string s, int length = 13) public static string ToPartialId(this string s, int length = 13)
=> s.PadRight(length + 1).Substring(0, length); => s.PadRight(length + 1).Substring(0, length);
} }
}

View File

@ -3,8 +3,8 @@ using System.Runtime.InteropServices;
using System.Text; using System.Text;
using ImGuiNET; using ImGuiNET;
namespace Pal.Client.Extensions namespace Pal.Client.Extensions;
{
internal static class PalImGui internal static class PalImGui
{ {
/// <summary> /// <summary>
@ -33,4 +33,3 @@ namespace Pal.Client.Extensions
choice = value; choice = value;
} }
} }
}

View File

@ -1,7 +1,7 @@
using System; using System;
namespace Pal.Client.Floors namespace Pal.Client.Floors;
{
/// <summary> /// <summary>
/// This is a currently-visible marker. /// This is a currently-visible marker.
/// </summary> /// </summary>
@ -26,4 +26,3 @@ namespace Pal.Client.Floors
return $"EphemeralLocation(Position={Position}, Type={Type})"; return $"EphemeralLocation(Position={Position}, Type={Type})";
} }
} }
}

View File

@ -10,8 +10,8 @@ using Pal.Client.Floors.Tasks;
using Pal.Client.Net; using Pal.Client.Net;
using Pal.Common; using Pal.Common;
namespace Pal.Client.Floors namespace Pal.Client.Floors;
{
internal sealed class FloorService internal sealed class FloorService
{ {
private readonly IPalacePalConfiguration _configuration; private readonly IPalacePalConfiguration _configuration;
@ -160,4 +160,3 @@ namespace Pal.Client.Floors
} }
} }
} }
}

View File

@ -4,10 +4,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Game;
using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin.Services;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Pal.Client.Configuration; using Pal.Client.Configuration;
@ -18,21 +16,21 @@ using Pal.Client.Rendering;
using Pal.Client.Scheduled; using Pal.Client.Scheduled;
using Pal.Common; using Pal.Common;
namespace Pal.Client.Floors namespace Pal.Client.Floors;
{
internal sealed class FrameworkService : IDisposable internal sealed class FrameworkService : IDisposable
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly ILogger<FrameworkService> _logger; private readonly ILogger<FrameworkService> _logger;
private readonly Framework _framework; private readonly IFramework _framework;
private readonly ConfigurationManager _configurationManager; private readonly ConfigurationManager _configurationManager;
private readonly IPalacePalConfiguration _configuration; private readonly IPalacePalConfiguration _configuration;
private readonly ClientState _clientState; private readonly IClientState _clientState;
private readonly TerritoryState _territoryState; private readonly TerritoryState _territoryState;
private readonly FloorService _floorService; private readonly FloorService _floorService;
private readonly DebugState _debugState; private readonly DebugState _debugState;
private readonly RenderAdapter _renderAdapter; private readonly RenderAdapter _renderAdapter;
private readonly ObjectTable _objectTable; private readonly IObjectTable _objectTable;
private readonly RemoteApi _remoteApi; private readonly RemoteApi _remoteApi;
internal Queue<IQueueOnFrameworkThread> EarlyEventQueue { get; } = new(); internal Queue<IQueueOnFrameworkThread> EarlyEventQueue { get; } = new();
@ -42,15 +40,15 @@ namespace Pal.Client.Floors
public FrameworkService( public FrameworkService(
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
ILogger<FrameworkService> logger, ILogger<FrameworkService> logger,
Framework framework, IFramework framework,
ConfigurationManager configurationManager, ConfigurationManager configurationManager,
IPalacePalConfiguration configuration, IPalacePalConfiguration configuration,
ClientState clientState, IClientState clientState,
TerritoryState territoryState, TerritoryState territoryState,
FloorService floorService, FloorService floorService,
DebugState debugState, DebugState debugState,
RenderAdapter renderAdapter, RenderAdapter renderAdapter,
ObjectTable objectTable, IObjectTable objectTable,
RemoteApi remoteApi) RemoteApi remoteApi)
{ {
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
@ -79,7 +77,7 @@ namespace Pal.Client.Floors
private void OnSaved(object? sender, IPalacePalConfiguration? config) private void OnSaved(object? sender, IPalacePalConfiguration? config)
=> EarlyEventQueue.Enqueue(new QueuedConfigUpdate()); => EarlyEventQueue.Enqueue(new QueuedConfigUpdate());
private void OnUpdate(Framework framework) private void OnUpdate(IFramework framework)
{ {
if (_configuration.FirstUse) if (_configuration.FirstUse)
return; return;
@ -177,12 +175,20 @@ namespace Pal.Client.Floors
{ {
foreach (var location in memoryTerritory.Locations) foreach (var location in memoryTerritory.Locations)
{ {
uint desiredColor = DetermineColor(location, visibleLocations); bool isEnabled = DetermineVisibility(location, visibleLocations);
if (location.RenderElement == null || !location.RenderElement.IsValid) if (location.RenderElement == null)
{
if (isEnabled)
return true;
else
continue;
}
if (!location.RenderElement.IsValid)
return true; return true;
if (location.RenderElement.Color != desiredColor) if (location.RenderElement.Enabled != isEnabled)
location.RenderElement.Color = desiredColor; location.RenderElement.Enabled = isEnabled;
} }
} }
catch (Exception e) catch (Exception e)
@ -227,12 +233,12 @@ namespace Pal.Client.Floors
{ {
if (location.Type == MemoryLocation.EType.Trap) if (location.Type == MemoryLocation.EType.Trap)
{ {
CreateRenderElement(location, elements, DetermineColor(location, visibleMarkers), CreateRenderElement(location, elements, DetermineVisibility(location, visibleMarkers),
_configuration.DeepDungeons.Traps); _configuration.DeepDungeons.Traps);
} }
else if (location.Type == MemoryLocation.EType.Hoard) else if (location.Type == MemoryLocation.EType.Hoard)
{ {
CreateRenderElement(location, elements, DetermineColor(location, visibleMarkers), CreateRenderElement(location, elements, DetermineVisibility(location, visibleMarkers),
_configuration.DeepDungeons.HoardCoffers); _configuration.DeepDungeons.HoardCoffers);
} }
} }
@ -253,14 +259,12 @@ namespace Pal.Client.Floors
if (location.Type == MemoryLocation.EType.SilverCoffer && if (location.Type == MemoryLocation.EType.SilverCoffer &&
_configuration.DeepDungeons.SilverCoffers.Show) _configuration.DeepDungeons.SilverCoffers.Show)
{ {
CreateRenderElement(location, elements, DetermineColor(location), CreateRenderElement(location, elements, true, _configuration.DeepDungeons.SilverCoffers);
_configuration.DeepDungeons.SilverCoffers);
} }
else if (location.Type == MemoryLocation.EType.GoldCoffer && else if (location.Type == MemoryLocation.EType.GoldCoffer &&
_configuration.DeepDungeons.GoldCoffers.Show) _configuration.DeepDungeons.GoldCoffers.Show)
{ {
CreateRenderElement(location, elements, DetermineColor(location), CreateRenderElement(location, elements, true, _configuration.DeepDungeons.GoldCoffers);
_configuration.DeepDungeons.GoldCoffers);
} }
} }
@ -270,7 +274,7 @@ namespace Pal.Client.Floors
_renderAdapter.SetLayer(ELayer.RegularCoffers, elements); _renderAdapter.SetLayer(ELayer.RegularCoffers, elements);
} }
private uint DetermineColor(PersistentLocation location, IReadOnlyList<PersistentLocation> visibleLocations) private bool DetermineVisibility(PersistentLocation location, IReadOnlyList<PersistentLocation> visibleLocations)
{ {
switch (location.Type) switch (location.Type)
{ {
@ -278,34 +282,28 @@ namespace Pal.Client.Floors
when _territoryState.PomanderOfSight == PomanderState.Inactive || when _territoryState.PomanderOfSight == PomanderState.Inactive ||
!_configuration.DeepDungeons.Traps.OnlyVisibleAfterPomander || !_configuration.DeepDungeons.Traps.OnlyVisibleAfterPomander ||
visibleLocations.Any(x => x == location): visibleLocations.Any(x => x == location):
return _configuration.DeepDungeons.Traps.Color; return true;
case MemoryLocation.EType.Hoard case MemoryLocation.EType.Hoard
when _territoryState.PomanderOfIntuition == PomanderState.Inactive || when _territoryState.PomanderOfIntuition == PomanderState.Inactive ||
!_configuration.DeepDungeons.HoardCoffers.OnlyVisibleAfterPomander || !_configuration.DeepDungeons.HoardCoffers.OnlyVisibleAfterPomander ||
visibleLocations.Any(x => x == location): visibleLocations.Any(x => x == location):
return _configuration.DeepDungeons.HoardCoffers.Color; return true;
default: default:
return RenderData.ColorInvisible; return false;
} }
} }
private uint DetermineColor(EphemeralLocation location) private void CreateRenderElement(MemoryLocation location, List<IRenderElement> elements, bool enabled,
{
return location.Type switch
{
MemoryLocation.EType.SilverCoffer => _configuration.DeepDungeons.SilverCoffers.Color,
MemoryLocation.EType.GoldCoffer => _configuration.DeepDungeons.GoldCoffers.Color,
_ => RenderData.ColorInvisible
};
}
private void CreateRenderElement(MemoryLocation location, List<IRenderElement> elements, uint color,
MarkerConfiguration config) MarkerConfiguration config)
{ {
if (!config.Show) if (!config.Show)
{
location.RenderElement = null;
return; return;
}
var element = _renderAdapter.CreateElement(location.Type, location.Position, color, config.Fill); var element =
_renderAdapter.CreateElement(location.Type, location.Position, enabled, config.Color, config.Fill);
location.RenderElement = element; location.RenderElement = element;
elements.Add(element); elements.Add(element);
} }
@ -385,7 +383,7 @@ namespace Pal.Client.Floors
List<EphemeralLocation> ephemeralLocations = new(); List<EphemeralLocation> ephemeralLocations = new();
for (int i = 246; i < _objectTable.Length; i++) for (int i = 246; i < _objectTable.Length; i++)
{ {
GameObject? obj = _objectTable[i]; IGameObject? obj = _objectTable[i];
if (obj == null) if (obj == null)
continue; continue;
@ -449,7 +447,6 @@ namespace Pal.Client.Floors
Position = obj.Position, Position = obj.Position,
Seen = true, Seen = true,
Source = ClientLocation.ESource.ExplodedLocally, Source = ClientLocation.ESource.ExplodedLocally,
}); });
} }
} }
@ -465,4 +462,3 @@ namespace Pal.Client.Floors
handler.RunIfCompatible(queued, ref recreateLayout); handler.RunIfCompatible(queued, ref recreateLayout);
} }
} }
}

View File

@ -5,8 +5,8 @@ using Pal.Client.Rendering;
using Pal.Common; using Pal.Common;
using Palace; using Palace;
namespace Pal.Client.Floors namespace Pal.Client.Floors;
{
/// <summary> /// <summary>
/// Base class for <see cref="MemoryLocation"/> and <see cref="EphemeralLocation"/>. /// Base class for <see cref="MemoryLocation"/> and <see cref="EphemeralLocation"/>.
/// </summary> /// </summary>
@ -64,4 +64,3 @@ namespace Pal.Client.Floors
}; };
} }
} }
}

View File

@ -5,8 +5,8 @@ using Pal.Client.Configuration;
using Pal.Client.Scheduled; using Pal.Client.Scheduled;
using Pal.Common; using Pal.Common;
namespace Pal.Client.Floors namespace Pal.Client.Floors;
{
/// <summary> /// <summary>
/// A single set of floors loaded entirely in memory, can be e.g. POTD 51-60. /// A single set of floors loaded entirely in memory, can be e.g. POTD 51-60.
/// </summary> /// </summary>
@ -60,4 +60,3 @@ namespace Pal.Client.Floors
Importing, Importing,
} }
} }
}

View File

@ -1,16 +1,14 @@
using System; using System;
using System.Numerics; using System.Numerics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.Gui;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using ImGuiNET; using ImGuiNET;
namespace Pal.Client.Floors namespace Pal.Client.Floors;
{
/// <summary> /// <summary>
/// This isn't very useful for running deep dungeons normally, but it is for plugin dev. /// This isn't very useful for running deep dungeons normally, but it is for plugin dev.
/// ///
@ -20,12 +18,13 @@ namespace Pal.Client.Floors
{ {
public const string FeatureName = nameof(ObjectTableDebug); public const string FeatureName = nameof(ObjectTableDebug);
private readonly DalamudPluginInterface _pluginInterface; private readonly IDalamudPluginInterface _pluginInterface;
private readonly ObjectTable _objectTable; private readonly IObjectTable _objectTable;
private readonly GameGui _gameGui; private readonly IGameGui _gameGui;
private readonly ClientState _clientState; private readonly IClientState _clientState;
public ObjectTableDebug(DalamudPluginInterface pluginInterface, ObjectTable objectTable, GameGui gameGui, ClientState clientState) public ObjectTableDebug(IDalamudPluginInterface pluginInterface, IObjectTable objectTable, IGameGui gameGui,
IClientState clientState)
{ {
_pluginInterface = pluginInterface; _pluginInterface = pluginInterface;
_objectTable = objectTable; _objectTable = objectTable;
@ -38,9 +37,9 @@ namespace Pal.Client.Floors
private void Draw() private void Draw()
{ {
int index = 0; int index = 0;
foreach (GameObject obj in _objectTable) foreach (IGameObject obj in _objectTable)
{ {
if (obj is EventObj eventObj && string.IsNullOrEmpty(eventObj.Name.ToString())) if (obj is IEventObj eventObj && string.IsNullOrEmpty(eventObj.Name.ToString()))
{ {
++index; ++index;
int model = Marshal.ReadInt32(obj.Address + 128); int model = Marshal.ReadInt32(obj.Address + 128);
@ -52,7 +51,7 @@ namespace Pal.Client.Floors
// produce a new viewport, and skip rendering it if so // produce a new viewport, and skip rendering it if so
float distance = DistanceToPlayer(obj.Position); float distance = DistanceToPlayer(obj.Position);
var objectText = var objectText =
$"{obj.Address.ToInt64():X}:{obj.ObjectId:X}[{index}]\nkind: {obj.ObjectKind} sub: {obj.SubKind}\nmodel: {model}\nname: {obj.Name}\ndata id: {obj.DataId}"; $"{obj.Address.ToInt64():X}:{obj.EntityId:X}[{index}]\nkind: {obj.ObjectKind} sub: {obj.SubKind}\nmodel: {model}\nname: {obj.Name}\ndata id: {obj.DataId}";
var screenPos = ImGui.GetMainViewport().Pos; var screenPos = ImGui.GetMainViewport().Pos;
var screenSize = ImGui.GetMainViewport().Size; var screenSize = ImGui.GetMainViewport().Size;
@ -98,4 +97,3 @@ namespace Pal.Client.Floors
_pluginInterface.UiBuilder.Draw -= Draw; _pluginInterface.UiBuilder.Draw -= Draw;
} }
} }
}

View File

@ -2,8 +2,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using Pal.Client.Database; using Pal.Client.Database;
namespace Pal.Client.Floors namespace Pal.Client.Floors;
{
/// <summary> /// <summary>
/// A <see cref="ClientLocation"/> loaded in memory, with certain extra attributes as needed. /// A <see cref="ClientLocation"/> loaded in memory, with certain extra attributes as needed.
/// </summary> /// </summary>
@ -52,4 +52,3 @@ namespace Pal.Client.Floors
return $"PersistentLocation(Position={Position}, Type={Type})"; return $"PersistentLocation(Position={Position}, Type={Type})";
} }
} }
}

View File

@ -4,8 +4,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Pal.Client.Database; using Pal.Client.Database;
namespace Pal.Client.Floors.Tasks namespace Pal.Client.Floors.Tasks;
{
internal abstract class DbTask<T> internal abstract class DbTask<T>
where T : DbTask<T> where T : DbTask<T>
{ {
@ -24,18 +24,23 @@ namespace Pal.Client.Floors.Tasks
{ {
using var scope = _serviceScopeFactory.CreateScope(); using var scope = _serviceScopeFactory.CreateScope();
ILogger<T> logger = scope.ServiceProvider.GetRequiredService<ILogger<T>>(); ILogger<T> logger = scope.ServiceProvider.GetRequiredService<ILogger<T>>();
try
{
using var dbContext = scope.ServiceProvider.GetRequiredService<PalClientContext>(); using var dbContext = scope.ServiceProvider.GetRequiredService<PalClientContext>();
Run(dbContext, logger); Run(dbContext, logger);
} }
catch (Exception e) catch (Exception e)
{ {
DependencyInjectionContext.LoggerProvider.CreateLogger<DbTask<T>>() logger.LogError(e, "Failed to run DbTask");
.LogError(e, "Failed to run DbTask"); }
}
catch (Exception)
{
// nothing we can do here but catch it, if we don't we crash the game
} }
}); });
} }
protected abstract void Run(PalClientContext dbContext, ILogger<T> logger); protected abstract void Run(PalClientContext dbContext, ILogger<T> logger);
} }
}

View File

@ -7,8 +7,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Pal.Client.Database; using Pal.Client.Database;
namespace Pal.Client.Floors.Tasks namespace Pal.Client.Floors.Tasks;
{
internal sealed class LoadTerritory : DbTask<LoadTerritory> internal sealed class LoadTerritory : DbTask<LoadTerritory>
{ {
private readonly Cleanup _cleanup; private readonly Cleanup _cleanup;
@ -76,4 +76,3 @@ namespace Pal.Client.Floors.Tasks
}; };
} }
} }
}

View File

@ -5,8 +5,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Pal.Client.Database; using Pal.Client.Database;
namespace Pal.Client.Floors.Tasks namespace Pal.Client.Floors.Tasks;
{
internal sealed class MarkLocalSeen : DbTask<MarkLocalSeen> internal sealed class MarkLocalSeen : DbTask<MarkLocalSeen>
{ {
private readonly MemoryTerritory _territory; private readonly MemoryTerritory _territory;
@ -24,7 +24,8 @@ namespace Pal.Client.Floors.Tasks
{ {
lock (_territory.LockObj) lock (_territory.LockObj)
{ {
logger.LogInformation("Marking {Count} locations as seen locally in territory {Territory}", _locations.Count, logger.LogInformation("Marking {Count} locations as seen locally in territory {Territory}",
_locations.Count,
_territory.TerritoryType); _territory.TerritoryType);
List<int> localIds = _locations.Select(l => l.LocalId).Where(x => x != null).Cast<int>().ToList(); List<int> localIds = _locations.Select(l => l.LocalId).Where(x => x != null).Cast<int>().ToList();
dbContext.Locations dbContext.Locations
@ -34,4 +35,3 @@ namespace Pal.Client.Floors.Tasks
} }
} }
} }
}

View File

@ -5,8 +5,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Pal.Client.Database; using Pal.Client.Database;
namespace Pal.Client.Floors.Tasks namespace Pal.Client.Floors.Tasks;
{
internal sealed class MarkRemoteSeen : DbTask<MarkRemoteSeen> internal sealed class MarkRemoteSeen : DbTask<MarkRemoteSeen>
{ {
private readonly MemoryTerritory _territory; private readonly MemoryTerritory _territory;
@ -48,4 +48,3 @@ namespace Pal.Client.Floors.Tasks
} }
} }
} }
}

View File

@ -6,8 +6,8 @@ using Microsoft.Extensions.Logging;
using Pal.Client.Database; using Pal.Client.Database;
using Pal.Common; using Pal.Common;
namespace Pal.Client.Floors.Tasks namespace Pal.Client.Floors.Tasks;
{
internal sealed class SaveNewLocations : DbTask<SaveNewLocations> internal sealed class SaveNewLocations : DbTask<SaveNewLocations>
{ {
private readonly MemoryTerritory _territory; private readonly MemoryTerritory _territory;
@ -74,4 +74,3 @@ namespace Pal.Client.Floors.Tasks
}; };
} }
} }
}

View File

@ -1,15 +1,15 @@
using Dalamud.Game.ClientState; using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Conditions; using Dalamud.Plugin.Services;
using Pal.Common; using Pal.Common;
namespace Pal.Client.Floors namespace Pal.Client.Floors;
{
public sealed class TerritoryState public sealed class TerritoryState
{ {
private readonly ClientState _clientState; private readonly IClientState _clientState;
private readonly Condition _condition; private readonly ICondition _condition;
public TerritoryState(ClientState clientState, Condition condition) public TerritoryState(IClientState clientState, ICondition condition)
{ {
_clientState = clientState; _clientState = clientState;
_condition = condition; _condition = condition;
@ -23,7 +23,6 @@ namespace Pal.Client.Floors
_clientState.IsLoggedIn _clientState.IsLoggedIn
&& _condition[ConditionFlag.InDeepDungeon] && _condition[ConditionFlag.InDeepDungeon]
&& typeof(ETerritoryType).IsEnumDefined(_clientState.TerritoryType); && typeof(ETerritoryType).IsEnumDefined(_clientState.TerritoryType);
} }
public enum PomanderState public enum PomanderState
@ -33,4 +32,3 @@ namespace Pal.Client.Floors
FoundOnCurrentFloor, FoundOnCurrentFloor,
PomanderOfSafetyUsed, PomanderOfSafetyUsed,
} }
}

View File

@ -4,10 +4,9 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Pal.Client namespace Pal.Client;
{
internal interface ILanguageChanged internal interface ILanguageChanged
{ {
void LanguageChanged(); void LanguageChanged();
} }
}

View File

@ -1,13 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Text.Json.Serialization;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Text.Json.Serialization;
namespace Pal.Client.Net;
namespace Pal.Client.Net
{
internal sealed class JwtClaims internal sealed class JwtClaims
{ {
[JsonPropertyName("nameid")] [JsonPropertyName("nameid")]
@ -42,7 +40,8 @@ namespace Pal.Client.Net
payload += "="; payload += "=";
string content = Encoding.UTF8.GetString(Convert.FromBase64String(payload)); string content = Encoding.UTF8.GetString(Convert.FromBase64String(payload));
return JsonSerializer.Deserialize<JwtClaims>(content) ?? throw new InvalidOperationException("token deserialization returned null"); return JsonSerializer.Deserialize<JwtClaims>(content) ??
throw new InvalidOperationException("token deserialization returned null");
} }
} }
@ -75,21 +74,6 @@ namespace Pal.Client.Net
throw new JsonException("bad token type"); throw new JsonException("bad token type");
} }
public override void Write(Utf8JsonWriter writer, List<string> value, JsonSerializerOptions options) => throw new NotImplementedException(); public override void Write(Utf8JsonWriter writer, List<string> value, JsonSerializerOptions options) =>
} throw new NotImplementedException();
public sealed class JwtDateConverter : JsonConverter<DateTimeOffset>
{
static readonly DateTimeOffset Zero = new(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.Number)
throw new JsonException("bad token type");
return Zero.AddSeconds(reader.GetInt64());
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) => throw new NotImplementedException();
}
} }

View File

@ -0,0 +1,21 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Pal.Client.Net;
public sealed class JwtDateConverter : JsonConverter<DateTimeOffset>
{
static readonly DateTimeOffset Zero = new(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.Number)
throw new JsonException("bad token type");
return Zero.AddSeconds(reader.GetInt64());
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) =>
throw new NotImplementedException();
}

View File

@ -1,21 +1,23 @@
using Account; using System;
using Grpc.Core;
using Grpc.Net.Client;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Account;
using Grpc.Core;
using Grpc.Net.Client;
using Microsoft.Extensions.Logging;
using Pal.Client.Configuration;
using Pal.Client.Extensions; using Pal.Client.Extensions;
using Pal.Client.Properties; using Pal.Client.Properties;
using Pal.Client.Configuration; using Version = System.Version;
namespace Pal.Client.Net;
namespace Pal.Client.Net
{
internal partial class RemoteApi internal partial class RemoteApi
{ {
private static readonly Version PluginVersion = typeof(Plugin).Assembly.GetName().Version!;
private readonly SemaphoreSlim _connectLock = new(1, 1); private readonly SemaphoreSlim _connectLock = new(1, 1);
private async Task<(bool Success, string Error)> TryConnect(CancellationToken cancellationToken, private async Task<(bool Success, string Error)> TryConnect(CancellationToken cancellationToken,
@ -73,7 +75,14 @@ namespace Pal.Client.Net
if (configuredAccount == null) if (configuredAccount == null)
{ {
_logger.LogInformation("No account information saved for {Url}, creating new account", RemoteUrl); _logger.LogInformation("No account information saved for {Url}, creating new account", RemoteUrl);
var createAccountReply = await accountClient.CreateAccountAsync(new CreateAccountRequest(), var createAccountReply = await accountClient.CreateAccountAsync(new CreateAccountRequest
{
Version = new()
{
Major = PluginVersion.Major,
Minor = PluginVersion.Minor,
},
},
headers: UnauthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10), headers: UnauthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10),
cancellationToken: cancellationToken); cancellationToken: cancellationToken);
if (createAccountReply.Success) if (createAccountReply.Success)
@ -115,7 +124,15 @@ namespace Pal.Client.Net
_logger.LogInformation("Logging in with account id {AccountId}", _logger.LogInformation("Logging in with account id {AccountId}",
configuredAccount.AccountId.ToPartialId()); configuredAccount.AccountId.ToPartialId());
LoginReply loginReply = await accountClient.LoginAsync( LoginReply loginReply = await accountClient.LoginAsync(
new LoginRequest { AccountId = configuredAccount.AccountId.ToString() }, new LoginRequest
{
AccountId = configuredAccount.AccountId.ToString(),
Version = new()
{
Major = PluginVersion.Major,
Minor = PluginVersion.Minor,
},
},
headers: UnauthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10), headers: UnauthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10),
cancellationToken: cancellationToken); cancellationToken: cancellationToken);
@ -229,4 +246,3 @@ namespace Pal.Client.Net
public bool IsValid => IsLoggedIn && !IsExpired; public bool IsValid => IsLoggedIn && !IsExpired;
} }
} }
}

View File

@ -1,10 +1,10 @@
using Account; using System;
using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Export;
namespace Pal.Client.Net;
namespace Pal.Client.Net
{
internal partial class RemoteApi internal partial class RemoteApi
{ {
public async Task<(bool, ExportRoot)> DoExport(CancellationToken cancellationToken = default) public async Task<(bool, ExportRoot)> DoExport(CancellationToken cancellationToken = default)
@ -16,8 +16,8 @@ namespace Pal.Client.Net
var exportReply = await exportClient.ExportAsync(new ExportRequest var exportReply = await exportClient.ExportAsync(new ExportRequest
{ {
ServerUrl = RemoteUrl, ServerUrl = RemoteUrl,
}, headers: AuthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(120), cancellationToken: cancellationToken); }, headers: AuthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(120),
cancellationToken: cancellationToken);
return (exportReply.Success, exportReply.Data); return (exportReply.Success, exportReply.Data);
} }
} }
}

View File

@ -1,5 +1,4 @@
using Palace; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
@ -7,22 +6,27 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Pal.Client.Database; using Pal.Client.Database;
using Pal.Client.Floors; using Pal.Client.Floors;
using Palace;
namespace Pal.Client.Net;
namespace Pal.Client.Net
{
internal partial class RemoteApi internal partial class RemoteApi
{ {
public async Task<(bool, List<PersistentLocation>)> DownloadRemoteMarkers(ushort territoryId, CancellationToken cancellationToken = default) public async Task<(bool, List<PersistentLocation>)> DownloadRemoteMarkers(ushort territoryId,
CancellationToken cancellationToken = default)
{ {
if (!await Connect(cancellationToken)) if (!await Connect(cancellationToken))
return (false, new()); return (false, new());
var palaceClient = new PalaceService.PalaceServiceClient(_channel); var palaceClient = new PalaceService.PalaceServiceClient(_channel);
var downloadReply = await palaceClient.DownloadFloorsAsync(new DownloadFloorsRequest { TerritoryType = territoryId }, headers: AuthorizedHeaders(), cancellationToken: cancellationToken); var downloadReply = await palaceClient.DownloadFloorsAsync(
new DownloadFloorsRequest { TerritoryType = territoryId }, headers: AuthorizedHeaders(),
cancellationToken: cancellationToken);
return (downloadReply.Success, downloadReply.Objects.Select(CreateLocationFromNetworkObject).ToList()); return (downloadReply.Success, downloadReply.Objects.Select(CreateLocationFromNetworkObject).ToList());
} }
public async Task<(bool, List<PersistentLocation>)> UploadLocations(ushort territoryType, IReadOnlyList<PersistentLocation> locations, CancellationToken cancellationToken = default) public async Task<(bool, List<PersistentLocation>)> UploadLocations(ushort territoryType,
IReadOnlyList<PersistentLocation> locations, CancellationToken cancellationToken = default)
{ {
if (locations.Count == 0) if (locations.Count == 0)
return (true, new()); return (true, new());
@ -42,11 +46,13 @@ namespace Pal.Client.Net
Y = m.Position.Y, Y = m.Position.Y,
Z = m.Position.Z Z = m.Position.Z
})); }));
var uploadReply = await palaceClient.UploadFloorsAsync(uploadRequest, headers: AuthorizedHeaders(), cancellationToken: cancellationToken); var uploadReply = await palaceClient.UploadFloorsAsync(uploadRequest, headers: AuthorizedHeaders(),
cancellationToken: cancellationToken);
return (uploadReply.Success, uploadReply.Objects.Select(CreateLocationFromNetworkObject).ToList()); return (uploadReply.Success, uploadReply.Objects.Select(CreateLocationFromNetworkObject).ToList());
} }
public async Task<bool> MarkAsSeen(ushort territoryType, IReadOnlyList<PersistentLocation> locations, CancellationToken cancellationToken = default) public async Task<bool> MarkAsSeen(ushort territoryType, IReadOnlyList<PersistentLocation> locations,
CancellationToken cancellationToken = default)
{ {
if (locations.Count == 0) if (locations.Count == 0)
return true; return true;
@ -59,7 +65,8 @@ namespace Pal.Client.Net
foreach (var marker in locations) foreach (var marker in locations)
seenRequest.NetworkIds.Add(marker.NetworkId.ToString()); seenRequest.NetworkIds.Add(marker.NetworkId.ToString());
var seenReply = await palaceClient.MarkObjectsSeenAsync(seenRequest, headers: AuthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken); var seenReply = await palaceClient.MarkObjectsSeenAsync(seenRequest, headers: AuthorizedHeaders(),
deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken);
return seenReply.Success; return seenReply.Success;
} }
@ -80,8 +87,9 @@ namespace Pal.Client.Net
return new(false, new List<FloorStatistics>()); return new(false, new List<FloorStatistics>());
var palaceClient = new PalaceService.PalaceServiceClient(_channel); var palaceClient = new PalaceService.PalaceServiceClient(_channel);
var statisticsReply = await palaceClient.FetchStatisticsAsync(new StatisticsRequest(), headers: AuthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(30), cancellationToken: cancellationToken); var statisticsReply = await palaceClient.FetchStatisticsAsync(new StatisticsRequest(),
headers: AuthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(30),
cancellationToken: cancellationToken);
return (statisticsReply.Success, statisticsReply.FloorStatistics.ToList()); return (statisticsReply.Success, statisticsReply.FloorStatistics.ToList());
} }
} }
}

View File

@ -1,12 +1,12 @@
using System; using System;
using Dalamud.Logging;
using Grpc.Core;
using System.Net.Security; using System.Net.Security;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using Dalamud.Logging;
using Grpc.Core;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace Pal.Client.Net namespace Pal.Client.Net;
{
internal partial class RemoteApi internal partial class RemoteApi
{ {
private Metadata UnauthorizedHeaders() => new() private Metadata UnauthorizedHeaders() => new()
@ -55,4 +55,3 @@ namespace Pal.Client.Net
#endif #endif
} }
} }
}

View File

@ -1,19 +1,19 @@
using Dalamud.Logging; using System;
using Dalamud.Game.Gui;
using Dalamud.Logging;
using Grpc.Net.Client; using Grpc.Net.Client;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System;
using Dalamud.Game.Gui;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Client.DependencyInjection; using Pal.Client.DependencyInjection;
namespace Pal.Client.Net namespace Pal.Client.Net;
{
internal sealed partial class RemoteApi : IDisposable internal sealed partial class RemoteApi : IDisposable
{ {
#if DEBUG #if DEBUG
public const string RemoteUrl = "http://localhost:5415"; public const string RemoteUrl = "http://localhost:5415";
#else #else
public const string RemoteUrl = "https://pal.liza.sh"; public const string RemoteUrl = "https://connect.palacepal.com";
#endif #endif
private readonly string _userAgent = private readonly string _userAgent =
$"{typeof(RemoteApi).Assembly.GetName().Name?.Replace(" ", "")}/{typeof(RemoteApi).Assembly.GetName().Version?.ToString(2)}"; $"{typeof(RemoteApi).Assembly.GetName().Name?.Replace(" ", "")}/{typeof(RemoteApi).Assembly.GetName().Version?.ToString(2)}";
@ -49,4 +49,3 @@ namespace Pal.Client.Net
_channel = null; _channel = null;
} }
} }
}

View File

@ -1,28 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Dalamud.NET.Sdk/9.0.2">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework> <Version>6.0</Version>
<LangVersion>11.0</LangVersion>
<Nullable>enable</Nullable>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<PlatformTarget>x64</PlatformTarget>
<AssemblyName>Palace Pal</AssemblyName> <AssemblyName>Palace Pal</AssemblyName>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <PlatformTarget>x64</PlatformTarget>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>portable</DebugType>
<PathMap Condition="$(SolutionDir) != ''">$(SolutionDir)=X:\</PathMap>
<GitVersion>false</GitVersion>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
</PropertyGroup> </PropertyGroup>
<Import Project="..\vendor\LLib\LLib.targets"/>
<Import Project="..\vendor\LLib\RenameZip.targets"/>
<PropertyGroup Condition="'$(Configuration)' == 'Release'"> <PropertyGroup Condition="'$(Configuration)' == 'Release'">
<OutputPath>dist</OutputPath> <OutputPath>dist</OutputPath>
</PropertyGroup> </PropertyGroup>
@ -36,29 +23,26 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.10" /> <PackageReference Include="Dalamud.Extensions.MicrosoftLogging" Version="4.0.1"/>
<PackageReference Include="Dalamud.Extensions.MicrosoftLogging" Version="1.0.0" /> <PackageReference Include="Google.Protobuf" Version="3.27.2" />
<PackageReference Include="Google.Protobuf" Version="3.22.1" /> <PackageReference Include="Grpc.Net.Client" Version="2.63.0"/>
<PackageReference Include="Grpc.Net.Client" Version="2.51.0" /> <PackageReference Include="Grpc.Tools" Version="2.64.0">
<PackageReference Include="GitInfo" Version="2.3.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Grpc.Tools" Version="2.52.0">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.3"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.6" Condition="'$(Configuration)' == 'EF'">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0"/>
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="7.0.1" /> <PackageReference Include="System.Security.Cryptography.ProtectedData" Version="8.0.0"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Pal.Common\Pal.Common.csproj"/> <ProjectReference Include="..\Pal.Common\Pal.Common.csproj"/>
<ProjectReference Include="..\vendor\ECommons\ECommons\ECommons.csproj"/> <ProjectReference Include="..\vendor\ECommons\ECommons\ECommons.csproj"/>
<ProjectReference Include="..\vendor\LLib\LLib.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -67,42 +51,6 @@
<Protobuf Include="..\Pal.Common\Protos\export.proto" Link="Protos\export.proto" GrpcServices="Client" Access="Internal"/> <Protobuf Include="..\Pal.Common\Protos\export.proto" Link="Protos\export.proto" GrpcServices="Client" Access="Internal"/>
</ItemGroup> </ItemGroup>
<ItemGroup>
<!--You may need to adjust these paths yourself. These point to a Dalamud assembly in AppData.-->
<Reference Include="Dalamud">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Dalamud.dll</HintPath>
<Private Condition="'$(Configuration)' != 'EF'">false</Private>
</Reference>
<Reference Include="ImGui.NET">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\ImGui.NET.dll</HintPath>
<Private Condition="'$(Configuration)' != 'EF'">false</Private>
</Reference>
<Reference Include="ImGuiScene">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\ImGuiScene.dll</HintPath>
<Private Condition="'$(Configuration)' != 'EF'">false</Private>
</Reference>
<Reference Include="Lumina">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.dll</HintPath>
<Private Condition="'$(Configuration)' != 'EF'">false</Private>
</Reference>
<Reference Include="Lumina.Excel">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath>
<Private Condition="'$(Configuration)' != 'EF'">false</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Newtonsoft.Json.dll</HintPath>
<Private Condition="'$(Configuration)' != 'EF'">false</Private>
</Reference>
<Reference Include="FFXIVClientStructs">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\FFXIVClientStructs.dll</HintPath>
<Private Condition="'$(Configuration)' != 'EF'">false</Private>
</Reference>
<Reference Include="Serilog">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Serilog.dll</HintPath>
<Private Condition="'$(Configuration)' != 'EF'">false</Private>
</Reference>
</ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Update="Properties\Localization.resx"> <EmbeddedResource Update="Properties\Localization.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
@ -115,17 +63,6 @@
</Compile> </Compile>
</ItemGroup> </ItemGroup>
<Target Name="PopulateInfo" DependsOnTargets="GitVersion" BeforeTargets="GetAssemblyVersion;GenerateNuspec;GetPackageContents">
<PropertyGroup>
<Version>$(GitSemVerMajor).$(GitSemVerMinor)</Version>
<PackageVersion>$(Version)</PackageVersion>
</PropertyGroup>
</Target>
<Target Name="RenameLatestZip" AfterTargets="PackagePlugin" Condition="'$(Configuration)' == 'Release'">
<Exec Command="rename &quot;$(OutDir)$(AssemblyName)\latest.zip&quot; &quot;$(AssemblyName)-$(Version).zip&quot;" />
</Target>
<Target Name="Clean"> <Target Name="Clean">
<RemoveDir Directories="dist"/> <RemoveDir Directories="dist"/>
</Target> </Target>

View File

@ -3,7 +3,12 @@
"Author": "Liza Carvelli", "Author": "Liza Carvelli",
"Punchline": "Shows possible trap & hoard coffer locations in Palace of the Dead & Heaven on High.", "Punchline": "Shows possible trap & hoard coffer locations in Palace of the Dead & Heaven on High.",
"Description": "Shows possible trap & hoard coffer locations in Palace of the Dead & Heaven on High.\n\nThe default configuration requires Splatoon to be installed. If you do not wish to install Splatoon, you can switch to the experimental 'Simple' renderer in the configuration.", "Description": "Shows possible trap & hoard coffer locations in Palace of the Dead & Heaven on High.\n\nThe default configuration requires Splatoon to be installed. If you do not wish to install Splatoon, you can switch to the experimental 'Simple' renderer in the configuration.",
"RepoUrl": "https://github.com/carvelli/PalacePal", "RepoUrl": "https://git.carvel.li/liza/PalacePal",
"IconUrl": "https://raw.githubusercontent.com/carvelli/Dalamud-Plugins/master/dist/Palace Pal.png", "IconUrl": "https://plugins.carvel.li/icons/PalacePal.png",
"Tags": [ "potd", "palace", "hoh", "splatoon" ] "Tags": [
"potd",
"palace",
"hoh",
"splatoon"
]
} }

View File

@ -1,18 +1,15 @@
using Dalamud.Interface.Windowing; using System;
using Dalamud.Plugin;
using Pal.Client.Rendering;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Game; using Dalamud.Extensions.MicrosoftLogging;
using Dalamud.Game.ClientState;
using Dalamud.Game.Command; using Dalamud.Game.Command;
using Dalamud.Game.Gui; using Dalamud.Interface.Windowing;
using Pal.Client.Properties; using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using ECommons; using ECommons;
using ECommons.DalamudServices; using ECommons.DalamudServices;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -20,9 +17,11 @@ using Microsoft.Extensions.Logging;
using Pal.Client.Commands; using Pal.Client.Commands;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Client.DependencyInjection; using Pal.Client.DependencyInjection;
using Pal.Client.Properties;
using Pal.Client.Rendering;
namespace Pal.Client;
namespace Pal.Client
{
/// <summary> /// <summary>
/// With all DI logic elsewhere, this plugin shell really only takes care of a few things around events that /// With all DI logic elsewhere, this plugin shell really only takes care of a few things around events that
/// need to be sent to different receivers depending on priority or configuration . /// need to be sent to different receivers depending on priority or configuration .
@ -32,33 +31,35 @@ namespace Pal.Client
{ {
private readonly CancellationTokenSource _initCts = new(); private readonly CancellationTokenSource _initCts = new();
private readonly DalamudPluginInterface _pluginInterface; private readonly IDalamudPluginInterface _pluginInterface;
private readonly CommandManager _commandManager; private readonly ICommandManager _commandManager;
private readonly ClientState _clientState; private readonly IClientState _clientState;
private readonly ChatGui _chatGui; private readonly IChatGui _chatGui;
private readonly Framework _framework; private readonly IFramework _framework;
private readonly TaskCompletionSource<IServiceScope> _rootScopeCompletionSource = new(); private readonly TaskCompletionSource<IServiceScope> _rootScopeCompletionSource = new();
private ELoadState _loadState = ELoadState.Initializing; private ELoadState _loadState = ELoadState.Initializing;
private DependencyInjectionContext? _dependencyInjectionContext; private DependencyInjectionContext? _dependencyInjectionContext;
private ILogger _logger = DependencyInjectionContext.LoggerProvider.CreateLogger<Plugin>(); private ILogger _logger;
private WindowSystem? _windowSystem; private WindowSystem? _windowSystem;
private IServiceScope? _rootScope; private IServiceScope? _rootScope;
private Action? _loginAction; private Action? _loginAction;
public Plugin( public Plugin(
DalamudPluginInterface pluginInterface, IDalamudPluginInterface pluginInterface,
CommandManager commandManager, ICommandManager commandManager,
ClientState clientState, IClientState clientState,
ChatGui chatGui, IChatGui chatGui,
Framework framework) IFramework framework,
IPluginLog pluginLog)
{ {
_pluginInterface = pluginInterface; _pluginInterface = pluginInterface;
_commandManager = commandManager; _commandManager = commandManager;
_clientState = clientState; _clientState = clientState;
_chatGui = chatGui; _chatGui = chatGui;
_framework = framework; _framework = framework;
_logger = new DalamudLoggerProvider(pluginLog).CreateLogger<Plugin>();
// set up the current UI language before creating anything // set up the current UI language before creating anything
Localization.Culture = new CultureInfo(_pluginInterface.UiLanguage); Localization.Culture = new CultureInfo(_pluginInterface.UiLanguage);
@ -75,8 +76,6 @@ namespace Pal.Client
Task.Run(async () => await CreateDependencyContext()); Task.Run(async () => await CreateDependencyContext());
} }
public string Name => Localization.Palace_Pal;
private async Task CreateDependencyContext() private async Task CreateDependencyContext()
{ {
try try
@ -134,7 +133,7 @@ namespace Pal.Client
_loginAction = loginAction; _loginAction = loginAction;
} }
private void Login(object? sender, EventArgs eventArgs) private void Login()
{ {
_loginAction?.Invoke(); _loginAction?.Invoke();
_loginAction = null; _loginAction = null;
@ -234,4 +233,3 @@ namespace Pal.Client
Error Error
} }
} }
}

View File

@ -1,8 +0,0 @@
using System.Reflection;
[assembly: AssemblyVersion(ThisAssembly.Git.SemVer.Major + "." + ThisAssembly.Git.SemVer.Minor)]
[assembly: AssemblyFileVersion(ThisAssembly.Git.SemVer.Major + "." + ThisAssembly.Git.SemVer.Minor)]
[assembly: AssemblyInformationalVersion(
ThisAssembly.Git.SemVer.Major + "." +
ThisAssembly.Git.SemVer.Minor + "+" +
ThisAssembly.Git.Commit)]

View File

@ -15,6 +15,7 @@ dotnet ef migrations add MigrationName --configuration EF
``` ```
To rebuild the compiled model: To rebuild the compiled model:
```shell ```shell
dotnet ef dbcontext optimize --output-dir Database/Compiled --namespace Pal.Client.Database.Compiled --configuration EF dotnet ef dbcontext optimize --output-dir Database/Compiled --namespace Pal.Client.Database.Compiled --configuration EF
``` ```

View File

@ -1,9 +1,8 @@
namespace Pal.Client.Rendering namespace Pal.Client.Rendering;
{
internal enum ELayer internal enum ELayer
{ {
TrapHoard, TrapHoard,
RegularCoffers, RegularCoffers,
Test, Test,
} }
}

View File

@ -1,9 +1,8 @@
namespace Pal.Client.Rendering namespace Pal.Client.Rendering;
{
public interface IRenderElement public interface IRenderElement
{ {
bool IsValid { get; } bool IsValid { get; }
uint Color { get; set; } bool Enabled { get; set; }
}
} }

View File

@ -3,8 +3,8 @@ using System.Numerics;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Client.Floors; using Pal.Client.Floors;
namespace Pal.Client.Rendering namespace Pal.Client.Rendering;
{
internal interface IRenderer internal interface IRenderer
{ {
ERenderer GetConfigValue(); ERenderer GetConfigValue();
@ -13,8 +13,7 @@ namespace Pal.Client.Rendering
void ResetLayer(ELayer layer); void ResetLayer(ELayer layer);
IRenderElement CreateElement(MemoryLocation.EType type, Vector3 pos, uint color, bool fill = false); IRenderElement CreateElement(MemoryLocation.EType type, Vector3 pos, bool enabled, uint color, bool fill = false);
void DrawDebugItems(uint trapColor, uint hoardColor); void DrawDebugItems(uint trapColor, uint hoardColor);
} }
}

View File

@ -1,8 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using Pal.Client.Floors; using Pal.Client.Floors;
namespace Pal.Client.Rendering namespace Pal.Client.Rendering;
{
internal sealed class MarkerConfig internal sealed class MarkerConfig
{ {
private static readonly MarkerConfig EmptyConfig = new(); private static readonly MarkerConfig EmptyConfig = new();
@ -21,4 +21,3 @@ namespace Pal.Client.Rendering
public static MarkerConfig ForType(MemoryLocation.EType type) => public static MarkerConfig ForType(MemoryLocation.EType type) =>
MarkerConfigs.GetValueOrDefault(type, EmptyConfig); MarkerConfigs.GetValueOrDefault(type, EmptyConfig);
} }
}

View File

@ -6,8 +6,8 @@ using Microsoft.Extensions.Logging;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Client.Floors; using Pal.Client.Floors;
namespace Pal.Client.Rendering namespace Pal.Client.Rendering;
{
internal sealed class RenderAdapter : IRenderer, IDisposable internal sealed class RenderAdapter : IRenderer, IDisposable
{ {
private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IServiceScopeFactory _serviceScopeFactory;
@ -60,8 +60,9 @@ namespace Pal.Client.Rendering
public void ResetLayer(ELayer layer) public void ResetLayer(ELayer layer)
=> _implementation.ResetLayer(layer); => _implementation.ResetLayer(layer);
public IRenderElement CreateElement(MemoryLocation.EType type, Vector3 pos, uint color, bool fill = false) public IRenderElement CreateElement(MemoryLocation.EType type, Vector3 pos, bool enabled, uint color,
=> _implementation.CreateElement(type, pos, color, fill); bool fill = false)
=> _implementation.CreateElement(type, pos, enabled, color, fill);
public ERenderer GetConfigValue() public ERenderer GetConfigValue()
=> throw new NotImplementedException(); => throw new NotImplementedException();
@ -75,4 +76,3 @@ namespace Pal.Client.Rendering
sr.DrawLayers(); sr.DrawLayers();
} }
} }
}

View File

@ -1,8 +1,6 @@
namespace Pal.Client.Rendering namespace Pal.Client.Rendering;
{
internal static class RenderData internal static class RenderData
{ {
public static readonly uint ColorInvisible = 0;
public static readonly long TestLayerTimeout = 10_000; public static readonly long TestLayerTimeout = 10_000;
} }
}

View File

@ -1,18 +1,16 @@
using Dalamud.Interface; using System;
using ImGuiNET;
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Game.ClientState; using Dalamud.Interface.Utility;
using Dalamud.Game.Gui; using Dalamud.Plugin.Services;
using ImGuiNET;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Client.DependencyInjection;
using Pal.Client.Floors; using Pal.Client.Floors;
namespace Pal.Client.Rendering namespace Pal.Client.Rendering;
{
/// <summary> /// <summary>
/// Simple renderer that only draws basic stuff. /// Simple renderer that only draws basic stuff.
/// ///
@ -24,13 +22,13 @@ namespace Pal.Client.Rendering
{ {
private const int SegmentCount = 20; private const int SegmentCount = 20;
private readonly ClientState _clientState; private readonly IClientState _clientState;
private readonly GameGui _gameGui; private readonly IGameGui _gameGui;
private readonly IPalacePalConfiguration _configuration; private readonly IPalacePalConfiguration _configuration;
private readonly TerritoryState _territoryState; private readonly TerritoryState _territoryState;
private readonly ConcurrentDictionary<ELayer, SimpleLayer> _layers = new(); private readonly ConcurrentDictionary<ELayer, SimpleLayer> _layers = new();
public SimpleRenderer(ClientState clientState, GameGui gameGui, IPalacePalConfiguration configuration, public SimpleRenderer(IClientState clientState, IGameGui gameGui, IPalacePalConfiguration configuration,
TerritoryState territoryState) TerritoryState territoryState)
{ {
_clientState = clientState; _clientState = clientState;
@ -54,13 +52,15 @@ namespace Pal.Client.Rendering
l.Dispose(); l.Dispose();
} }
public IRenderElement CreateElement(MemoryLocation.EType type, Vector3 pos, uint color, bool fill = false) public IRenderElement CreateElement(MemoryLocation.EType type, Vector3 pos, bool enabled, uint color,
bool fill = false)
{ {
var config = MarkerConfig.ForType(type); var config = MarkerConfig.ForType(type);
return new SimpleElement return new SimpleElement
{ {
Type = type, Type = type,
Position = pos + new Vector3(0, config.OffsetY, 0), Position = pos + new Vector3(0, config.OffsetY, 0),
Enabled = enabled,
Color = color, Color = color,
Radius = config.Radius, Radius = config.Radius,
Fill = fill, Fill = fill,
@ -77,10 +77,12 @@ namespace Pal.Client.Rendering
(SimpleElement)CreateElement( (SimpleElement)CreateElement(
MemoryLocation.EType.Trap, MemoryLocation.EType.Trap,
_clientState.LocalPlayer?.Position ?? default, _clientState.LocalPlayer?.Position ?? default,
true,
trapColor), trapColor),
(SimpleElement)CreateElement( (SimpleElement)CreateElement(
MemoryLocation.EType.Hoard, MemoryLocation.EType.Hoard,
_clientState.LocalPlayer?.Position ?? default, _clientState.LocalPlayer?.Position ?? default,
true,
hoardColor) hoardColor)
}, },
ExpiresAt = Environment.TickCount64 + RenderData.TestLayerTimeout ExpiresAt = Environment.TickCount64 + RenderData.TestLayerTimeout
@ -120,7 +122,7 @@ namespace Pal.Client.Rendering
private void Draw(SimpleElement e) private void Draw(SimpleElement e)
{ {
if (e.Color == RenderData.ColorInvisible) if (!e.Enabled)
return; return;
switch (e.Type) switch (e.Type)
@ -181,7 +183,7 @@ namespace Pal.Client.Rendering
public required IReadOnlyList<SimpleElement> Elements { get; init; } public required IReadOnlyList<SimpleElement> Elements { get; init; }
public long ExpiresAt { get; init; } = long.MaxValue; public long ExpiresAt { get; init; } = long.MaxValue;
public bool IsValid(ClientState clientState) => public bool IsValid(IClientState clientState) =>
TerritoryType == clientState.TerritoryType && ExpiresAt >= Environment.TickCount64; TerritoryType == clientState.TerritoryType && ExpiresAt >= Environment.TickCount64;
public void Dispose() public void Dispose()
@ -196,9 +198,9 @@ namespace Pal.Client.Rendering
public bool IsValid { get; set; } = true; public bool IsValid { get; set; } = true;
public required MemoryLocation.EType Type { get; init; } public required MemoryLocation.EType Type { get; init; }
public required Vector3 Position { get; init; } public required Vector3 Position { get; init; }
public required bool Enabled { get; set; }
public required uint Color { get; set; } public required uint Color { get; set; }
public required float Radius { get; init; } public required float Radius { get; init; }
public required bool Fill { get; init; } public required bool Fill { get; init; }
} }
} }
}

View File

@ -1,37 +1,37 @@
using Dalamud.Plugin; using System;
using ECommons;
using ECommons.Reflection;
using ECommons.Schedulers;
using ECommons.SplatoonAPI;
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using System.Reflection; using System.Reflection;
using Dalamud.Game.ClientState; using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using ECommons;
using ECommons.Reflection;
using ECommons.Schedulers;
using ECommons.SplatoonAPI;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Client.DependencyInjection; using Pal.Client.DependencyInjection;
using Pal.Client.Floors; using Pal.Client.Floors;
namespace Pal.Client.Rendering namespace Pal.Client.Rendering;
{
internal sealed class SplatoonRenderer : IRenderer, IDisposable internal sealed class SplatoonRenderer : IRenderer, IDisposable
{ {
private const long OnTerritoryChange = -2; private const long OnTerritoryChange = -2;
private readonly ILogger<SplatoonRenderer> _logger; private readonly ILogger<SplatoonRenderer> _logger;
private readonly DebugState _debugState; private readonly DebugState _debugState;
private readonly ClientState _clientState; private readonly IClientState _clientState;
private readonly Chat _chat; private readonly Chat _chat;
public SplatoonRenderer( public SplatoonRenderer(
ILogger<SplatoonRenderer> logger, ILogger<SplatoonRenderer> logger,
DalamudPluginInterface pluginInterface, IDalamudPluginInterface pluginInterface,
IDalamudPlugin dalamudPlugin, IDalamudPlugin dalamudPlugin,
DebugState debugState, DebugState debugState,
ClientState clientState, IClientState clientState,
Chat chat) Chat chat)
{ {
_logger = logger; _logger = logger;
@ -80,7 +80,7 @@ namespace Pal.Client.Rendering
private string ToLayerName(ELayer layer) private string ToLayerName(ELayer layer)
=> $"PalacePal.{layer}"; => $"PalacePal.{layer}";
public IRenderElement CreateElement(MemoryLocation.EType type, Vector3 pos, uint color, bool fill = false) public IRenderElement CreateElement(MemoryLocation.EType type, Vector3 pos, bool enabled, uint color, bool fill = false)
{ {
MarkerConfig config = MarkerConfig.ForType(type); MarkerConfig config = MarkerConfig.ForType(type);
Element element = new Element(ElementType.CircleAtFixedCoordinates) Element element = new Element(ElementType.CircleAtFixedCoordinates)
@ -96,6 +96,7 @@ namespace Pal.Client.Rendering
FillStep = 1, FillStep = 1,
color = color, color = color,
thicc = 2, thicc = 2,
Enabled = enabled,
}; };
return new SplatoonElement(this, element); return new SplatoonElement(this, element);
} }
@ -111,8 +112,8 @@ namespace Pal.Client.Rendering
var elements = new List<IRenderElement> var elements = new List<IRenderElement>
{ {
CreateElement(MemoryLocation.EType.Trap, pos.Value, trapColor), CreateElement(MemoryLocation.EType.Trap, pos.Value, true, trapColor),
CreateElement(MemoryLocation.EType.Hoard, pos.Value, hoardColor), CreateElement(MemoryLocation.EType.Hoard, pos.Value, true, hoardColor),
}; };
if (!Splatoon.AddDynamicElements(ToLayerName(ELayer.Test), if (!Splatoon.AddDynamicElements(ToLayerName(ELayer.Test),
@ -186,11 +187,10 @@ namespace Pal.Client.Rendering
public bool IsValid => !_renderer.IsDisposed && Delegate.IsValid(); public bool IsValid => !_renderer.IsDisposed && Delegate.IsValid();
public uint Color public bool Enabled
{ {
get => Delegate.color; get => Delegate.Enabled;
set => Delegate.color = value; set => Delegate.Enabled = value;
}
} }
} }
} }

View File

@ -2,8 +2,8 @@
using Dalamud.Logging; using Dalamud.Logging;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace Pal.Client.Scheduled namespace Pal.Client.Scheduled;
{
internal interface IQueueOnFrameworkThread internal interface IQueueOnFrameworkThread
{ {
internal interface IHandler internal interface IHandler
@ -37,4 +37,3 @@ namespace Pal.Client.Scheduled
} }
} }
} }
}

View File

@ -4,8 +4,8 @@ using Pal.Client.DependencyInjection;
using Pal.Client.Floors; using Pal.Client.Floors;
using Pal.Client.Rendering; using Pal.Client.Rendering;
namespace Pal.Client.Scheduled namespace Pal.Client.Scheduled;
{
internal sealed class QueuedConfigUpdate : IQueueOnFrameworkThread internal sealed class QueuedConfigUpdate : IQueueOnFrameworkThread
{ {
internal sealed class Handler : IQueueOnFrameworkThread.Handler<QueuedConfigUpdate> internal sealed class Handler : IQueueOnFrameworkThread.Handler<QueuedConfigUpdate>
@ -26,4 +26,3 @@ namespace Pal.Client.Scheduled
} }
} }
} }
}

View File

@ -1,17 +1,17 @@
using Account; using System;
using Pal.Common;
using System;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Export;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Pal.Client.Database; using Pal.Client.Database;
using Pal.Client.DependencyInjection; using Pal.Client.DependencyInjection;
using Pal.Client.Properties; using Pal.Client.Properties;
using Pal.Client.Windows; using Pal.Client.Windows;
using Pal.Common;
namespace Pal.Client.Scheduled;
namespace Pal.Client.Scheduled
{
internal sealed class QueuedImport : IQueueOnFrameworkThread internal sealed class QueuedImport : IQueueOnFrameworkThread
{ {
private ExportRoot Export { get; } private ExportRoot Export { get; }
@ -120,4 +120,3 @@ namespace Pal.Client.Scheduled
} }
} }
} }
}

View File

@ -11,8 +11,8 @@ using Pal.Client.Floors.Tasks;
using Pal.Client.Net; using Pal.Client.Net;
using Pal.Common; using Pal.Common;
namespace Pal.Client.Scheduled namespace Pal.Client.Scheduled;
{
internal sealed class QueuedSyncResponse : IQueueOnFrameworkThread internal sealed class QueuedSyncResponse : IQueueOnFrameworkThread
{ {
public required SyncType Type { get; init; } public required SyncType Type { get; init; }
@ -158,4 +158,3 @@ namespace Pal.Client.Scheduled
Download, Download,
MarkSeen, MarkSeen,
} }
}

View File

@ -7,8 +7,8 @@ using Pal.Client.Floors;
using Pal.Client.Windows; using Pal.Client.Windows;
using Pal.Common; using Pal.Common;
namespace Pal.Client.Scheduled namespace Pal.Client.Scheduled;
{
internal sealed class QueuedUndoImport : IQueueOnFrameworkThread internal sealed class QueuedUndoImport : IQueueOnFrameworkThread
{ {
public QueuedUndoImport(Guid exportId) public QueuedUndoImport(Guid exportId)
@ -39,4 +39,3 @@ namespace Pal.Client.Scheduled
} }
} }
} }
}

View File

@ -1,15 +1,15 @@
using System; using System;
using System.Numerics;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using ECommons; using ECommons;
using ImGuiNET; using ImGuiNET;
using System.Numerics;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Client.Extensions; using Pal.Client.Extensions;
using Pal.Client.Properties; using Pal.Client.Properties;
namespace Pal.Client.Windows namespace Pal.Client.Windows;
{
internal sealed class AgreementWindow : Window, IDisposable, ILanguageChanged internal sealed class AgreementWindow : Window, IDisposable, ILanguageChanged
{ {
private const string WindowId = "###PalPalaceAgreement"; private const string WindowId = "###PalPalaceAgreement";
@ -99,7 +99,6 @@ namespace Pal.Client.Windows
ImGui.Separator(); ImGui.Separator();
if (ImGui.Button(Localization.Agreement_ViewPluginAndServerSourceCode)) if (ImGui.Button(Localization.Agreement_ViewPluginAndServerSourceCode))
GenericHelpers.ShellStart("https://github.com/carvelli/PalPalace"); GenericHelpers.ShellStart("https://git.carvel.li/liza/PalacePal");
}
} }
} }

View File

@ -1,31 +1,33 @@
using Account; using System;
using Dalamud.Interface;
using Dalamud.Interface.Components;
using Dalamud.Interface.ImGuiFileDialog;
using Dalamud.Interface.Windowing;
using ECommons;
using Google.Protobuf;
using ImGuiNET;
using Pal.Client.Net;
using Pal.Client.Rendering;
using Pal.Client.Scheduled;
using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Interface;
using Dalamud.Interface.Components;
using Dalamud.Interface.ImGuiFileDialog;
using Dalamud.Interface.Windowing;
using ECommons;
using Export;
using Google.Protobuf;
using ImGuiNET;
using LLib;
using LLib.ImGui;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Pal.Client.Extensions;
using Pal.Client.Properties;
using Pal.Client.Configuration; using Pal.Client.Configuration;
using Pal.Client.Database; using Pal.Client.Database;
using Pal.Client.DependencyInjection; using Pal.Client.DependencyInjection;
using Pal.Client.Extensions;
using Pal.Client.Floors; using Pal.Client.Floors;
using Pal.Client.Net;
using Pal.Client.Properties;
using Pal.Client.Rendering;
using Pal.Client.Scheduled;
namespace Pal.Client.Windows namespace Pal.Client.Windows;
{
internal sealed class ConfigWindow : Window, ILanguageChanged, IDisposable internal sealed class ConfigWindow : LWindow, ILanguageChanged, IDisposable
{ {
private const string WindowId = "###PalPalaceConfig"; private const string WindowId = "###PalPalaceConfig";
@ -97,6 +99,12 @@ namespace Pal.Client.Windows
Position = new Vector2(300, 300); Position = new Vector2(300, 300);
PositionCondition = ImGuiCond.FirstUseEver; PositionCondition = ImGuiCond.FirstUseEver;
SizeConstraints = new WindowSizeConstraints
{
MinimumSize = new Vector2(300, 300),
MaximumSize = new Vector2(9999, 9999),
};
_importDialog = new FileDialogManager _importDialog = new FileDialogManager
{ AddedWindowFlags = ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoDocking }; { AddedWindowFlags = ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoDocking };
_exportDialog = new FileDialogManager _exportDialog = new FileDialogManager
@ -284,11 +292,13 @@ namespace Pal.Client.Windows
ImGui.TextWrapped(Localization.Config_ImportExplanation1); ImGui.TextWrapped(Localization.Config_ImportExplanation1);
ImGui.TextWrapped(Localization.Config_ImportExplanation2); ImGui.TextWrapped(Localization.Config_ImportExplanation2);
ImGui.TextWrapped(Localization.Config_ImportExplanation3); ImGui.TextWrapped(Localization.Config_ImportExplanation3);
/* FIXME
ImGui.Separator(); ImGui.Separator();
ImGui.TextWrapped(string.Format(Localization.Config_ImportDownloadLocation, ImGui.TextWrapped(string.Format(Localization.Config_ImportDownloadLocation,
"https://github.com/carvelli/PalacePal/releases/")); "https://github.com/carvelli/PalacePal/releases/"));
if (ImGui.Button(Localization.Config_Import_VisitGitHub)) if (ImGui.Button(Localization.Config_Import_VisitGitHub))
GenericHelpers.ShellStart("https://github.com/carvelli/PalacePal/releases/latest"); GenericHelpers.ShellStart("https://github.com/carvelli/PalacePal/releases/latest");
*/
ImGui.Separator(); ImGui.Separator();
ImGui.Text(Localization.Config_SelectImportFile); ImGui.Text(Localization.Config_SelectImportFile);
ImGui.SameLine(); ImGui.SameLine();
@ -576,4 +586,3 @@ namespace Pal.Client.Windows
} }
} }
} }
}

View File

@ -1,15 +1,15 @@
using Dalamud.Interface.Windowing; using System;
using ImGuiNET;
using Pal.Common;
using Palace;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Interface.Windowing;
using ImGuiNET;
using Pal.Client.Properties; using Pal.Client.Properties;
using Pal.Common;
using Palace;
namespace Pal.Client.Windows;
namespace Pal.Client.Windows
{
internal sealed class StatisticsWindow : Window, IDisposable, ILanguageChanged internal sealed class StatisticsWindow : Window, IDisposable, ILanguageChanged
{ {
private const string WindowId = "###PalacePalStats"; private const string WindowId = "###PalacePalStats";
@ -123,4 +123,3 @@ namespace Pal.Client.Windows
} }
} }
} }
}

View File

@ -0,0 +1,344 @@
{
"version": 1,
"dependencies": {
"net8.0-windows7.0": {
"Dalamud.Extensions.MicrosoftLogging": {
"type": "Direct",
"requested": "[4.0.1, )",
"resolved": "4.0.1",
"contentHash": "fMEL2ajtF/30SBBku7vMyG0yye5eHN/A9fgT//1CEjUth/Wz2CYco5Ehye21T8KN1IuAPwoqJuu49rB71j+8ug==",
"dependencies": {
"Microsoft.Extensions.Logging": "8.0.0"
}
},
"DalamudPackager": {
"type": "Direct",
"requested": "[2.1.13, )",
"resolved": "2.1.13",
"contentHash": "rMN1omGe8536f4xLMvx9NwfvpAc9YFFfeXJ1t4P4PE6Gu8WCIoFliR1sh07hM+bfODmesk/dvMbji7vNI+B/pQ=="
},
"DotNet.ReproducibleBuilds": {
"type": "Direct",
"requested": "[1.1.1, )",
"resolved": "1.1.1",
"contentHash": "+H2t/t34h6mhEoUvHi8yGXyuZ2GjSovcGYehJrS2MDm2XgmPfZL2Sdxg+uL2lKgZ4M6tTwKHIlxOob2bgh0NRQ==",
"dependencies": {
"Microsoft.SourceLink.AzureRepos.Git": "1.1.1",
"Microsoft.SourceLink.Bitbucket.Git": "1.1.1",
"Microsoft.SourceLink.GitHub": "1.1.1",
"Microsoft.SourceLink.GitLab": "1.1.1"
}
},
"Google.Protobuf": {
"type": "Direct",
"requested": "[3.27.2, )",
"resolved": "3.27.2",
"contentHash": "0wdgA3LO9mBS477jieBFs4pU1sWhVtwv/P+i9nAEiFDQyUA7PPHDBbJL1CeqYtV18jLiq9og4n7wSVCO171OBg=="
},
"Grpc.Net.Client": {
"type": "Direct",
"requested": "[2.63.0, )",
"resolved": "2.63.0",
"contentHash": "847zG24daOP1242OpbnjhbKtplH/EfV/76QReQA3cbS5SL78uIXsWMe9IN9JlIb4+kT3eE4fjMCXTn8BAQ91Ng==",
"dependencies": {
"Grpc.Net.Common": "2.63.0",
"Microsoft.Extensions.Logging.Abstractions": "6.0.0"
}
},
"Grpc.Tools": {
"type": "Direct",
"requested": "[2.64.0, )",
"resolved": "2.64.0",
"contentHash": "W5RrhDFHUhioASktxfuDs5fTjWUxwegljZAig9zFL8nWNskeyQA6OXN2choWKYxGrljer25VqCJCMbWz7XHvqg=="
},
"Microsoft.EntityFrameworkCore.Sqlite": {
"type": "Direct",
"requested": "[8.0.6, )",
"resolved": "8.0.6",
"contentHash": "nC4cZN4zReTb22qd9WDU0eDmlXvkyf2g2pqQ3VIHJbkpJcdWSY/PDgwGpbpShsVcAjXbkjGiUcv9aGwa61xQPw==",
"dependencies": {
"Microsoft.EntityFrameworkCore.Sqlite.Core": "8.0.6",
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.6"
}
},
"Microsoft.Extensions.Logging": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "tvRkov9tAJ3xP51LCv3FJ2zINmv1P8Hi8lhhtcKGqM+ImiTCC84uOPEI4z8Cdq2C3o9e+Aa0Gw0rmrsJD77W+w==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "8.0.0",
"Microsoft.Extensions.Logging.Abstractions": "8.0.0",
"Microsoft.Extensions.Options": "8.0.0"
}
},
"Microsoft.SourceLink.Gitea": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "KOBodmDnlWGIqZt2hT47Q69TIoGhIApDVLCyyj9TT5ct8ju16AbHYcB4XeknoHX562wO1pMS/1DfBIZK+V+sxg==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "8.0.0",
"Microsoft.SourceLink.Common": "8.0.0"
}
},
"System.Security.Cryptography.ProtectedData": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "+TUFINV2q2ifyXauQXRwy4CiBhqvDEDZeVJU7qfxya4aRYOKzVBpN+4acx25VcPB9ywUN6C0n8drWl110PhZEg=="
},
"Grpc.Core.Api": {
"type": "Transitive",
"resolved": "2.63.0",
"contentHash": "t3+/MF8AxIqKq5UmPB9EWAnM9C/+lXOB8TRFfeVMDntf6dekfJmjpKDebaT4t2bbuwVwwvthxxox9BuGr59kYA=="
},
"Grpc.Net.Common": {
"type": "Transitive",
"resolved": "2.63.0",
"contentHash": "RLt6p31ZMsXRcHNeu1dQuIFLYZvnwP6LUzoDPlV3KoR4w9btmwrXIvz9Jbp1SOmxW7nXw9zShAeIt5LsqFAx5w==",
"dependencies": {
"Grpc.Core.Api": "2.63.0"
}
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.Data.Sqlite.Core": {
"type": "Transitive",
"resolved": "8.0.6",
"contentHash": "umhZ0ZF2RI81rGFTnYmCxI+Euj4Aqe/6Y4+8CxN9OVJNGDNIqB5laJ3wxQTU8zXCcm2k9F7FL+/6RVoOT4z1Fw==",
"dependencies": {
"SQLitePCLRaw.core": "2.1.6"
}
},
"Microsoft.EntityFrameworkCore": {
"type": "Transitive",
"resolved": "8.0.6",
"contentHash": "Ms5e5QuBAjVIuQsGumeLvkgMiOpnj6wxPvwBIoe1NfTkseWK4NZYztnhgDlpkCPkrUmJEXLv69kl349Ours30Q==",
"dependencies": {
"Microsoft.EntityFrameworkCore.Abstractions": "8.0.6",
"Microsoft.EntityFrameworkCore.Analyzers": "8.0.6",
"Microsoft.Extensions.Caching.Memory": "8.0.0",
"Microsoft.Extensions.Logging": "8.0.0"
}
},
"Microsoft.EntityFrameworkCore.Abstractions": {
"type": "Transitive",
"resolved": "8.0.6",
"contentHash": "X7wSSBNFRuN8j8M9HDYG7rPpEeyhY+PdJZR9rftmgvsZH0eK5+bZ3b3As8iO4rLEpjsBzDnrgSIY6q2F3HQatw=="
},
"Microsoft.EntityFrameworkCore.Analyzers": {
"type": "Transitive",
"resolved": "8.0.6",
"contentHash": "fDNtuQ4lAaPaCOlsrwUck/GvnF4QLeDpMmE1L5QtxZpMSmWfnL2/vk8sDL9OVTWcfprooI9V5MNpIx3/Tq5ehg=="
},
"Microsoft.EntityFrameworkCore.Relational": {
"type": "Transitive",
"resolved": "8.0.6",
"contentHash": "chhfmLusCGLGvNYtvMji6KGQlduPDnJsStG/LjS8qJhFWJDDzTZpSr2LHowewcxMrMo/Axc6Jwe+WwSi/vlkTg==",
"dependencies": {
"Microsoft.EntityFrameworkCore": "8.0.6",
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0"
}
},
"Microsoft.EntityFrameworkCore.Sqlite.Core": {
"type": "Transitive",
"resolved": "8.0.6",
"contentHash": "87xfPtqSouxWWdynYZv/rubd0rOUeiN9+XeoMWQzpZm/5svH1TuvzFODGIY0zKuXS18NiOFyHl9N6///eaEs/Q==",
"dependencies": {
"Microsoft.Data.Sqlite.Core": "8.0.6",
"Microsoft.EntityFrameworkCore.Relational": "8.0.6",
"Microsoft.Extensions.DependencyModel": "8.0.0"
}
},
"Microsoft.Extensions.Caching.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "3KuSxeHoNYdxVYfg2IRZCThcrlJ1XJqIXkAWikCsbm5C/bCjv7G0WoKDyuR98Q+T607QT2Zl5GsbGRkENcV2yQ==",
"dependencies": {
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Caching.Memory": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "7pqivmrZDzo1ADPkRwjy+8jtRKWRCPag9qPI+p7sgu7Q4QreWhcvbiWXsbhP+yY8XSiDvZpu2/LWdBv7PnmOpQ==",
"dependencies": {
"Microsoft.Extensions.Caching.Abstractions": "8.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Logging.Abstractions": "8.0.0",
"Microsoft.Extensions.Options": "8.0.0",
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Configuration.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "3lE/iLSutpgX1CC0NOW70FJoGARRHbyKmG7dc0klnUZ9Dd9hS6N/POPWhKhMLCEuNN5nXEY5agmlFtH562vqhQ==",
"dependencies": {
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.DependencyInjection": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "V8S3bsm50ig6JSyrbcJJ8bW2b9QLGouz+G1miK3UTaOWmMtFwNNNzUf4AleyDWUmTrWMLNnFSLEQtxmxgNQnNQ==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg=="
},
"Microsoft.Extensions.DependencyModel": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "NSmDw3K0ozNDgShSIpsZcbFIzBX4w28nDag+TfaQujkXGazBm+lid5onlWoCBy4VsLxqnnKjEBbGSJVWJMf43g==",
"dependencies": {
"System.Text.Encodings.Web": "8.0.0",
"System.Text.Json": "8.0.0"
}
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "JOVOfqpnqlVLUzINQ2fox8evY2SKLYJ3BV8QDe/Jyp21u1T7r45x/R/5QdteURMR5r01GxeJSBBUOCOyaNXA3g==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g=="
},
"Microsoft.SourceLink.AzureRepos.Git": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "qB5urvw9LO2bG3eVAkuL+2ughxz2rR7aYgm2iyrB8Rlk9cp2ndvGRCvehk3rNIhRuNtQaeKwctOl1KvWiklv5w==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.Bitbucket.Git": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "cDzxXwlyWpLWaH0em4Idj0H3AmVo3L/6xRXKssYemx+7W52iNskj/SQ4FOmfCb8YQt39otTDNMveCZzYtMoucQ==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "IaJGnOv/M7UQjRJks7B6p7pbPnOwisYGOIzqCz5ilGFTApZ3ktOR+6zJ12ZRPInulBmdAf1SrGdDG2MU8g6XTw==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"Microsoft.SourceLink.GitLab": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "tvsg47DDLqqedlPeYVE2lmiTpND8F0hkrealQ5hYltSmvruy/Gr5nHAKSsjyw5L3NeM/HLMI5ORv7on/M4qyZw==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.6",
"contentHash": "BmAf6XWt4TqtowmiWe4/5rRot6GerAeklmOPfviOvwLoF5WwgxcJHAxZtySuyW9r9w+HLILnm8VfJFLCUJYW8A==",
"dependencies": {
"SQLitePCLRaw.lib.e_sqlite3": "2.1.6",
"SQLitePCLRaw.provider.e_sqlite3": "2.1.6"
}
},
"SQLitePCLRaw.core": {
"type": "Transitive",
"resolved": "2.1.6",
"contentHash": "wO6v9GeMx9CUngAet8hbO7xdm+M42p1XeJq47ogyRoYSvNSp0NGLI+MgC0bhrMk9C17MTVFlLiN6ylyExLCc5w==",
"dependencies": {
"System.Memory": "4.5.3"
}
},
"SQLitePCLRaw.lib.e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.6",
"contentHash": "2ObJJLkIUIxRpOUlZNGuD4rICpBnrBR5anjyfUFQep4hMOIeqW+XGQYzrNmHSVz5xSWZ3klSbh7sFR6UyDj68Q=="
},
"SQLitePCLRaw.provider.e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.6",
"contentHash": "PQ2Oq3yepLY4P7ll145P3xtx2bX8xF4PzaKPRpw9jZlKvfe4LE/saAV82inND9usn1XRpmxXk7Lal3MTI+6CNg==",
"dependencies": {
"SQLitePCLRaw.core": "2.1.6"
}
},
"System.Memory": {
"type": "Transitive",
"resolved": "4.5.3",
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA=="
},
"System.Text.Encodings.Web": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ=="
},
"System.Text.Json": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==",
"dependencies": {
"System.Text.Encodings.Web": "8.0.0"
}
},
"ecommons": {
"type": "Project"
},
"llib": {
"type": "Project",
"dependencies": {
"DalamudPackager": "[2.1.13, )"
}
},
"pal.common": {
"type": "Project"
}
},
"net8.0-windows7.0/win-x64": {
"SQLitePCLRaw.lib.e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.6",
"contentHash": "2ObJJLkIUIxRpOUlZNGuD4rICpBnrBR5anjyfUFQep4hMOIeqW+XGQYzrNmHSVz5xSWZ3klSbh7sFR6UyDj68Q=="
},
"System.Text.Encodings.Web": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ=="
}
}
}
}

View File

@ -1,8 +1,8 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
namespace Pal.Common namespace Pal.Common;
{
[SuppressMessage("ReSharper", "UnusedMember.Global")] [SuppressMessage("ReSharper", "UnusedMember.Global")]
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum ETerritoryType : ushort public enum ETerritoryType : ushort
@ -60,4 +60,3 @@ namespace Pal.Common
EurekaOrthos_81_90, EurekaOrthos_81_90,
EurekaOrthos_91_100 EurekaOrthos_91_100
} }
}

View File

@ -1,8 +1,10 @@
using System.ComponentModel.DataAnnotations; using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection; using System.Reflection;
namespace Pal.Common namespace Pal.Common;
{
public static class EnumExtensions public static class EnumExtensions
{ {
public static int? GetOrder(this Enum e) public static int? GetOrder(this Enum e)
@ -13,4 +15,3 @@ namespace Pal.Common
return attribute?.Order; return attribute?.Order;
} }
} }
}

View File

@ -4,10 +4,9 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Pal.Common namespace Pal.Common;
{
public static class ExportConfig public static class ExportConfig
{ {
public static int ExportVersion => 2; public static int ExportVersion => 2;
} }
}

View File

@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<LangVersion>11.0</LangVersion> <LangVersion>12.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<DebugType>portable</DebugType> <DebugType>portable</DebugType>
<PathMap Condition="$(SolutionDir) != ''">$(SolutionDir)=X:\</PathMap> <PathMap Condition="$(SolutionDir) != ''">$(SolutionDir)=X:\</PathMap>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -1,7 +1,8 @@
using System.Numerics; using System;
using System.Numerics;
namespace Pal.Common;
namespace Pal.Common
{
public class PalaceMath public class PalaceMath
{ {
private static readonly Vector3 ScaleFactor = new(5); private static readonly Vector3 ScaleFactor = new(5);
@ -19,4 +20,3 @@ namespace Pal.Common
return HashCode.Combine((int)v.X, (int)v.Y, (int)v.Z); return HashCode.Combine((int)v.X, (int)v.Y, (int)v.Z);
} }
} }
}

View File

@ -18,6 +18,7 @@ service AccountService {
} }
message CreateAccountRequest { message CreateAccountRequest {
Version version = 1;
} }
message CreateAccountReply { message CreateAccountReply {
@ -35,6 +36,7 @@ enum CreateAccountError {
message LoginRequest { message LoginRequest {
string accountId = 1; string accountId = 1;
Version version = 2;
} }
message LoginReply { message LoginReply {
@ -56,3 +58,8 @@ message VerifyRequest {
message VerifyReply { message VerifyReply {
} }
message Version {
int32 major = 1;
int32 minor = 2;
}

View File

@ -1,6 +1,6 @@
syntax = "proto3"; syntax = "proto3";
package account; package export;
import "google/protobuf/timestamp.proto"; import "google/protobuf/timestamp.proto";

View File

@ -0,0 +1,6 @@
{
"version": 1,
"dependencies": {
"net8.0": {}
}
}

View File

@ -1,27 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.22.1" />
<PackageReference Include="Grpc.Net.Client" Version="2.51.0" />
<PackageReference Include="Grpc.Tools" Version="2.52.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Pal.Common\Pal.Common.csproj" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="..\Pal.Common\Protos\account.proto" Link="Protos\account.proto" GrpcServices="Client" Access="Internal" />
<Protobuf Include="..\Pal.Common\Protos\palace.proto" Link="Protos\palace.proto" GrpcServices="Client" Access="Internal" />
</ItemGroup>
</Project>

View File

@ -1,34 +0,0 @@
using Grpc.Core;
using Grpc.Net.Client;
using Palace;
namespace Pal.StandaloneClient
{
internal class Program
{
private const string remoteUrl = "http://localhost:5415";
private static readonly Guid accountId = Guid.Parse("ce7b109a-5e29-4b63-ab3e-b6f89eb5e19e"); // manually created account id
static async Task Main(string[] args)
{
GrpcChannel channel = GrpcChannel.ForAddress(remoteUrl);
var accountClient = new Account.AccountService.AccountServiceClient(channel);
var loginReply = await accountClient.LoginAsync(new Account.LoginRequest
{
AccountId = accountId.ToString()
});
if (loginReply == null || !loginReply.Success)
throw new Exception($"Login failed: {loginReply?.Error}");
var headers = new Metadata()
{
{ "Authorization", $"Bearer {loginReply.AuthToken}" }
};
var palaceClient = new Palace.PalaceService.PalaceServiceClient(channel);
var markAsSeenRequest = new MarkObjectsSeenRequest { TerritoryType = 772 };
markAsSeenRequest.NetworkIds.Add("0c635960-0e2e-4ec6-9fb5-443d0e7a3315"); // this is an already existing entry
var markAsSeenReply = await palaceClient.MarkObjectsSeenAsync(markAsSeenRequest, headers: headers);
Console.WriteLine($"Reply = {markAsSeenReply.Success}");
}
}
}

View File

@ -1,6 +0,0 @@
# Palace Pal - Test Client
This is a very simple prototype for a local test client, which is more helpful
in troubleshooting some specific edge cases with the server implementation.
This should eventually be refactored into a test suite.

31
Pal.sln
View File

@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.3.32929.385 VisualStudioVersion = 17.3.32929.385
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pal.Server", "Pal.Server\Pal.Server.csproj", "{AB3E2849-DB06-46F6-8457-9AC1096B4125}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pal.Server", "Server\Server\Pal.Server.csproj", "{AB3E2849-DB06-46F6-8457-9AC1096B4125}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pal.Client", "Pal.Client\Pal.Client.csproj", "{7F1985B3-D376-4A91-BC9B-46C2A860F9EF}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pal.Client", "Pal.Client\Pal.Client.csproj", "{7F1985B3-D376-4A91-BC9B-46C2A860F9EF}"
EndProject EndProject
@ -13,6 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
Dockerfile = Dockerfile Dockerfile = Dockerfile
README.md = README.md README.md = README.md
.editorconfig = .editorconfig
EndProjectSection EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ECommons", "vendor\ECommons\ECommons\ECommons.csproj", "{D0B37096-5BC3-41B0-8D81-203CBA3932B0}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ECommons", "vendor\ECommons\ECommons\ECommons.csproj", "{D0B37096-5BC3-41B0-8D81-203CBA3932B0}"
@ -24,7 +25,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "github-workflows", "github-
.github\workflows\upload-crowdin.yml = .github\workflows\upload-crowdin.yml .github\workflows\upload-crowdin.yml = .github\workflows\upload-crowdin.yml
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pal.StandaloneClient", "Pal.StandaloneClient\Pal.StandaloneClient.csproj", "{EDC1C408-D832-4C09-97A2-61B223A84166}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pal.Server.Tests", "Server\Tests\Pal.Server.Tests.csproj", "{AEC052FA-F178-492C-9A09-ED28DBE1EF5E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LLib", "vendor\LLib\LLib.csproj", "{B1321FD5-7BBF-4C9D-83C1-F8D7C394F32A}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -66,14 +69,22 @@ Global
{D0B37096-5BC3-41B0-8D81-203CBA3932B0}.Release|Any CPU.Build.0 = Release|x64 {D0B37096-5BC3-41B0-8D81-203CBA3932B0}.Release|Any CPU.Build.0 = Release|x64
{D0B37096-5BC3-41B0-8D81-203CBA3932B0}.Release|x64.ActiveCfg = Release|x64 {D0B37096-5BC3-41B0-8D81-203CBA3932B0}.Release|x64.ActiveCfg = Release|x64
{D0B37096-5BC3-41B0-8D81-203CBA3932B0}.Release|x64.Build.0 = Release|x64 {D0B37096-5BC3-41B0-8D81-203CBA3932B0}.Release|x64.Build.0 = Release|x64
{EDC1C408-D832-4C09-97A2-61B223A84166}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EDC1C408-D832-4C09-97A2-61B223A84166}.Debug|Any CPU.Build.0 = Debug|Any CPU {AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EDC1C408-D832-4C09-97A2-61B223A84166}.Debug|x64.ActiveCfg = Debug|Any CPU {AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Debug|x64.ActiveCfg = Debug|Any CPU
{EDC1C408-D832-4C09-97A2-61B223A84166}.Debug|x64.Build.0 = Debug|Any CPU {AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Debug|x64.Build.0 = Debug|Any CPU
{EDC1C408-D832-4C09-97A2-61B223A84166}.Release|Any CPU.ActiveCfg = Release|Any CPU {AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EDC1C408-D832-4C09-97A2-61B223A84166}.Release|Any CPU.Build.0 = Release|Any CPU {AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Release|Any CPU.Build.0 = Release|Any CPU
{EDC1C408-D832-4C09-97A2-61B223A84166}.Release|x64.ActiveCfg = Release|Any CPU {AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Release|x64.ActiveCfg = Release|Any CPU
{EDC1C408-D832-4C09-97A2-61B223A84166}.Release|x64.Build.0 = Release|Any CPU {AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Release|x64.Build.0 = Release|Any CPU
{B1321FD5-7BBF-4C9D-83C1-F8D7C394F32A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B1321FD5-7BBF-4C9D-83C1-F8D7C394F32A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1321FD5-7BBF-4C9D-83C1-F8D7C394F32A}.Debug|x64.ActiveCfg = Debug|Any CPU
{B1321FD5-7BBF-4C9D-83C1-F8D7C394F32A}.Debug|x64.Build.0 = Debug|Any CPU
{B1321FD5-7BBF-4C9D-83C1-F8D7C394F32A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1321FD5-7BBF-4C9D-83C1-F8D7C394F32A}.Release|Any CPU.Build.0 = Release|Any CPU
{B1321FD5-7BBF-4C9D-83C1-F8D7C394F32A}.Release|x64.ActiveCfg = Release|Any CPU
{B1321FD5-7BBF-4C9D-83C1-F8D7C394F32A}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -5,15 +5,14 @@ Shows possible trap & hoard coffer locations in Palace of the Dead & Heaven on H
## Installation ## Installation
To install this plugin from my plugin repository, please check the To install this plugin from my plugin repository, please check the
[Installation Instructions](https://github.com/carvelli/Dalamud-Plugins#installation). [Installation Instructions](https://git.carvel.li/liza/plugin-repo/src/branch/master/README.md).
Additionally, you **need to install Splatoon**, which is used to render the visible overlays. Additionally, you **need to install Splatoon**, which is used to render the visible overlays.
Please check [Splatoon's Installation Instructions](https://github.com/NightmareXIV/MyDalamudPlugins#installation). Please check [Splatoon's Installation Instructions](https://github.com/NightmareXIV/MyDalamudPlugins#installation).
## Translation ## Translation
Please feel free to help by [translating this plugin into your language](https://crowdin.com/project/palace-pal). Please feel free to help by [translating this plugin into your language](https://crowdin.com/project/palace-pal).
If you want to translate the plugin into a language that is currently not enabled, If you want to translate the plugin into a language that is currently not enabled,
[please create a new issue](https://github.com/carvelli/PalacePal/issues/new). [please create a new issue](https://git.carvel.li/liza/PalacePal/issues/new).

1
Server Submodule

@ -0,0 +1 @@
Subproject commit e59583fac353fdd960556ed2fa65220d66db5637

4
docker-build.sh Executable file
View File

@ -0,0 +1,4 @@
git fetch origin master
git reset --hard origin/master
git submodule update --checkout
docker buildx build -t palacepal-server --platform linux/amd64,linux/arm64 .

2
vendor/ECommons vendored

@ -1 +1 @@
Subproject commit 001af17d74ab681f88d92600fa06dc3f98af74de Subproject commit dcd85f8cca504360eda4b2cb5327632cc500a22c

1
vendor/LLib vendored Submodule

@ -0,0 +1 @@
Subproject commit e206782c1106e1a5292a06af61783faef1ac0c42