Compare commits
62 Commits
Author | SHA1 | Date | |
---|---|---|---|
d239a6e4b0 | |||
9d5e4a797b | |||
3e2f917c14 | |||
2fdf9b1e4d | |||
18ffd66086 | |||
64e576a004 | |||
0d1882d97f | |||
964119cfd2 | |||
309edfcd17 | |||
8fbd3fbc0d | |||
ce9be45e8f | |||
8def5e28a4 | |||
ba06576c2d | |||
f259f03534 | |||
cf3a24afe8 | |||
2a180345eb | |||
345c9c59a3 | |||
5c4e9f30e0 | |||
d337413b82 | |||
5a5d7fecfd | |||
1ee86d378f | |||
cd52192d15 | |||
6260f35b61 | |||
79ad7fbc39 | |||
1bdcc7179c | |||
5ba18477b4 | |||
5f506bda8a | |||
bbec57c3ad | |||
58404b9728 | |||
8042aee951 | |||
0b07e8b8f6 | |||
7e73430179 | |||
cec3597629 | |||
ae29eaa52f | |||
b81ced33e8 | |||
87806397d1 | |||
d645aa9ea7 | |||
4288440e6c | |||
36b328c29e | |||
232ab164be | |||
a4890c0159 | |||
7bdf97411c | |||
3e9f14419c | |||
a21e9335aa | |||
1b415d7a7f | |||
c5acb2ca54 | |||
7a514fad2a | |||
125b687a9c | |||
07ed62cd9a | |||
7179d41e59 | |||
8279bfe9bf | |||
e45b72a655 | |||
cbdcf58063 | |||
d25e21619d | |||
2bfbeacdd0 | |||
88ec7a00da | |||
0c922c1695 | |||
e1dc8cafd9 | |||
e79e8de6dc | |||
f140fb870c | |||
3663bbb241 | |||
17f7dcdf12 |
@ -4,4 +4,6 @@
|
|||||||
.gitignore
|
.gitignore
|
||||||
Dockerfile
|
Dockerfile
|
||||||
.dockerignore
|
.dockerignore
|
||||||
|
docker-build.sh
|
||||||
.vs/
|
.vs/
|
||||||
|
.idea/
|
||||||
|
31
.editorconfig
Normal file
31
.editorconfig
Normal 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
|
29
.github/workflows/build.yml
vendored
29
.github/workflows/build.yml
vendored
@ -1,29 +0,0 @@
|
|||||||
name: dotnet build
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
- 'Dockerfile'
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: windows-latest
|
|
||||||
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
|
|
30
.github/workflows/server.yml
vendored
30
.github/workflows/server.yml
vendored
@ -1,30 +0,0 @@
|
|||||||
name: docker build
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths:
|
|
||||||
- '.github/workflows/server.yml'
|
|
||||||
- 'Pal.Common/**'
|
|
||||||
- 'Pal.Server/**'
|
|
||||||
- 'Dockerfile'
|
|
||||||
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
|
|
24
.github/workflows/upload-crowdin.yml
vendored
24
.github/workflows/upload-crowdin.yml
vendored
@ -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
6
.gitmodules
vendored
@ -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
|
||||||
|
10
Directory.Build.targets
Normal file
10
Directory.Build.targets
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||||
|
<WindowsKitsRoot Condition="'$(WindowsKitsRoot)' == ''">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots', 'KitsRoot10', null, RegistryView.Registry32, RegistryView.Default))</WindowsKitsRoot>
|
||||||
|
<SignToolPath Condition="'$(WindowsKitsRoot)' != '' And '$(SignToolPath)' == '' And exists('$(WindowsKitsRoot)bin\10.0.19041.0\')">$(WindowsKitsRoot)bin\10.0.19041.0\x86\</SignToolPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(SignToolPath)' != '' And Exists('$(SolutionDir)codesigning.pfx')">
|
||||||
|
<Exec Command=""$(SignToolPath)signtool.exe" sign /f $(SolutionDir)codesigning.pfx /t http://timestamp.digicert.com /fd SHA256 "$(TargetPath)""/>
|
||||||
|
</Target>
|
||||||
|
</Project>
|
16
Dockerfile
16
Dockerfile
@ -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=
|
||||||
|
9
Pal.Client/Commands/ISubCommand.cs
Normal file
9
Pal.Client/Commands/ISubCommand.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Pal.Client.Commands;
|
||||||
|
|
||||||
|
public interface ISubCommand
|
||||||
|
{
|
||||||
|
IReadOnlyDictionary<string, Action<string>> GetHandlers();
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
using Dalamud.Interface.Windowing;
|
using System;
|
||||||
|
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
|
internal class PalConfigCommand : ISubCommand
|
||||||
{
|
{
|
||||||
private readonly IPalacePalConfiguration _configuration;
|
private readonly IPalacePalConfiguration _configuration;
|
||||||
private readonly AgreementWindow _agreementWindow;
|
private readonly AgreementWindow _agreementWindow;
|
||||||
@ -20,6 +21,14 @@ namespace Pal.Client.Commands
|
|||||||
_configWindow = configWindow;
|
_configWindow = configWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IReadOnlyDictionary<string, Action<string>> GetHandlers()
|
||||||
|
=> new Dictionary<string, Action<string>>
|
||||||
|
{
|
||||||
|
{ "config", _ => Execute() },
|
||||||
|
{ "", _ => Execute() }
|
||||||
|
};
|
||||||
|
|
||||||
public void Execute()
|
public void Execute()
|
||||||
{
|
{
|
||||||
if (_configuration.FirstUse)
|
if (_configuration.FirstUse)
|
||||||
@ -28,4 +37,3 @@ namespace Pal.Client.Commands
|
|||||||
_configWindow.Toggle();
|
_configWindow.Toggle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
using System;
|
using System;
|
||||||
|
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
|
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;
|
||||||
@ -24,23 +25,14 @@ namespace Pal.Client.Commands
|
|||||||
_floorService = floorService;
|
_floorService = floorService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute(string arguments)
|
|
||||||
{
|
|
||||||
switch (arguments)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
DebugNearest(_ => true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "tnear":
|
public IReadOnlyDictionary<string, Action<string>> GetHandlers()
|
||||||
DebugNearest(m => m.Type == MemoryLocation.EType.Trap);
|
=> new Dictionary<string, Action<string>>
|
||||||
break;
|
{
|
||||||
|
{ "near", _ => DebugNearest(_ => true) },
|
||||||
case "hnear":
|
{ "tnear", _ => DebugNearest(m => m.Type == MemoryLocation.EType.Trap) },
|
||||||
DebugNearest(m => m.Type == MemoryLocation.EType.Hoard);
|
{ "hnear", _ => DebugNearest(m => m.Type == MemoryLocation.EType.Hoard) },
|
||||||
break;
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DebugNearest(Predicate<PersistentLocation> predicate)
|
private void DebugNearest(Predicate<PersistentLocation> predicate)
|
||||||
{
|
{
|
||||||
@ -54,11 +46,11 @@ namespace Pal.Client.Commands
|
|||||||
var playerPosition = _clientState.LocalPlayer?.Position;
|
var playerPosition = _clientState.LocalPlayer?.Position;
|
||||||
if (playerPosition == null)
|
if (playerPosition == null)
|
||||||
return;
|
return;
|
||||||
_chat.Message($"{playerPosition}");
|
_chat.Message($"Your position: {playerPosition}");
|
||||||
|
|
||||||
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)
|
||||||
@ -68,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}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Pal.Client.DependencyInjection;
|
using Pal.Client.DependencyInjection;
|
||||||
|
|
||||||
namespace Pal.Client.Commands
|
namespace Pal.Client.Commands;
|
||||||
{
|
|
||||||
internal sealed class PalStatsCommand
|
internal sealed class PalStatsCommand : ISubCommand
|
||||||
{
|
{
|
||||||
private readonly StatisticsService _statisticsService;
|
private readonly StatisticsService _statisticsService;
|
||||||
|
|
||||||
@ -12,7 +13,12 @@ namespace Pal.Client.Commands
|
|||||||
_statisticsService = statisticsService;
|
_statisticsService = statisticsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute()
|
public IReadOnlyDictionary<string, Action<string>> GetHandlers()
|
||||||
|
=> new Dictionary<string, Action<string>>
|
||||||
|
{
|
||||||
|
{ "stats", _ => Execute() },
|
||||||
|
};
|
||||||
|
|
||||||
|
private void Execute()
|
||||||
=> _statisticsService.ShowGlobalStatistics();
|
=> _statisticsService.ShowGlobalStatistics();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
using ECommons.Schedulers;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using ECommons.Schedulers;
|
||||||
using Pal.Client.Windows;
|
using Pal.Client.Windows;
|
||||||
|
|
||||||
namespace Pal.Client.Commands
|
namespace Pal.Client.Commands;
|
||||||
{
|
|
||||||
internal sealed class PalTestConnectionCommand
|
internal sealed class PalTestConnectionCommand : ISubCommand
|
||||||
{
|
{
|
||||||
private readonly ConfigWindow _configWindow;
|
private readonly ConfigWindow _configWindow;
|
||||||
|
|
||||||
@ -12,9 +14,16 @@ namespace Pal.Client.Commands
|
|||||||
_configWindow = configWindow;
|
_configWindow = configWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Execute()
|
public IReadOnlyDictionary<string, Action<string>> GetHandlers()
|
||||||
|
=> new Dictionary<string, Action<string>>
|
||||||
{
|
{
|
||||||
|
{ "test-connection", _ => Execute() },
|
||||||
|
{ "tc", _ => Execute() },
|
||||||
|
};
|
||||||
|
|
||||||
|
private void Execute()
|
||||||
|
{
|
||||||
|
_configWindow.IsOpen = true;
|
||||||
var _ = new TickScheduler(() => _configWindow.TestConnection());
|
var _ = new TickScheduler(() => _configWindow.TestConnection());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -2,19 +2,14 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Dalamud.Logging;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Pal.Client.DependencyInjection.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()
|
||||||
{
|
{
|
||||||
@ -77,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,4 +142,3 @@ namespace Pal.Client.Configuration
|
|||||||
ProtectedDataUnsupported = 3,
|
ProtectedDataUnsupported = 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
using Dalamud.Logging;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Pal.Client.DependencyInjection.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
|
||||||
@ -36,11 +32,9 @@ namespace Pal.Client.Configuration
|
|||||||
{
|
{
|
||||||
_supportsDpapi = false;
|
_supportsDpapi = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogTrace("DPAPI support: {Supported}", _supportsDpapi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _supportsDpapi.Value;
|
return _supportsDpapi.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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; }
|
||||||
@ -19,6 +19,7 @@ namespace Pal.Client.Configuration
|
|||||||
bool FirstUse { get; set; }
|
bool FirstUse { get; set; }
|
||||||
EMode Mode { get; set; }
|
EMode Mode { get; set; }
|
||||||
string BetaKey { get; }
|
string BetaKey { get; }
|
||||||
|
bool HasBetaFeature(string feature) => BetaKey.Contains(feature);
|
||||||
|
|
||||||
DeepDungeonConfiguration DeepDungeons { get; set; }
|
DeepDungeonConfiguration DeepDungeons { get; set; }
|
||||||
RendererConfiguration Renderer { get; set; }
|
RendererConfiguration Renderer { get; set; }
|
||||||
@ -56,6 +57,14 @@ namespace Pal.Client.Configuration
|
|||||||
OnlyVisibleAfterPomander = false,
|
OnlyVisibleAfterPomander = false,
|
||||||
Fill = true
|
Fill = true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public MarkerConfiguration GoldCoffers { get; set; } = new()
|
||||||
|
{
|
||||||
|
Show = false,
|
||||||
|
Color = ImGui.ColorConvertFloat4ToU32(new Vector4(1, 1, 0, 0.4f)),
|
||||||
|
OnlyVisibleAfterPomander = false,
|
||||||
|
Fill = true
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MarkerConfiguration
|
public class MarkerConfiguration
|
||||||
@ -99,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;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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.
|
||||||
@ -69,10 +69,12 @@ namespace Pal.Client
|
|||||||
_serviceProvider.GetRequiredService<ChatService>();
|
_serviceProvider.GetRequiredService<ChatService>();
|
||||||
|
|
||||||
// eager load any commands to find errors now, not when running them
|
// eager load any commands to find errors now, not when running them
|
||||||
_serviceProvider.GetRequiredService<PalConfigCommand>();
|
_serviceProvider.GetRequiredService<IEnumerable<ISubCommand>>();
|
||||||
_serviceProvider.GetRequiredService<PalNearCommand>();
|
|
||||||
_serviceProvider.GetRequiredService<PalStatsCommand>();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
_serviceProvider.GetRequiredService<PalTestConnectionCommand>();
|
|
||||||
|
if (_serviceProvider.GetRequiredService<IPalacePalConfiguration>().HasBetaFeature(ObjectTableDebug.FeatureName))
|
||||||
|
_serviceProvider.GetRequiredService<ObjectTableDebug>();
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
@ -82,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",
|
||||||
@ -114,7 +116,7 @@ namespace Pal.Client
|
|||||||
|
|
||||||
var toDelete = backupFiles.OrderByDescending(x => x.Date)
|
var toDelete = backupFiles.OrderByDescending(x => x.Date)
|
||||||
.Skip(configuration.Backups.MinimumBackupsToKeep)
|
.Skip(configuration.Backups.MinimumBackupsToKeep)
|
||||||
.Where(x => (DateTime.Today.ToUniversalTime() - x.Date).Days > configuration.Backups.DaysToDeleteAfter)
|
.Where(x => (DateTime.Now.ToUniversalTime() - x.Date).Days > configuration.Backups.DaysToDeleteAfter)
|
||||||
.Select(x => x.Path);
|
.Select(x => x.Path);
|
||||||
foreach (var path in toDelete)
|
foreach (var path in toDelete)
|
||||||
{
|
{
|
||||||
@ -134,24 +136,31 @@ 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.Today.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(),
|
||||||
DependencyInjectionContext.DatabaseFileName);
|
DependencyInjectionContext.DatabaseFileName);
|
||||||
if (File.Exists(sourcePath) && !File.Exists(backupPath))
|
if (File.Exists(sourcePath) && !File.Exists(backupPath))
|
||||||
{
|
{
|
||||||
if (File.Exists(sourcePath + "-shm") || File.Exists(sourcePath + "-wal"))
|
|
||||||
{
|
|
||||||
_logger.LogWarning("Could not create backup, database is open in another program");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogInformation("Creating database backup '{Path}'", backupPath);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (File.Exists(sourcePath + "-shm") || File.Exists(sourcePath + "-wal"))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Creating database backup '{Path}' (open db)", backupPath);
|
||||||
|
await using var db = scope.ServiceProvider.GetRequiredService<PalClientContext>();
|
||||||
|
await using SqliteConnection source = new(db.Database.GetConnectionString());
|
||||||
|
await source.OpenAsync();
|
||||||
|
await using SqliteConnection backup = new($"Data Source={backupPath}");
|
||||||
|
source.BackupDatabase(backup);
|
||||||
|
SqliteConnection.ClearPool(backup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Creating database backup '{Path}' (file copy)", backupPath);
|
||||||
File.Copy(sourcePath, backupPath);
|
File.Copy(sourcePath, backupPath);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.LogError(e, "Could not create backup");
|
_logger.LogError(e, "Could not create backup");
|
||||||
@ -184,4 +193,3 @@ namespace Pal.Client
|
|||||||
await dbContext.SaveChangesAsync();
|
await dbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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+)$");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Pal.Client.DependencyInjection.Logging
|
|
||||||
{
|
|
||||||
internal sealed class DalamudLogger : ILogger
|
|
||||||
{
|
|
||||||
private static readonly string AssemblyName = typeof(Plugin).Assembly.GetName().Name!;
|
|
||||||
private static readonly Serilog.ILogger PluginLogDelegate = Serilog.Log.ForContext("SourceContext", AssemblyName);
|
|
||||||
private readonly string _name;
|
|
||||||
private readonly IExternalScopeProvider? _scopeProvider;
|
|
||||||
|
|
||||||
public DalamudLogger(string name, IExternalScopeProvider? scopeProvider)
|
|
||||||
{
|
|
||||||
_name = name;
|
|
||||||
_scopeProvider = scopeProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDisposable BeginScope<TState>(TState state)
|
|
||||||
where TState : notnull
|
|
||||||
=> _scopeProvider?.Push(state) ?? NullScope.Instance;
|
|
||||||
|
|
||||||
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None && IsEnabled(ToSerilogLevel(logLevel));
|
|
||||||
|
|
||||||
private bool IsEnabled(LogEventLevel logEventLevel) => PluginLogDelegate.IsEnabled(logEventLevel);
|
|
||||||
|
|
||||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception,
|
|
||||||
Func<TState, Exception?, string> formatter)
|
|
||||||
{
|
|
||||||
if (logLevel == LogLevel.None)
|
|
||||||
return;
|
|
||||||
|
|
||||||
LogEventLevel logEventLevel = ToSerilogLevel(logLevel);
|
|
||||||
if (!IsEnabled(logEventLevel))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (formatter == null)
|
|
||||||
throw new ArgumentNullException(nameof(formatter));
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.Append('[').Append(AssemblyName).Append("] ");
|
|
||||||
_scopeProvider?.ForEachScope((scope, builder) =>
|
|
||||||
{
|
|
||||||
if (scope is IEnumerable<KeyValuePair<string, object>> properties)
|
|
||||||
{
|
|
||||||
foreach (KeyValuePair<string, object> pair in properties)
|
|
||||||
{
|
|
||||||
builder.Append('<').Append(pair.Key).Append('=').Append(pair.Value)
|
|
||||||
.Append("> ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (scope != null)
|
|
||||||
builder.Append('<').Append(scope).Append("> ");
|
|
||||||
},
|
|
||||||
sb);
|
|
||||||
sb.Append(_name).Append(": ").Append(formatter(state, null));
|
|
||||||
PluginLogDelegate.Write(logEventLevel, exception, sb.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private LogEventLevel ToSerilogLevel(LogLevel logLevel)
|
|
||||||
{
|
|
||||||
return logLevel switch
|
|
||||||
{
|
|
||||||
LogLevel.Critical => LogEventLevel.Fatal,
|
|
||||||
LogLevel.Error => LogEventLevel.Error,
|
|
||||||
LogLevel.Warning => LogEventLevel.Warning,
|
|
||||||
LogLevel.Information => LogEventLevel.Information,
|
|
||||||
LogLevel.Debug => LogEventLevel.Debug,
|
|
||||||
LogLevel.Trace => LogEventLevel.Verbose,
|
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(logLevel), logLevel, null)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class NullScope : IDisposable
|
|
||||||
{
|
|
||||||
public static NullScope Instance { get; } = new();
|
|
||||||
|
|
||||||
private NullScope()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Pal.Client.DependencyInjection.Logging
|
|
||||||
{
|
|
||||||
internal sealed class DalamudLoggerProvider : ILoggerProvider, ISupportExternalScope
|
|
||||||
{
|
|
||||||
private IExternalScopeProvider? _scopeProvider;
|
|
||||||
|
|
||||||
public ILogger CreateLogger(string categoryName) => new DalamudLogger(categoryName, _scopeProvider);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Manual logger creation, doesn't handle scopes.
|
|
||||||
/// </summary>
|
|
||||||
public ILogger CreateLogger(Type type) => CreateLogger(type.FullName ?? type.ToString());
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Manual logger creation, doesn't handle scopes.
|
|
||||||
/// </summary>
|
|
||||||
public ILogger CreateLogger<T>() => CreateLogger(typeof(T));
|
|
||||||
|
|
||||||
public void SetScopeProvider(IExternalScopeProvider scopeProvider)
|
|
||||||
{
|
|
||||||
_scopeProvider = scopeProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,21 +6,22 @@ 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 InvalidOperationException();
|
throw new RepoVerificationFailedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal sealed class RepoVerificationFailedException : Exception
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,25 +2,32 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Dalamud.Game.Gui;
|
using Dalamud.Game.Gui;
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Pal.Client.Configuration;
|
using Pal.Client.Configuration;
|
||||||
using Pal.Client.Extensions;
|
using Pal.Client.Extensions;
|
||||||
using Pal.Client.Net;
|
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;
|
||||||
|
private readonly ILogger<StatisticsService> _logger;
|
||||||
private readonly RemoteApi _remoteApi;
|
private readonly RemoteApi _remoteApi;
|
||||||
private readonly StatisticsWindow _statisticsWindow;
|
private readonly StatisticsWindow _statisticsWindow;
|
||||||
private readonly Chat _chat;
|
private readonly Chat _chat;
|
||||||
|
|
||||||
public StatisticsService(IPalacePalConfiguration configuration, RemoteApi remoteApi,
|
public StatisticsService(
|
||||||
StatisticsWindow statisticsWindow, Chat chat)
|
IPalacePalConfiguration configuration,
|
||||||
|
ILogger<StatisticsService> logger,
|
||||||
|
RemoteApi remoteApi,
|
||||||
|
StatisticsWindow statisticsWindow,
|
||||||
|
Chat chat)
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
|
_logger = logger;
|
||||||
_remoteApi = remoteApi;
|
_remoteApi = remoteApi;
|
||||||
_statisticsWindow = statisticsWindow;
|
_statisticsWindow = statisticsWindow;
|
||||||
_chat = chat;
|
_chat = chat;
|
||||||
@ -32,6 +39,8 @@ namespace Pal.Client.DependencyInjection
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task FetchFloorStatistics()
|
private async Task FetchFloorStatistics()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (!_configuration.HasRoleOnCurrentServer(RemoteApi.RemoteUrl, "statistics:view"))
|
if (!_configuration.HasRoleOnCurrentServer(RemoteApi.RemoteUrl, "statistics:view"))
|
||||||
{
|
{
|
||||||
@ -39,8 +48,6 @@ namespace Pal.Client.DependencyInjection
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var (success, floorStatistics) = await _remoteApi.FetchStatistics();
|
var (success, floorStatistics) = await _remoteApi.FetchStatistics();
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
@ -54,12 +61,14 @@ namespace Pal.Client.DependencyInjection
|
|||||||
}
|
}
|
||||||
catch (RpcException e) when (e.StatusCode == StatusCode.PermissionDenied)
|
catch (RpcException e) when (e.StatusCode == StatusCode.PermissionDenied)
|
||||||
{
|
{
|
||||||
|
_logger.LogWarning(e, "Access denied while fetching floor statistics");
|
||||||
_chat.Error(Localization.Command_pal_stats_CurrentFloor);
|
_chat.Error(Localization.Command_pal_stats_CurrentFloor);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_chat.Error(e.ToString());
|
_logger.LogError(e, "Could not fetch floor statistics");
|
||||||
}
|
_chat.Error(string.Format(Localization.Error_CommandFailed,
|
||||||
|
$"{e.GetType()} - {e.Message}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Dalamud.Data;
|
using Dalamud.Data;
|
||||||
|
using Dalamud.Extensions.MicrosoftLogging;
|
||||||
using Dalamud.Game;
|
using Dalamud.Game;
|
||||||
using Dalamud.Game.ClientState;
|
using Dalamud.Game.ClientState;
|
||||||
using Dalamud.Game.ClientState.Conditions;
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
@ -9,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;
|
||||||
@ -18,47 +20,46 @@ using Pal.Client.Configuration;
|
|||||||
using Pal.Client.Configuration.Legacy;
|
using Pal.Client.Configuration.Legacy;
|
||||||
using Pal.Client.Database;
|
using Pal.Client.Database;
|
||||||
using Pal.Client.DependencyInjection;
|
using Pal.Client.DependencyInjection;
|
||||||
using Pal.Client.DependencyInjection.Logging;
|
|
||||||
using Pal.Client.Floors;
|
using Pal.Client.Floors;
|
||||||
using Pal.Client.Net;
|
using Pal.Client.Net;
|
||||||
using Pal.Client.Properties;
|
|
||||||
using Pal.Client.Rendering;
|
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();
|
|
||||||
|
|
||||||
/// <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 string Name => Localization.Palace_Pal;
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@ -73,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()
|
||||||
.AddProvider(LoggerProvider));
|
.AddDalamudLogger(pluginLog));
|
||||||
|
|
||||||
// dalamud
|
// dalamud
|
||||||
_serviceCollection.AddSingleton<IDalamudPlugin>(plugin);
|
_serviceCollection.AddSingleton<IDalamudPlugin>(plugin);
|
||||||
@ -87,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 =
|
||||||
@ -117,9 +119,10 @@ namespace Pal.Client
|
|||||||
|
|
||||||
// commands
|
// commands
|
||||||
_serviceCollection.AddScoped<PalConfigCommand>();
|
_serviceCollection.AddScoped<PalConfigCommand>();
|
||||||
_serviceCollection.AddScoped<PalNearCommand>();
|
_serviceCollection.AddScoped<ISubCommand, PalConfigCommand>();
|
||||||
_serviceCollection.AddScoped<PalStatsCommand>();
|
_serviceCollection.AddScoped<ISubCommand, PalNearCommand>();
|
||||||
_serviceCollection.AddScoped<PalTestConnectionCommand>();
|
_serviceCollection.AddScoped<ISubCommand, PalStatsCommand>();
|
||||||
|
_serviceCollection.AddScoped<ISubCommand, PalTestConnectionCommand>();
|
||||||
|
|
||||||
// territory & marker related services
|
// territory & marker related services
|
||||||
_serviceCollection.AddScoped<TerritoryState>();
|
_serviceCollection.AddScoped<TerritoryState>();
|
||||||
@ -127,6 +130,7 @@ namespace Pal.Client
|
|||||||
_serviceCollection.AddScoped<ChatService>();
|
_serviceCollection.AddScoped<ChatService>();
|
||||||
_serviceCollection.AddScoped<FloorService>();
|
_serviceCollection.AddScoped<FloorService>();
|
||||||
_serviceCollection.AddScoped<ImportService>();
|
_serviceCollection.AddScoped<ImportService>();
|
||||||
|
_serviceCollection.AddScoped<ObjectTableDebug>();
|
||||||
|
|
||||||
// windows & related services
|
// windows & related services
|
||||||
_serviceCollection.AddScoped<AgreementWindow>();
|
_serviceCollection.AddScoped<AgreementWindow>();
|
||||||
@ -188,4 +192,3 @@ namespace Pal.Client
|
|||||||
SqliteConnection.ClearPool(sqliteConnection);
|
SqliteConnection.ClearPool(sqliteConnection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
@ -110,6 +108,12 @@ namespace Pal.Client.Floors
|
|||||||
if (!_territoryState.IsInDeepDungeon() || !_floorService.IsReady(_territoryState.LastTerritory))
|
if (!_territoryState.IsInDeepDungeon() || !_floorService.IsReady(_territoryState.LastTerritory))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (_renderAdapter.RequireRedraw)
|
||||||
|
{
|
||||||
|
recreateLayout = true;
|
||||||
|
_renderAdapter.RequireRedraw = false;
|
||||||
|
}
|
||||||
|
|
||||||
ETerritoryType territoryType = (ETerritoryType)_territoryState.LastTerritory;
|
ETerritoryType territoryType = (ETerritoryType)_territoryState.LastTerritory;
|
||||||
MemoryTerritory memoryTerritory = _floorService.GetTerritoryIfReady(territoryType)!;
|
MemoryTerritory memoryTerritory = _floorService.GetTerritoryIfReady(territoryType)!;
|
||||||
if (_configuration.Mode == EMode.Online && memoryTerritory.SyncState == ESyncState.NotAttempted)
|
if (_configuration.Mode == EMode.Online && memoryTerritory.SyncState == ESyncState.NotAttempted)
|
||||||
@ -171,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)
|
||||||
@ -221,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -247,8 +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 &&
|
||||||
|
_configuration.DeepDungeons.GoldCoffers.Show)
|
||||||
|
{
|
||||||
|
CreateRenderElement(location, elements, true, _configuration.DeepDungeons.GoldCoffers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,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)
|
||||||
{
|
{
|
||||||
@ -266,32 +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,
|
||||||
{
|
|
||||||
if (location.Type == MemoryLocation.EType.SilverCoffer)
|
|
||||||
return _configuration.DeepDungeons.SilverCoffers.Color;
|
|
||||||
|
|
||||||
return 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);
|
||||||
}
|
}
|
||||||
@ -371,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;
|
||||||
|
|
||||||
@ -383,6 +395,7 @@ namespace Pal.Client.Floors
|
|||||||
case 2007185:
|
case 2007185:
|
||||||
case 2007186:
|
case 2007186:
|
||||||
case 2009504:
|
case 2009504:
|
||||||
|
case 2013284:
|
||||||
persistentLocations.Add(new PersistentLocation
|
persistentLocations.Add(new PersistentLocation
|
||||||
{
|
{
|
||||||
Type = MemoryLocation.EType.Trap,
|
Type = MemoryLocation.EType.Trap,
|
||||||
@ -411,6 +424,15 @@ namespace Pal.Client.Floors
|
|||||||
Seen = true,
|
Seen = true,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 2007358:
|
||||||
|
ephemeralLocations.Add(new EphemeralLocation
|
||||||
|
{
|
||||||
|
Type = MemoryLocation.EType.GoldCoffer,
|
||||||
|
Position = obj.Position,
|
||||||
|
Seen = true
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,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,
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -441,4 +462,3 @@ namespace Pal.Client.Floors
|
|||||||
handler.RunIfCompatible(queued, ref recreateLayout);
|
handler.RunIfCompatible(queued, ref recreateLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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>
|
||||||
@ -26,6 +26,7 @@ namespace Pal.Client.Floors
|
|||||||
Hoard,
|
Hoard,
|
||||||
|
|
||||||
SilverCoffer,
|
SilverCoffer,
|
||||||
|
GoldCoffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
public override bool Equals(object? obj)
|
||||||
@ -63,4 +64,3 @@ namespace Pal.Client.Floors
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
99
Pal.Client/Floors/ObjectTableDebug.cs
Normal file
99
Pal.Client/Floors/ObjectTableDebug.cs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Dalamud.Plugin.Services;
|
||||||
|
using ImGuiNET;
|
||||||
|
|
||||||
|
namespace Pal.Client.Floors;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This isn't very useful for running deep dungeons normally, but it is for plugin dev.
|
||||||
|
///
|
||||||
|
/// Needs the corresponding beta feature to be enabled.
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class ObjectTableDebug : IDisposable
|
||||||
|
{
|
||||||
|
public const string FeatureName = nameof(ObjectTableDebug);
|
||||||
|
|
||||||
|
private readonly IDalamudPluginInterface _pluginInterface;
|
||||||
|
private readonly IObjectTable _objectTable;
|
||||||
|
private readonly IGameGui _gameGui;
|
||||||
|
private readonly IClientState _clientState;
|
||||||
|
|
||||||
|
public ObjectTableDebug(IDalamudPluginInterface pluginInterface, IObjectTable objectTable, IGameGui gameGui,
|
||||||
|
IClientState clientState)
|
||||||
|
{
|
||||||
|
_pluginInterface = pluginInterface;
|
||||||
|
_objectTable = objectTable;
|
||||||
|
_gameGui = gameGui;
|
||||||
|
_clientState = clientState;
|
||||||
|
|
||||||
|
_pluginInterface.UiBuilder.Draw += Draw;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Draw()
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
foreach (IGameObject obj in _objectTable)
|
||||||
|
{
|
||||||
|
if (obj is IEventObj eventObj && string.IsNullOrEmpty(eventObj.Name.ToString()))
|
||||||
|
{
|
||||||
|
++index;
|
||||||
|
int model = Marshal.ReadInt32(obj.Address + 128);
|
||||||
|
|
||||||
|
if (_gameGui.WorldToScreen(obj.Position, out var screenCoords))
|
||||||
|
{
|
||||||
|
// So, while WorldToScreen will return false if the point is off of game client screen, to
|
||||||
|
// to avoid performance issues, we have to manually determine if creating a window would
|
||||||
|
// produce a new viewport, and skip rendering it if so
|
||||||
|
float distance = DistanceToPlayer(obj.Position);
|
||||||
|
var objectText =
|
||||||
|
$"{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 screenSize = ImGui.GetMainViewport().Size;
|
||||||
|
|
||||||
|
var windowSize = ImGui.CalcTextSize(objectText);
|
||||||
|
|
||||||
|
// Add some extra safety padding
|
||||||
|
windowSize.X += ImGui.GetStyle().WindowPadding.X + 10;
|
||||||
|
windowSize.Y += ImGui.GetStyle().WindowPadding.Y + 10;
|
||||||
|
|
||||||
|
if (screenCoords.X + windowSize.X > screenPos.X + screenSize.X ||
|
||||||
|
screenCoords.Y + windowSize.Y > screenPos.Y + screenSize.Y)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (distance > 50f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ImGui.SetNextWindowPos(new Vector2(screenCoords.X, screenCoords.Y));
|
||||||
|
|
||||||
|
ImGui.SetNextWindowBgAlpha(Math.Max(1f - (distance / 50f), 0.2f));
|
||||||
|
if (ImGui.Begin(
|
||||||
|
$"PalacePal_{nameof(ObjectTableDebug)}_{index}",
|
||||||
|
ImGuiWindowFlags.NoDecoration |
|
||||||
|
ImGuiWindowFlags.AlwaysAutoResize |
|
||||||
|
ImGuiWindowFlags.NoSavedSettings |
|
||||||
|
ImGuiWindowFlags.NoMove |
|
||||||
|
ImGuiWindowFlags.NoMouseInputs |
|
||||||
|
ImGuiWindowFlags.NoDocking |
|
||||||
|
ImGuiWindowFlags.NoFocusOnAppearing |
|
||||||
|
ImGuiWindowFlags.NoNav))
|
||||||
|
ImGui.Text(objectText);
|
||||||
|
ImGui.End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float DistanceToPlayer(Vector3 center)
|
||||||
|
=> Vector3.Distance(_clientState.LocalPlayer?.Position ?? Vector3.Zero, center);
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_pluginInterface.UiBuilder.Draw -= Draw;
|
||||||
|
}
|
||||||
|
}
|
@ -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})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
using System.Threading.Tasks;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
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>
|
||||||
{
|
{
|
||||||
@ -18,15 +19,28 @@ namespace Pal.Client.Floors.Tasks
|
|||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
{
|
||||||
|
logger.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);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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,13 +24,14 @@ 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();
|
||||||
dbContext.Locations
|
dbContext.Locations
|
||||||
.Where(loc => _locations.Any(l => l.LocalId == loc.LocalId))
|
.Where(loc => localIds.Contains(loc.LocalId))
|
||||||
.ExecuteUpdate(loc => loc.SetProperty(l => l.Seen, true));
|
.ExecuteUpdate(loc => loc.SetProperty(l => l.Seen, true));
|
||||||
dbContext.SaveChanges();
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
21
Pal.Client/Net/JwtDateConverter.cs
Normal file
21
Pal.Client/Net/JwtDateConverter.cs
Normal 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();
|
||||||
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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,28 +23,26 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DalamudPackager" Version="2.1.10" />
|
<PackageReference Include="Dalamud.Extensions.MicrosoftLogging" Version="4.0.1"/>
|
||||||
<PackageReference Include="Google.Protobuf" Version="3.21.12" />
|
<PackageReference Include="Google.Protobuf" Version="3.27.2" />
|
||||||
<PackageReference Include="Grpc.Net.Client" Version="2.51.0" />
|
<PackageReference Include="Grpc.Net.Client" Version="2.63.0"/>
|
||||||
<PackageReference Include="GitInfo" Version="2.3.0">
|
<PackageReference Include="Grpc.Tools" Version="2.64.0">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Grpc.Tools" Version="2.51.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>
|
||||||
@ -66,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>
|
||||||
@ -114,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 "$(OutDir)$(AssemblyName)\latest.zip" "$(AssemblyName)-$(Version).zip"" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="Clean">
|
<Target Name="Clean">
|
||||||
<RemoveDir Directories="dist"/>
|
<RemoveDir Directories="dist"/>
|
||||||
</Target>
|
</Target>
|
||||||
|
@ -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"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,27 @@
|
|||||||
using Dalamud.Interface.Windowing;
|
using System;
|
||||||
using Dalamud.Plugin;
|
using System.Collections.Generic;
|
||||||
using Pal.Client.Rendering;
|
|
||||||
using System;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
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 Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
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 .
|
||||||
@ -29,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);
|
||||||
@ -65,11 +69,13 @@ namespace Pal.Client
|
|||||||
HelpMessage = Localization.Command_pal_HelpText
|
HelpMessage = Localization.Command_pal_HelpText
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Using TickScheduler requires ECommons to at least be partially initialized
|
||||||
|
// ECommonsMain.Dispose leaves this untouched.
|
||||||
|
Svc.Init(pluginInterface);
|
||||||
|
|
||||||
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
|
||||||
@ -96,12 +102,10 @@ namespace Pal.Client
|
|||||||
_rootScopeCompletionSource.SetResult(_rootScope);
|
_rootScopeCompletionSource.SetResult(_rootScope);
|
||||||
_loadState = ELoadState.Loaded;
|
_loadState = ELoadState.Loaded;
|
||||||
}
|
}
|
||||||
catch (ObjectDisposedException e)
|
catch (Exception e) when (e is ObjectDisposedException
|
||||||
{
|
or OperationCanceledException
|
||||||
_rootScopeCompletionSource.SetException(e);
|
or RepoVerification.RepoVerificationFailedException
|
||||||
_loadState = ELoadState.Error;
|
|| (e is FileLoadException && _pluginInterface.IsDev))
|
||||||
}
|
|
||||||
catch (OperationCanceledException e)
|
|
||||||
{
|
{
|
||||||
_rootScopeCompletionSource.SetException(e);
|
_rootScopeCompletionSource.SetException(e);
|
||||||
_loadState = ELoadState.Error;
|
_loadState = ELoadState.Error;
|
||||||
@ -129,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;
|
||||||
@ -142,9 +146,12 @@ namespace Pal.Client
|
|||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
IServiceScope rootScope;
|
IServiceScope rootScope;
|
||||||
|
Chat chat;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
rootScope = await _rootScopeCompletionSource.Task;
|
rootScope = await _rootScopeCompletionSource.Task;
|
||||||
|
chat = rootScope.ServiceProvider.GetRequiredService<Chat>();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -152,50 +159,34 @@ namespace Pal.Client
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
IPalacePalConfiguration configuration =
|
IPalacePalConfiguration configuration =
|
||||||
rootScope.ServiceProvider.GetRequiredService<IPalacePalConfiguration>();
|
rootScope.ServiceProvider.GetRequiredService<IPalacePalConfiguration>();
|
||||||
Chat chat = rootScope.ServiceProvider.GetRequiredService<Chat>();
|
|
||||||
if (configuration.FirstUse && arguments != "" && arguments != "config")
|
if (configuration.FirstUse && arguments != "" && arguments != "config")
|
||||||
{
|
{
|
||||||
chat.Error(Localization.Error_FirstTimeSetupRequired);
|
chat.Error(Localization.Error_FirstTimeSetupRequired);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
Action<string> commandHandler = rootScope.ServiceProvider
|
||||||
|
.GetRequiredService<IEnumerable<ISubCommand>>()
|
||||||
|
.SelectMany(cmd => cmd.GetHandlers())
|
||||||
|
.Where(cmd => cmd.Key == arguments.ToLowerInvariant())
|
||||||
|
.Select(cmd => cmd.Value)
|
||||||
|
.SingleOrDefault(missingCommand =>
|
||||||
{
|
{
|
||||||
var sp = rootScope.ServiceProvider;
|
chat.Error(string.Format(Localization.Command_pal_UnknownSubcommand, missingCommand,
|
||||||
|
|
||||||
switch (arguments)
|
|
||||||
{
|
|
||||||
case "":
|
|
||||||
case "config":
|
|
||||||
sp.GetRequiredService<PalConfigCommand>().Execute();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "stats":
|
|
||||||
sp.GetRequiredService<PalStatsCommand>().Execute();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "tc":
|
|
||||||
case "test-connection":
|
|
||||||
sp.GetRequiredService<PalTestConnectionCommand>().Execute();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "near":
|
|
||||||
case "tnear":
|
|
||||||
case "hnear":
|
|
||||||
sp.GetRequiredService<PalNearCommand>().Execute(arguments);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
chat.Error(string.Format(Localization.Command_pal_UnknownSubcommand, arguments,
|
|
||||||
command));
|
command));
|
||||||
break;
|
});
|
||||||
}
|
commandHandler.Invoke(arguments);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
chat.Error(e.ToString());
|
_logger.LogError(e, "Could not execute command '{Command}' with arguments '{Arguments}'", command,
|
||||||
|
arguments);
|
||||||
|
chat.Error(string.Format(Localization.Error_CommandFailed,
|
||||||
|
$"{e.GetType()} - {e.Message}"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -242,4 +233,3 @@ namespace Pal.Client
|
|||||||
Error
|
Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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)]
|
|
48
Pal.Client/Properties/Localization.Designer.cs
generated
48
Pal.Client/Properties/Localization.Designer.cs
generated
@ -176,6 +176,43 @@ namespace Pal.Client.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Gold Coffer color.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Config_GoldCoffer_Color {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Config_GoldCoffer_Color", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Draw filled.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Config_GoldCoffer_Filled {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Config_GoldCoffer_Filled", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Show gold coffers on current floor.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Config_GoldCoffer_Show {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Config_GoldCoffer_Show", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Shows nearby gold coffers (containing pomanders) on the current floor.
|
||||||
|
///This is not synchronized with other players and not saved between floors/runs..
|
||||||
|
/// </summary>
|
||||||
|
internal static string Config_GoldCoffers_ToolTip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Config_GoldCoffers_ToolTip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Hoard Coffer color.
|
/// Looks up a localized string similar to Hoard Coffer color.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -357,7 +394,7 @@ namespace Pal.Client.Properties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Shows all the silver coffers visible to you on the current floor.
|
/// Looks up a localized string similar to Shows nearby silver coffers (gear upgrades and magicites) on the current floor.
|
||||||
///This is not synchronized with other players and not saved between floors/runs..
|
///This is not synchronized with other players and not saved between floors/runs..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string Config_SilverCoffers_ToolTip {
|
internal static string Config_SilverCoffers_ToolTip {
|
||||||
@ -619,6 +656,15 @@ namespace Pal.Client.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Command could not be executed: {0}.
|
||||||
|
/// </summary>
|
||||||
|
internal static string Error_CommandFailed {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Error_CommandFailed", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Please finish the initial setup first..
|
/// Looks up a localized string similar to Please finish the initial setup first..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -18,10 +18,39 @@
|
|||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<!-- Common -->
|
<!-- Common -->
|
||||||
|
<data name="PalaceOfTheDead" xml:space="preserve">
|
||||||
|
<value>Palast der Toten</value>
|
||||||
|
</data>
|
||||||
|
<data name="HeavenOnHigh" xml:space="preserve">
|
||||||
|
<value>Himmelssäule</value>
|
||||||
|
</data>
|
||||||
|
<data name="Save" xml:space="preserve">
|
||||||
|
<value>Speichern</value>
|
||||||
|
</data>
|
||||||
|
<data name="SaveAndClose" xml:space="preserve">
|
||||||
|
<value>Speichern & Schließen</value>
|
||||||
|
</data>
|
||||||
<!-- Generic Errors -->
|
<!-- Generic Errors -->
|
||||||
<!-- /pal commands -->
|
<!-- /pal commands -->
|
||||||
<!-- Messages while connecting to the server. These are typically only visible when clicking 'Test connection'. -->
|
<!-- Messages while connecting to the server. These are typically only visible when clicking 'Test connection'. -->
|
||||||
|
<data name="ConnectionSuccessful" xml:space="preserve">
|
||||||
|
<value>Verbindung erfolgreich.</value>
|
||||||
|
</data>
|
||||||
|
<data name="ConnectionError_NotOnline" xml:space="preserve">
|
||||||
|
<value>Sie sind nicht online.</value>
|
||||||
|
<comment>Shown if you attempt to connect to the server while you have selected 'never upload discoveries, only show traps and coffers i found myself'</comment>
|
||||||
|
</data>
|
||||||
|
<data name="ConnectionError_OldVersion" xml:space="preserve">
|
||||||
|
<value>Ihre Version von Palace Pal ist veraltet, bitte aktualisieren Sie das Plugin mit Hilfe des Plugin Installers.</value>
|
||||||
|
<comment>Shown if the version is too old to create an account or log in.</comment>
|
||||||
|
</data>
|
||||||
<!-- Config Window: Deep Dungeons -->
|
<!-- Config Window: Deep Dungeons -->
|
||||||
|
<data name="ConfigTab_DeepDungeons" xml:space="preserve">
|
||||||
|
<value>Tiefe Gewölbe</value>
|
||||||
|
</data>
|
||||||
|
<data name="Config_Traps_Show" xml:space="preserve">
|
||||||
|
<value>Fallen anzeigen</value>
|
||||||
|
</data>
|
||||||
<!-- Config Window: Community -->
|
<!-- Config Window: Community -->
|
||||||
<!-- Config Window: Import -->
|
<!-- Config Window: Import -->
|
||||||
<!-- Config Window: Export -->
|
<!-- Config Window: Export -->
|
||||||
|
@ -142,6 +142,20 @@
|
|||||||
<value>塗りつぶす</value>
|
<value>塗りつぶす</value>
|
||||||
<comment>Whether silver coffers should only be drawn with the circle outline or as filled circle.</comment>
|
<comment>Whether silver coffers should only be drawn with the circle outline or as filled circle.</comment>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Config_GoldCoffer_Show" xml:space="preserve">
|
||||||
|
<value>金の宝箱を表示</value>
|
||||||
|
</data>
|
||||||
|
<data name="Config_GoldCoffers_ToolTip" xml:space="preserve">
|
||||||
|
<value>現在のフロアにある全ての金の宝箱を表示します。
|
||||||
|
これは他のプレイヤーと同期されず、データは保存されません。</value>
|
||||||
|
</data>
|
||||||
|
<data name="Config_GoldCoffer_Color" xml:space="preserve">
|
||||||
|
<value>金の宝箱の色</value>
|
||||||
|
</data>
|
||||||
|
<data name="Config_GoldCoffer_Filled" xml:space="preserve">
|
||||||
|
<value>塗りつぶす</value>
|
||||||
|
<comment>Whether gold coffers should only be drawn with the circle outline or as filled circle.</comment>
|
||||||
|
</data>
|
||||||
<!-- Config Window: Community -->
|
<!-- Config Window: Community -->
|
||||||
<data name="ConfigTab_Community" xml:space="preserve">
|
<data name="ConfigTab_Community" xml:space="preserve">
|
||||||
<value>コミュニティ</value>
|
<value>コミュニティ</value>
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
</data>
|
</data>
|
||||||
<data name="Error_LoadFailed" xml:space="preserve">
|
<data name="Error_LoadFailed" xml:space="preserve">
|
||||||
<value>Plugin could not be loaded: {0}</value>
|
<value>Plugin could not be loaded: {0}</value>
|
||||||
|
<comment>Shown when the plugin fails to load, with the placeholder filled with the exception message.</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error_WrongRepository" xml:space="preserve">
|
<data name="Error_WrongRepository" xml:space="preserve">
|
||||||
<value>Please install this plugin from the official repository at {0} to continue using it.</value>
|
<value>Please install this plugin from the official repository at {0} to continue using it.</value>
|
||||||
@ -69,6 +70,10 @@
|
|||||||
<value>Unable to fetch statistics.</value>
|
<value>Unable to fetch statistics.</value>
|
||||||
<comment>Shown when /pal stats produces a server-side error, and the statistics window can't be loaded.</comment>
|
<comment>Shown when /pal stats produces a server-side error, and the statistics window can't be loaded.</comment>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Error_CommandFailed" xml:space="preserve">
|
||||||
|
<value>Command could not be executed: {0}</value>
|
||||||
|
<comment>Shown when '/pal ...' fails, with the placeholder filled with the exception message.</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
<!-- Messages while connecting to the server. These are typically only visible when clicking 'Test connection'. -->
|
<!-- Messages while connecting to the server. These are typically only visible when clicking 'Test connection'. -->
|
||||||
<data name="ConnectionSuccessful" xml:space="preserve">
|
<data name="ConnectionSuccessful" xml:space="preserve">
|
||||||
@ -141,7 +146,7 @@ When using a Pomander of Safety, all traps are hidden.</value>
|
|||||||
<value>Show silver coffers on current floor</value>
|
<value>Show silver coffers on current floor</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Config_SilverCoffers_ToolTip" xml:space="preserve">
|
<data name="Config_SilverCoffers_ToolTip" xml:space="preserve">
|
||||||
<value>Shows all the silver coffers visible to you on the current floor.
|
<value>Shows nearby silver coffers (gear upgrades and magicites) on the current floor.
|
||||||
This is not synchronized with other players and not saved between floors/runs.</value>
|
This is not synchronized with other players and not saved between floors/runs.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Config_SilverCoffer_Color" xml:space="preserve">
|
<data name="Config_SilverCoffer_Color" xml:space="preserve">
|
||||||
@ -151,6 +156,20 @@ This is not synchronized with other players and not saved between floors/runs.</
|
|||||||
<value>Draw filled</value>
|
<value>Draw filled</value>
|
||||||
<comment>Whether silver coffers should only be drawn with the circle outline or as filled circle.</comment>
|
<comment>Whether silver coffers should only be drawn with the circle outline or as filled circle.</comment>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Config_GoldCoffer_Show" xml:space="preserve">
|
||||||
|
<value>Show gold coffers on current floor</value>
|
||||||
|
</data>
|
||||||
|
<data name="Config_GoldCoffers_ToolTip" xml:space="preserve">
|
||||||
|
<value>Shows nearby gold coffers (containing pomanders) on the current floor.
|
||||||
|
This is not synchronized with other players and not saved between floors/runs.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Config_GoldCoffer_Color" xml:space="preserve">
|
||||||
|
<value>Gold Coffer color</value>
|
||||||
|
</data>
|
||||||
|
<data name="Config_GoldCoffer_Filled" xml:space="preserve">
|
||||||
|
<value>Draw filled</value>
|
||||||
|
<comment>Whether gold coffers should only be drawn with the circle outline or as filled circle.</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
<!-- Config Window: Community -->
|
<!-- Config Window: Community -->
|
||||||
<data name="ConfigTab_Community" xml:space="preserve">
|
<data name="ConfigTab_Community" xml:space="preserve">
|
||||||
|
@ -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
|
||||||
```
|
```
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
namespace Pal.Client.Rendering
|
namespace Pal.Client.Rendering;
|
||||||
{
|
|
||||||
internal enum ELayer
|
internal enum ELayer
|
||||||
{
|
{
|
||||||
TrapHoard,
|
TrapHoard,
|
||||||
RegularCoffers,
|
RegularCoffers,
|
||||||
Test,
|
Test,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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();
|
||||||
@ -12,6 +12,7 @@ namespace Pal.Client.Rendering
|
|||||||
{ MemoryLocation.EType.Trap, new MarkerConfig { Radius = 1.7f } },
|
{ MemoryLocation.EType.Trap, new MarkerConfig { Radius = 1.7f } },
|
||||||
{ MemoryLocation.EType.Hoard, new MarkerConfig { Radius = 1.7f, OffsetY = -0.03f } },
|
{ MemoryLocation.EType.Hoard, new MarkerConfig { Radius = 1.7f, OffsetY = -0.03f } },
|
||||||
{ MemoryLocation.EType.SilverCoffer, new MarkerConfig { Radius = 1f } },
|
{ MemoryLocation.EType.SilverCoffer, new MarkerConfig { Radius = 1f } },
|
||||||
|
{ MemoryLocation.EType.GoldCoffer, new MarkerConfig { Radius = 1f } },
|
||||||
};
|
};
|
||||||
|
|
||||||
public float OffsetY { get; private init; }
|
public float OffsetY { get; private init; }
|
||||||
@ -20,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);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
@ -27,6 +27,8 @@ namespace Pal.Client.Rendering
|
|||||||
_implementation = Recreate(null);
|
_implementation = Recreate(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool RequireRedraw { get; set; }
|
||||||
|
|
||||||
private IRenderer Recreate(ERenderer? currentRenderer)
|
private IRenderer Recreate(ERenderer? currentRenderer)
|
||||||
{
|
{
|
||||||
ERenderer targetRenderer = _configuration.Renderer.SelectedRenderer;
|
ERenderer targetRenderer = _configuration.Renderer.SelectedRenderer;
|
||||||
@ -46,6 +48,7 @@ namespace Pal.Client.Rendering
|
|||||||
public void ConfigUpdated()
|
public void ConfigUpdated()
|
||||||
{
|
{
|
||||||
_implementation = Recreate(_implementation.GetConfigValue());
|
_implementation = Recreate(_implementation.GetConfigValue());
|
||||||
|
RequireRedraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@ -57,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();
|
||||||
@ -72,4 +76,3 @@ namespace Pal.Client.Rendering
|
|||||||
sr.DrawLayers();
|
sr.DrawLayers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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>
|
||||||
@ -22,9 +22,7 @@ namespace Pal.Client.Scheduled
|
|||||||
|
|
||||||
protected override void Run(QueuedConfigUpdate queued, ref bool recreateLayout)
|
protected override void Run(QueuedConfigUpdate queued, ref bool recreateLayout)
|
||||||
{
|
{
|
||||||
// TODO filter stuff if offline
|
|
||||||
_renderAdapter.ConfigUpdated();
|
_renderAdapter.ConfigUpdated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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";
|
||||||
|
|
||||||
@ -47,6 +49,7 @@ namespace Pal.Client.Windows
|
|||||||
private ConfigurableMarker _trapConfig = new();
|
private ConfigurableMarker _trapConfig = new();
|
||||||
private ConfigurableMarker _hoardConfig = new();
|
private ConfigurableMarker _hoardConfig = new();
|
||||||
private ConfigurableMarker _silverConfig = new();
|
private ConfigurableMarker _silverConfig = new();
|
||||||
|
private ConfigurableMarker _goldConfig = new();
|
||||||
|
|
||||||
private string? _connectionText;
|
private string? _connectionText;
|
||||||
private bool _switchToCommunityTab;
|
private bool _switchToCommunityTab;
|
||||||
@ -96,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
|
||||||
@ -124,6 +133,7 @@ namespace Pal.Client.Windows
|
|||||||
_trapConfig = new ConfigurableMarker(_configuration.DeepDungeons.Traps);
|
_trapConfig = new ConfigurableMarker(_configuration.DeepDungeons.Traps);
|
||||||
_hoardConfig = new ConfigurableMarker(_configuration.DeepDungeons.HoardCoffers);
|
_hoardConfig = new ConfigurableMarker(_configuration.DeepDungeons.HoardCoffers);
|
||||||
_silverConfig = new ConfigurableMarker(_configuration.DeepDungeons.SilverCoffers);
|
_silverConfig = new ConfigurableMarker(_configuration.DeepDungeons.SilverCoffers);
|
||||||
|
_goldConfig = new ConfigurableMarker(_configuration.DeepDungeons.GoldCoffers);
|
||||||
_connectionText = null;
|
_connectionText = null;
|
||||||
|
|
||||||
UpdateLastImport();
|
UpdateLastImport();
|
||||||
@ -162,6 +172,7 @@ namespace Pal.Client.Windows
|
|||||||
_configuration.DeepDungeons.Traps = _trapConfig.Build();
|
_configuration.DeepDungeons.Traps = _trapConfig.Build();
|
||||||
_configuration.DeepDungeons.HoardCoffers = _hoardConfig.Build();
|
_configuration.DeepDungeons.HoardCoffers = _hoardConfig.Build();
|
||||||
_configuration.DeepDungeons.SilverCoffers = _silverConfig.Build();
|
_configuration.DeepDungeons.SilverCoffers = _silverConfig.Build();
|
||||||
|
_configuration.DeepDungeons.GoldCoffers = _goldConfig.Build();
|
||||||
|
|
||||||
_configurationManager.Save(_configuration);
|
_configurationManager.Save(_configuration);
|
||||||
|
|
||||||
@ -174,6 +185,7 @@ namespace Pal.Client.Windows
|
|||||||
{
|
{
|
||||||
if (ImGui.BeginTabItem($"{Localization.ConfigTab_DeepDungeons}###TabDeepDungeons"))
|
if (ImGui.BeginTabItem($"{Localization.ConfigTab_DeepDungeons}###TabDeepDungeons"))
|
||||||
{
|
{
|
||||||
|
ImGui.PushID("trap");
|
||||||
ImGui.Checkbox(Localization.Config_Traps_Show, ref _trapConfig.Show);
|
ImGui.Checkbox(Localization.Config_Traps_Show, ref _trapConfig.Show);
|
||||||
ImGui.Indent();
|
ImGui.Indent();
|
||||||
ImGui.BeginDisabled(!_trapConfig.Show);
|
ImGui.BeginDisabled(!_trapConfig.Show);
|
||||||
@ -184,9 +196,11 @@ namespace Pal.Client.Windows
|
|||||||
ImGuiComponents.HelpMarker(Localization.Config_Traps_HideImpossible_ToolTip);
|
ImGuiComponents.HelpMarker(Localization.Config_Traps_HideImpossible_ToolTip);
|
||||||
ImGui.EndDisabled();
|
ImGui.EndDisabled();
|
||||||
ImGui.Unindent();
|
ImGui.Unindent();
|
||||||
|
ImGui.PopID();
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
|
ImGui.PushID("hoard");
|
||||||
ImGui.Checkbox(Localization.Config_HoardCoffers_Show, ref _hoardConfig.Show);
|
ImGui.Checkbox(Localization.Config_HoardCoffers_Show, ref _hoardConfig.Show);
|
||||||
ImGui.Indent();
|
ImGui.Indent();
|
||||||
ImGui.BeginDisabled(!_hoardConfig.Show);
|
ImGui.BeginDisabled(!_hoardConfig.Show);
|
||||||
@ -199,9 +213,11 @@ namespace Pal.Client.Windows
|
|||||||
ImGuiComponents.HelpMarker(Localization.Config_HoardCoffers_HideImpossible_ToolTip);
|
ImGuiComponents.HelpMarker(Localization.Config_HoardCoffers_HideImpossible_ToolTip);
|
||||||
ImGui.EndDisabled();
|
ImGui.EndDisabled();
|
||||||
ImGui.Unindent();
|
ImGui.Unindent();
|
||||||
|
ImGui.PopID();
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
|
ImGui.PushID("silver");
|
||||||
ImGui.Checkbox(Localization.Config_SilverCoffer_Show, ref _silverConfig.Show);
|
ImGui.Checkbox(Localization.Config_SilverCoffer_Show, ref _silverConfig.Show);
|
||||||
ImGuiComponents.HelpMarker(Localization.Config_SilverCoffers_ToolTip);
|
ImGuiComponents.HelpMarker(Localization.Config_SilverCoffers_ToolTip);
|
||||||
ImGui.Indent();
|
ImGui.Indent();
|
||||||
@ -212,6 +228,22 @@ namespace Pal.Client.Windows
|
|||||||
ImGui.Checkbox(Localization.Config_SilverCoffer_Filled, ref _silverConfig.Fill);
|
ImGui.Checkbox(Localization.Config_SilverCoffer_Filled, ref _silverConfig.Fill);
|
||||||
ImGui.EndDisabled();
|
ImGui.EndDisabled();
|
||||||
ImGui.Unindent();
|
ImGui.Unindent();
|
||||||
|
ImGui.PopID();
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
|
ImGui.PushID("gold");
|
||||||
|
ImGui.Checkbox(Localization.Config_GoldCoffer_Show, ref _goldConfig.Show);
|
||||||
|
ImGuiComponents.HelpMarker(Localization.Config_GoldCoffers_ToolTip);
|
||||||
|
ImGui.Indent();
|
||||||
|
ImGui.BeginDisabled(!_goldConfig.Show);
|
||||||
|
ImGui.Spacing();
|
||||||
|
ImGui.ColorEdit4(Localization.Config_GoldCoffer_Color, ref _goldConfig.Color,
|
||||||
|
ImGuiColorEditFlags.NoInputs);
|
||||||
|
ImGui.Checkbox(Localization.Config_GoldCoffer_Filled, ref _goldConfig.Fill);
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
ImGui.Unindent();
|
||||||
|
ImGui.PopID();
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
@ -260,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();
|
||||||
@ -408,6 +442,15 @@ namespace Pal.Client.Windows
|
|||||||
$"{silverCoffers} silver coffer{(silverCoffers == 1 ? "" : "s")} visible on current floor");
|
$"{silverCoffers} silver coffer{(silverCoffers == 1 ? "" : "s")} visible on current floor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_goldConfig.Show)
|
||||||
|
{
|
||||||
|
int goldCoffers =
|
||||||
|
_floorService.EphemeralLocations.Count(x =>
|
||||||
|
x.Type == MemoryLocation.EType.GoldCoffer);
|
||||||
|
ImGui.Text(
|
||||||
|
$"{goldCoffers} silver coffer{(goldCoffers == 1 ? "" : "s")} visible on current floor");
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.Text($"Pomander of Sight: {_territoryState.PomanderOfSight}");
|
ImGui.Text($"Pomander of Sight: {_territoryState.PomanderOfSight}");
|
||||||
ImGui.Text($"Pomander of Intuition: {_territoryState.PomanderOfIntuition}");
|
ImGui.Text($"Pomander of Intuition: {_territoryState.PomanderOfIntuition}");
|
||||||
}
|
}
|
||||||
@ -472,7 +515,17 @@ namespace Pal.Client.Windows
|
|||||||
CancellationTokenSource cts = new CancellationTokenSource();
|
CancellationTokenSource cts = new CancellationTokenSource();
|
||||||
_lastImportCts = cts;
|
_lastImportCts = cts;
|
||||||
|
|
||||||
Task.Run(async () => { _lastImport = await _importService.FindLast(cts.Token); }, cts.Token);
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_lastImport = await _importService.FindLast(cts.Token);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.LogError(e, "Unable to fetch last import");
|
||||||
|
}
|
||||||
|
}, cts.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DoExport(string destinationPath)
|
private void DoExport(string destinationPath)
|
||||||
@ -533,4 +586,3 @@ namespace Pal.Client.Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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";
|
||||||
@ -49,6 +49,8 @@ namespace Pal.Client.Windows
|
|||||||
ETerritoryType.Palace_191_200);
|
ETerritoryType.Palace_191_200);
|
||||||
DrawDungeonStats("Heaven on High", Localization.HeavenOnHigh, ETerritoryType.HeavenOnHigh_1_10,
|
DrawDungeonStats("Heaven on High", Localization.HeavenOnHigh, ETerritoryType.HeavenOnHigh_1_10,
|
||||||
ETerritoryType.HeavenOnHigh_91_100);
|
ETerritoryType.HeavenOnHigh_91_100);
|
||||||
|
DrawDungeonStats("Eureka Orthos", Localization.EurekaOrthos, ETerritoryType.EurekaOrthos_1_10,
|
||||||
|
ETerritoryType.EurekaOrthos_91_100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,4 +123,3 @@ namespace Pal.Client.Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
344
Pal.Client/packages.lock.json
Normal file
344
Pal.Client/packages.lock.json
Normal 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=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
@ -47,6 +47,16 @@ namespace Pal.Common
|
|||||||
[Display(Order = 9)]
|
[Display(Order = 9)]
|
||||||
HeavenOnHigh_81_90 = 775,
|
HeavenOnHigh_81_90 = 775,
|
||||||
[Display(Order = 10)]
|
[Display(Order = 10)]
|
||||||
HeavenOnHigh_91_100 = 785
|
HeavenOnHigh_91_100 = 785,
|
||||||
}
|
|
||||||
|
EurekaOrthos_1_10 = 1099,
|
||||||
|
EurekaOrthos_11_20,
|
||||||
|
EurekaOrthos_21_30,
|
||||||
|
EurekaOrthos_31_40,
|
||||||
|
EurekaOrthos_41_50,
|
||||||
|
EurekaOrthos_51_60,
|
||||||
|
EurekaOrthos_61_70,
|
||||||
|
EurekaOrthos_71_80,
|
||||||
|
EurekaOrthos_81_90,
|
||||||
|
EurekaOrthos_91_100
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
package account;
|
package export;
|
||||||
|
|
||||||
import "google/protobuf/timestamp.proto";
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
6
Pal.Common/packages.lock.json
Normal file
6
Pal.Common/packages.lock.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"dependencies": {
|
||||||
|
"net8.0": {}
|
||||||
|
}
|
||||||
|
}
|
23
Pal.sln
23
Pal.sln
@ -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,6 +25,10 @@ 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.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
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -64,6 +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
|
||||||
|
{AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{AEC052FA-F178-492C-9A09-ED28DBE1EF5E}.Release|x64.ActiveCfg = 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
|
||||||
|
@ -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
1
Server
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit e59583fac353fdd960556ed2fa65220d66db5637
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user