New configuration format
This commit is contained in:
parent
4be0bdf637
commit
b0de113ad2
80
Pal.Client/Configuration/AccountConfigurationV7.cs
Normal file
80
Pal.Client/Configuration/AccountConfigurationV7.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json.Serialization;
|
||||
using Dalamud.Logging;
|
||||
|
||||
namespace Pal.Client.Configuration
|
||||
{
|
||||
public class AccountConfigurationV7 : IAccountConfiguration
|
||||
{
|
||||
[JsonConstructor]
|
||||
public AccountConfigurationV7()
|
||||
{
|
||||
}
|
||||
|
||||
public AccountConfigurationV7(string server, Guid accountId)
|
||||
{
|
||||
Server = server;
|
||||
EncryptedId = EncryptAccountId(accountId);
|
||||
}
|
||||
|
||||
[Obsolete("for V1 import")]
|
||||
public AccountConfigurationV7(string server, string accountId)
|
||||
{
|
||||
Server = server;
|
||||
|
||||
if (accountId.StartsWith("s:"))
|
||||
EncryptedId = accountId;
|
||||
else if (Guid.TryParse(accountId, out Guid guid))
|
||||
EncryptedId = EncryptAccountId(guid);
|
||||
else
|
||||
throw new InvalidOperationException("invalid account id format");
|
||||
}
|
||||
|
||||
public string EncryptedId { get; init; } = null!;
|
||||
|
||||
public string Server { get; set; } = null!;
|
||||
|
||||
[JsonIgnore] public bool IsUsable => DecryptAccountId(EncryptedId) != null;
|
||||
|
||||
[JsonIgnore] public Guid AccountId => DecryptAccountId(EncryptedId) ?? throw new InvalidOperationException();
|
||||
|
||||
public List<string> CachedRoles { get; set; } = new();
|
||||
|
||||
private Guid? DecryptAccountId(string id)
|
||||
{
|
||||
if (Guid.TryParse(id, out Guid guid) && guid != Guid.Empty)
|
||||
return guid;
|
||||
|
||||
if (!id.StartsWith("s:"))
|
||||
throw new InvalidOperationException("invalid prefix");
|
||||
|
||||
try
|
||||
{
|
||||
byte[] guidBytes = ProtectedData.Unprotect(Convert.FromBase64String(id.Substring(2)),
|
||||
ConfigurationData.Entropy, DataProtectionScope.CurrentUser);
|
||||
return new Guid(guidBytes);
|
||||
}
|
||||
catch (CryptographicException e)
|
||||
{
|
||||
PluginLog.Verbose(e, $"Could not load account id {id}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private string EncryptAccountId(Guid g)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] guidBytes = ProtectedData.Protect(g.ToByteArray(), ConfigurationData.Entropy,
|
||||
DataProtectionScope.CurrentUser);
|
||||
return $"s:{Convert.ToBase64String(guidBytes)}";
|
||||
}
|
||||
catch (CryptographicException)
|
||||
{
|
||||
return g.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
Pal.Client/Configuration/ConfigurationData.cs
Normal file
7
Pal.Client/Configuration/ConfigurationData.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Pal.Client.Configuration
|
||||
{
|
||||
internal static class ConfigurationData
|
||||
{
|
||||
internal static readonly byte[] Entropy = { 0x22, 0x4b, 0xe7, 0x21, 0x44, 0x83, 0x69, 0x55, 0x80, 0x38 };
|
||||
}
|
||||
}
|
108
Pal.Client/Configuration/ConfigurationManager.cs
Normal file
108
Pal.Client/Configuration/ConfigurationManager.cs
Normal file
@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Dalamud.Logging;
|
||||
using Dalamud.Plugin;
|
||||
using ImGuiNET;
|
||||
using Newtonsoft.Json;
|
||||
using JsonSerializer = System.Text.Json.JsonSerializer;
|
||||
|
||||
namespace Pal.Client.Configuration
|
||||
{
|
||||
internal class ConfigurationManager
|
||||
{
|
||||
private readonly DalamudPluginInterface _pluginInterface;
|
||||
|
||||
public ConfigurationManager(DalamudPluginInterface pluginInterface)
|
||||
{
|
||||
_pluginInterface = pluginInterface;
|
||||
}
|
||||
|
||||
public string ConfigPath => Path.Join(_pluginInterface.GetPluginConfigDirectory(), "palace-pal.config.json");
|
||||
|
||||
#pragma warning disable CS0612
|
||||
#pragma warning disable CS0618
|
||||
public void Migrate()
|
||||
{
|
||||
if (_pluginInterface.ConfigFile.Exists)
|
||||
{
|
||||
PluginLog.Information("Migrating config file from v1-v6 format");
|
||||
|
||||
ConfigurationV1 configurationV1 =
|
||||
JsonConvert.DeserializeObject<ConfigurationV1>(
|
||||
File.ReadAllText(_pluginInterface.ConfigFile.FullName)) ?? new ConfigurationV1();
|
||||
configurationV1.Migrate();
|
||||
configurationV1.Save();
|
||||
|
||||
var v7 = MigrateToV7(configurationV1);
|
||||
Save(v7);
|
||||
|
||||
File.Move(_pluginInterface.ConfigFile.FullName, _pluginInterface.ConfigFile.FullName + ".old", true);
|
||||
}
|
||||
}
|
||||
|
||||
public IPalacePalConfiguration Load()
|
||||
{
|
||||
return JsonSerializer.Deserialize<ConfigurationV7>(File.ReadAllText(ConfigPath, Encoding.UTF8)) ??
|
||||
new ConfigurationV7();
|
||||
}
|
||||
|
||||
public void Save(IConfigurationInConfigDirectory config)
|
||||
{
|
||||
File.WriteAllText(ConfigPath,
|
||||
JsonSerializer.Serialize(config, config.GetType(), new JsonSerializerOptions { WriteIndented = true }),
|
||||
Encoding.UTF8);
|
||||
}
|
||||
|
||||
private ConfigurationV7 MigrateToV7(ConfigurationV1 v1)
|
||||
{
|
||||
ConfigurationV7 v7 = new()
|
||||
{
|
||||
Version = 7,
|
||||
FirstUse = v1.FirstUse,
|
||||
Mode = v1.Mode,
|
||||
BetaKey = v1.BetaKey,
|
||||
|
||||
DeepDungeons = new DeepDungeonConfiguration
|
||||
{
|
||||
Traps = new MarkerConfiguration
|
||||
{
|
||||
Show = v1.ShowTraps,
|
||||
Color = ImGui.ColorConvertFloat4ToU32(v1.TrapColor),
|
||||
Fill = false
|
||||
},
|
||||
HoardCoffers = new MarkerConfiguration
|
||||
{
|
||||
Show = v1.ShowHoard,
|
||||
Color = ImGui.ColorConvertFloat4ToU32(v1.HoardColor),
|
||||
Fill = false
|
||||
},
|
||||
SilverCoffers = new MarkerConfiguration
|
||||
{
|
||||
Show = v1.ShowSilverCoffers,
|
||||
Color = ImGui.ColorConvertFloat4ToU32(v1.SilverCofferColor),
|
||||
Fill = v1.FillSilverCoffers
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
foreach (var (server, oldAccount) in v1.Accounts)
|
||||
{
|
||||
string? accountId = oldAccount.Id;
|
||||
if (string.IsNullOrEmpty(accountId))
|
||||
continue;
|
||||
|
||||
IAccountConfiguration newAccount = v7.CreateAccount(server, accountId);
|
||||
newAccount.CachedRoles = oldAccount.CachedRoles.ToList();
|
||||
}
|
||||
|
||||
// TODO Migrate ImportHistory
|
||||
|
||||
return v7;
|
||||
}
|
||||
#pragma warning restore CS0618
|
||||
#pragma warning restore CS0612
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using Dalamud.Configuration;
|
||||
using Dalamud.Logging;
|
||||
using Dalamud.Logging;
|
||||
using ECommons.Schedulers;
|
||||
using Newtonsoft.Json;
|
||||
using Pal.Client.Scheduled;
|
||||
@ -9,15 +8,13 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Security.Cryptography;
|
||||
using Pal.Client.Extensions;
|
||||
|
||||
namespace Pal.Client
|
||||
namespace Pal.Client.Configuration
|
||||
{
|
||||
public class Configuration : IPluginConfiguration
|
||||
[Obsolete]
|
||||
public class ConfigurationV1
|
||||
{
|
||||
private static readonly byte[] Entropy = { 0x22, 0x4b, 0xe7, 0x21, 0x44, 0x83, 0x69, 0x55, 0x80, 0x38 };
|
||||
|
||||
public int Version { get; set; } = 6;
|
||||
|
||||
#region Saved configuration values
|
||||
@ -55,7 +52,6 @@ namespace Pal.Client
|
||||
public string BetaKey { get; set; } = "";
|
||||
#endregion
|
||||
|
||||
#pragma warning disable CS0612 // Type or member is obsolete
|
||||
public void Migrate()
|
||||
{
|
||||
if (Version == 1)
|
||||
@ -78,7 +74,7 @@ namespace Pal.Client
|
||||
|
||||
Accounts = AccountIds.ToDictionary(x => x.Key, x => new AccountInfo
|
||||
{
|
||||
Id = x.Value
|
||||
Id = x.Value.ToString() // encryption happens in V7 migration at latest
|
||||
});
|
||||
Version = 3;
|
||||
Save();
|
||||
@ -140,108 +136,23 @@ namespace Pal.Client
|
||||
Save();
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS0612 // Type or member is obsolete
|
||||
|
||||
public void Save()
|
||||
{
|
||||
Service.PluginInterface.SavePluginConfig(this);
|
||||
File.WriteAllText(Service.PluginInterface.ConfigFile.FullName, JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
|
||||
TypeNameHandling = TypeNameHandling.Objects
|
||||
}));
|
||||
Service.Plugin.EarlyEventQueue.Enqueue(new QueuedConfigUpdate());
|
||||
}
|
||||
|
||||
public enum EMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Fetches trap locations from remote server.
|
||||
/// </summary>
|
||||
Online = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Only shows traps found by yourself uisng a pomander of sight.
|
||||
/// </summary>
|
||||
Offline = 2,
|
||||
}
|
||||
|
||||
public enum ERenderer
|
||||
{
|
||||
/// <see cref="Rendering.SimpleRenderer"/>
|
||||
Simple = 0,
|
||||
|
||||
/// <see cref="Rendering.SplatoonRenderer"/>
|
||||
Splatoon = 1,
|
||||
}
|
||||
|
||||
public class AccountInfo
|
||||
{
|
||||
[JsonConverter(typeof(AccountIdConverter))]
|
||||
public Guid? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is taken from the JWT, and is only refreshed on a successful login.
|
||||
///
|
||||
/// If you simply reload the plugin without any server interaction, this doesn't change.
|
||||
///
|
||||
/// This has no impact on what roles the JWT actually contains, but is just to make it
|
||||
/// easier to draw a consistent UI. The server will still reject unauthorized calls.
|
||||
/// </summary>
|
||||
public string? Id { get; set; }
|
||||
public List<string> CachedRoles { get; set; } = new();
|
||||
}
|
||||
|
||||
public class AccountIdConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType) => true;
|
||||
|
||||
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.String)
|
||||
{
|
||||
string? text = reader.Value?.ToString();
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return null;
|
||||
|
||||
if (Guid.TryParse(text, out Guid guid) && guid != Guid.Empty)
|
||||
return guid;
|
||||
|
||||
if (text.StartsWith("s:"))
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] guidBytes = ProtectedData.Unprotect(Convert.FromBase64String(text.Substring(2)), Entropy, DataProtectionScope.CurrentUser);
|
||||
return new Guid(guidBytes);
|
||||
}
|
||||
catch (CryptographicException e)
|
||||
{
|
||||
PluginLog.Error(e, "Could not load account id");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new JsonSerializationException();
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteNull();
|
||||
return;
|
||||
}
|
||||
|
||||
Guid g = (Guid)value;
|
||||
string text;
|
||||
try
|
||||
{
|
||||
byte[] guidBytes = ProtectedData.Protect(g.ToByteArray(), Entropy, DataProtectionScope.CurrentUser);
|
||||
text = $"s:{Convert.ToBase64String(guidBytes)}";
|
||||
}
|
||||
catch (CryptographicException)
|
||||
{
|
||||
text = g.ToString();
|
||||
}
|
||||
|
||||
writer.WriteValue(text);
|
||||
}
|
||||
}
|
||||
|
||||
public class ImportHistoryEntry
|
||||
{
|
||||
public Guid Id { get; set; }
|
48
Pal.Client/Configuration/ConfigurationV7.cs
Normal file
48
Pal.Client/Configuration/ConfigurationV7.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Pal.Client.Configuration;
|
||||
|
||||
public class ConfigurationV7 : IPalacePalConfiguration, IConfigurationInConfigDirectory
|
||||
{
|
||||
public int Version { get; set; } = 7;
|
||||
|
||||
public bool FirstUse { get; set; } = true;
|
||||
public EMode Mode { get; set; }
|
||||
public string BetaKey { get; init; } = "";
|
||||
|
||||
public DeepDungeonConfiguration DeepDungeons { get; set; } = new();
|
||||
public RendererConfiguration Renderer { get; set; } = new();
|
||||
public List<AccountConfigurationV7> Accounts { get; set; } = new();
|
||||
|
||||
[JsonIgnore]
|
||||
[Obsolete]
|
||||
public List<ConfigurationV1.ImportHistoryEntry> ImportHistory { get; set; } = new();
|
||||
|
||||
public IAccountConfiguration CreateAccount(string server, Guid accountId)
|
||||
{
|
||||
var account = new AccountConfigurationV7(server, accountId);
|
||||
Accounts.Add(account);
|
||||
return account;
|
||||
}
|
||||
|
||||
[Obsolete("for V1 import")]
|
||||
internal IAccountConfiguration CreateAccount(string server, string accountId)
|
||||
{
|
||||
var account = new AccountConfigurationV7(server, accountId);
|
||||
Accounts.Add(account);
|
||||
return account;
|
||||
}
|
||||
|
||||
public IAccountConfiguration? FindAccount(string server)
|
||||
{
|
||||
return Accounts.FirstOrDefault(a => a.Server == server && a.IsUsable);
|
||||
}
|
||||
|
||||
public void RemoveAccount(string server)
|
||||
{
|
||||
Accounts.RemoveAll(a => a.Server == server && a.IsUsable);
|
||||
}
|
||||
}
|
15
Pal.Client/Configuration/EMode.cs
Normal file
15
Pal.Client/Configuration/EMode.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace Pal.Client.Configuration
|
||||
{
|
||||
public enum EMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Fetches trap locations from remote server.
|
||||
/// </summary>
|
||||
Online = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Only shows traps found by yourself uisng a pomander of sight.
|
||||
/// </summary>
|
||||
Offline = 2,
|
||||
}
|
||||
}
|
11
Pal.Client/Configuration/ERenderer.cs
Normal file
11
Pal.Client/Configuration/ERenderer.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace Pal.Client.Configuration
|
||||
{
|
||||
public enum ERenderer
|
||||
{
|
||||
/// <see cref="Rendering.SimpleRenderer"/>
|
||||
Simple = 0,
|
||||
|
||||
/// <see cref="Rendering.SplatoonRenderer"/>
|
||||
Splatoon = 1,
|
||||
}
|
||||
}
|
89
Pal.Client/Configuration/IPalacePalConfiguration.cs
Normal file
89
Pal.Client/Configuration/IPalacePalConfiguration.cs
Normal file
@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Pal.Client.Configuration
|
||||
{
|
||||
public interface IVersioned
|
||||
{
|
||||
int Version { get; set; }
|
||||
}
|
||||
public interface IConfigurationInConfigDirectory : IVersioned
|
||||
{
|
||||
}
|
||||
|
||||
public interface IPalacePalConfiguration : IConfigurationInConfigDirectory
|
||||
{
|
||||
bool FirstUse { get; set; }
|
||||
EMode Mode { get; set; }
|
||||
string BetaKey { get; }
|
||||
|
||||
DeepDungeonConfiguration DeepDungeons { get; set; }
|
||||
RendererConfiguration Renderer { get; set; }
|
||||
|
||||
[Obsolete]
|
||||
List<ConfigurationV1.ImportHistoryEntry> ImportHistory { get; }
|
||||
|
||||
IAccountConfiguration CreateAccount(string server, Guid accountId);
|
||||
IAccountConfiguration? FindAccount(string server);
|
||||
void RemoveAccount(string server);
|
||||
}
|
||||
|
||||
public class DeepDungeonConfiguration
|
||||
{
|
||||
public MarkerConfiguration Traps { get; set; } = new()
|
||||
{
|
||||
Show = true,
|
||||
Color = ImGui.ColorConvertFloat4ToU32(new Vector4(1, 0, 0, 0.4f)),
|
||||
OnlyVisibleAfterPomander = true,
|
||||
Fill = false
|
||||
};
|
||||
|
||||
public MarkerConfiguration HoardCoffers { get; set; } = new()
|
||||
{
|
||||
Show = true,
|
||||
Color = ImGui.ColorConvertFloat4ToU32(new Vector4(0, 1, 1, 0.4f)),
|
||||
OnlyVisibleAfterPomander = true,
|
||||
Fill = false
|
||||
};
|
||||
|
||||
public MarkerConfiguration SilverCoffers { get; set; } = new()
|
||||
{
|
||||
Show = false,
|
||||
Color = ImGui.ColorConvertFloat4ToU32(new Vector4(1, 1, 1, 0.4f)),
|
||||
OnlyVisibleAfterPomander = false,
|
||||
Fill = true
|
||||
};
|
||||
}
|
||||
|
||||
public class MarkerConfiguration
|
||||
{
|
||||
public bool Show { get; set; }
|
||||
public uint Color { get; set; }
|
||||
public bool OnlyVisibleAfterPomander { get; set; }
|
||||
public bool Fill { get; set; }
|
||||
}
|
||||
|
||||
public class RendererConfiguration
|
||||
{
|
||||
public ERenderer SelectedRenderer { get; set; } = ERenderer.Splatoon;
|
||||
}
|
||||
|
||||
public interface IAccountConfiguration
|
||||
{
|
||||
public bool IsUsable { get; }
|
||||
public string Server { get; }
|
||||
public Guid AccountId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// This is taken from the JWT, and is only refreshed on a successful login.
|
||||
///
|
||||
/// If you simply reload the plugin without any server interaction, this doesn't change.
|
||||
///
|
||||
/// This has no impact on what roles the JWT actually contains, but is just to make it
|
||||
/// easier to draw a consistent UI. The server will still reject unauthorized calls.
|
||||
/// </summary>
|
||||
public List<string> CachedRoles { get; set; }
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Pal.Client.Extensions;
|
||||
using Pal.Client.Properties;
|
||||
using Pal.Client.Configuration;
|
||||
|
||||
namespace Pal.Client.Net
|
||||
{
|
||||
@ -18,7 +19,7 @@ namespace Pal.Client.Net
|
||||
{
|
||||
private async Task<(bool Success, string Error)> TryConnect(CancellationToken cancellationToken, ILoggerFactory? loggerFactory = null, bool retry = true)
|
||||
{
|
||||
if (Service.Configuration.Mode != Configuration.EMode.Online)
|
||||
if (Service.Configuration.Mode != EMode.Online)
|
||||
{
|
||||
PluginLog.Debug("TryConnect: Not Online, not attempting to establish a connection");
|
||||
return (false, Localization.ConnectionError_NotOnline);
|
||||
@ -46,19 +47,20 @@ namespace Pal.Client.Net
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var accountClient = new AccountService.AccountServiceClient(_channel);
|
||||
if (AccountId == null)
|
||||
IAccountConfiguration? configuredAccount = Service.Configuration.FindAccount(RemoteUrl);
|
||||
if (configuredAccount == null)
|
||||
{
|
||||
PluginLog.Information($"TryConnect: No account information saved for {RemoteUrl}, creating new account");
|
||||
var createAccountReply = await accountClient.CreateAccountAsync(new CreateAccountRequest(), headers: UnauthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken);
|
||||
if (createAccountReply.Success)
|
||||
{
|
||||
Account = new Configuration.AccountInfo
|
||||
{
|
||||
Id = Guid.Parse(createAccountReply.AccountId),
|
||||
};
|
||||
PluginLog.Information($"TryConnect: Account created with id {FormattedPartialAccountId}");
|
||||
if (Guid.TryParse(createAccountReply.AccountId, out Guid accountId))
|
||||
throw new InvalidOperationException("invalid account id returned");
|
||||
|
||||
Service.Configuration.Save();
|
||||
configuredAccount = Service.Configuration.CreateAccount(RemoteUrl, accountId);
|
||||
PluginLog.Information($"TryConnect: Account created with id {accountId.ToPartialId()}");
|
||||
|
||||
Service.ConfigurationManager.Save(Service.Configuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -74,27 +76,24 @@ namespace Pal.Client.Net
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (AccountId == null)
|
||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
||||
if (configuredAccount == null)
|
||||
{
|
||||
PluginLog.Warning("TryConnect: No account id to login with");
|
||||
PluginLog.Warning("TryConnect: No account to login with");
|
||||
return (false, Localization.ConnectionError_CreateAccountReturnedNoId);
|
||||
}
|
||||
|
||||
if (!_loginInfo.IsValid)
|
||||
{
|
||||
PluginLog.Information($"TryConnect: Logging in with account id {FormattedPartialAccountId}");
|
||||
LoginReply loginReply = await accountClient.LoginAsync(new LoginRequest { AccountId = AccountId?.ToString() }, headers: UnauthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken);
|
||||
PluginLog.Information($"TryConnect: Logging in with account id {configuredAccount.AccountId.ToPartialId()}");
|
||||
LoginReply loginReply = await accountClient.LoginAsync(new LoginRequest { AccountId = configuredAccount.AccountId.ToString() }, headers: UnauthorizedHeaders(), deadline: DateTime.UtcNow.AddSeconds(10), cancellationToken: cancellationToken);
|
||||
if (loginReply.Success)
|
||||
{
|
||||
PluginLog.Information($"TryConnect: Login successful with account id: {FormattedPartialAccountId}");
|
||||
PluginLog.Information($"TryConnect: Login successful with account id: {configuredAccount.AccountId.ToPartialId()}");
|
||||
_loginInfo = new LoginInfo(loginReply.AuthToken);
|
||||
|
||||
var account = Account;
|
||||
if (account != null)
|
||||
{
|
||||
account.CachedRoles = _loginInfo.Claims?.Roles.ToList() ?? new List<string>();
|
||||
Service.Configuration.Save();
|
||||
}
|
||||
configuredAccount.CachedRoles = _loginInfo.Claims?.Roles.ToList() ?? new List<string>();
|
||||
Service.ConfigurationManager.Save(Service.Configuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -102,8 +101,8 @@ namespace Pal.Client.Net
|
||||
_loginInfo = new LoginInfo(null);
|
||||
if (loginReply.Error == LoginError.InvalidAccountId)
|
||||
{
|
||||
Account = null;
|
||||
Service.Configuration.Save();
|
||||
Service.Configuration.RemoveAccount(RemoteUrl);
|
||||
Service.ConfigurationManager.Save(Service.Configuration);
|
||||
if (retry)
|
||||
{
|
||||
PluginLog.Information("TryConnect: Attempting connection retry without account id");
|
||||
|
@ -59,7 +59,7 @@ namespace Pal.Client.Net
|
||||
if (Service.Configuration.Mode != Configuration.EMode.Online)
|
||||
return false;
|
||||
|
||||
var account = Account;
|
||||
var account = Service.Configuration.FindAccount(RemoteUrl);
|
||||
return account == null || account.CachedRoles.Contains(role);
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,19 @@
|
||||
using Grpc.Net.Client;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Pal.Client.Extensions;
|
||||
using Pal.Client.Configuration;
|
||||
|
||||
namespace Pal.Client.Net
|
||||
{
|
||||
internal partial class RemoteApi : IDisposable
|
||||
{
|
||||
#if DEBUG
|
||||
public static string RemoteUrl { get; } = "http://localhost:5145";
|
||||
public const string RemoteUrl = "http://localhost:5145";
|
||||
#else
|
||||
public static string RemoteUrl { get; } = "https://pal.μ.tv";
|
||||
public const string RemoteUrl = "https://pal.μ.tv";
|
||||
#endif
|
||||
private readonly string _userAgent = $"{typeof(RemoteApi).Assembly.GetName().Name?.Replace(" ", "")}/{typeof(RemoteApi).Assembly.GetName().Version?.ToString(2)}";
|
||||
|
||||
@ -21,24 +24,6 @@ namespace Pal.Client.Net
|
||||
private LoginInfo _loginInfo = new(null);
|
||||
private bool _warnedAboutUpgrade;
|
||||
|
||||
public Configuration.AccountInfo? Account
|
||||
{
|
||||
get => Service.Configuration.Accounts.TryGetValue(RemoteUrl, out Configuration.AccountInfo? accountInfo) ? accountInfo : null;
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
Service.Configuration.Accounts[RemoteUrl] = value;
|
||||
else
|
||||
Service.Configuration.Accounts.Remove(RemoteUrl);
|
||||
}
|
||||
}
|
||||
|
||||
public Guid? AccountId => Account?.Id;
|
||||
|
||||
public string? PartialAccountId => Account?.Id?.ToPartialId();
|
||||
|
||||
private string FormattedPartialAccountId => PartialAccountId ?? "[no account id]";
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
PluginLog.Debug("Disposing gRPC channel");
|
||||
|
@ -27,6 +27,9 @@ using System.Threading.Tasks;
|
||||
using Pal.Client.Extensions;
|
||||
using Pal.Client.Properties;
|
||||
using ECommons;
|
||||
using ECommons.Schedulers;
|
||||
using Pal.Client.Configuration;
|
||||
using Pal.Client.Net;
|
||||
|
||||
namespace Pal.Client
|
||||
{
|
||||
@ -71,8 +74,10 @@ namespace Pal.Client
|
||||
|
||||
pluginInterface.Create<Service>();
|
||||
Service.Plugin = this;
|
||||
Service.Configuration = (Configuration?)pluginInterface.GetPluginConfig() ?? pluginInterface.Create<Configuration>()!;
|
||||
Service.Configuration.Migrate();
|
||||
|
||||
Service.ConfigurationManager = new(pluginInterface);
|
||||
Service.ConfigurationManager.Migrate();
|
||||
Service.Configuration = Service.ConfigurationManager.Load();
|
||||
|
||||
ResetRenderer();
|
||||
|
||||
@ -146,7 +151,7 @@ namespace Pal.Client
|
||||
return;
|
||||
|
||||
configWindow.IsOpen = true;
|
||||
configWindow.TestConnection();
|
||||
var _ = new TickScheduler(() => configWindow.TestConnection());
|
||||
break;
|
||||
|
||||
#if DEBUG
|
||||
@ -196,6 +201,7 @@ namespace Pal.Client
|
||||
Service.Framework.Update -= OnFrameworkUpdate;
|
||||
Service.Chat.ChatMessage -= OnChatMessage;
|
||||
|
||||
Service.WindowSystem.GetWindow<ConfigWindow>()?.Dispose();
|
||||
Service.WindowSystem.RemoveAllWindows();
|
||||
|
||||
Service.RemoteApi.Dispose();
|
||||
@ -318,7 +324,7 @@ namespace Pal.Client
|
||||
var currentFloorMarkers = currentFloor.Markers;
|
||||
|
||||
bool updateSeenMarkers = false;
|
||||
var partialAccountId = Service.RemoteApi.PartialAccountId;
|
||||
var partialAccountId = Service.Configuration.FindAccount(RemoteApi.RemoteUrl)?.AccountId.ToPartialId();
|
||||
foreach (var visibleMarker in visibleMarkers)
|
||||
{
|
||||
Marker? knownMarker = currentFloorMarkers.SingleOrDefault(x => x == visibleMarker);
|
||||
@ -343,7 +349,7 @@ namespace Pal.Client
|
||||
saveMarkers = true;
|
||||
}
|
||||
|
||||
if (!recreateLayout && currentFloorMarkers.Count > 0 && (config.OnlyVisibleTrapsAfterPomander || config.OnlyVisibleHoardAfterPomander))
|
||||
if (!recreateLayout && currentFloorMarkers.Count > 0 && (config.DeepDungeons.Traps.OnlyVisibleAfterPomander || config.DeepDungeons.HoardCoffers.OnlyVisibleAfterPomander))
|
||||
{
|
||||
|
||||
try
|
||||
@ -399,15 +405,15 @@ namespace Pal.Client
|
||||
List<IRenderElement> elements = new();
|
||||
foreach (var marker in currentFloorMarkers)
|
||||
{
|
||||
if (marker.Seen || config.Mode == Configuration.EMode.Online || marker is { WasImported: true, Imports.Count: > 0 })
|
||||
if (marker.Seen || config.Mode == EMode.Online || marker is { WasImported: true, Imports.Count: > 0 })
|
||||
{
|
||||
if (marker.Type == Marker.EType.Trap && config.ShowTraps)
|
||||
if (marker.Type == Marker.EType.Trap)
|
||||
{
|
||||
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers));
|
||||
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers), config.DeepDungeons.Traps);
|
||||
}
|
||||
else if (marker.Type == Marker.EType.Hoard && config.ShowHoard)
|
||||
else if (marker.Type == Marker.EType.Hoard)
|
||||
{
|
||||
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers));
|
||||
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers), config.DeepDungeons.HoardCoffers);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -436,9 +442,9 @@ namespace Pal.Client
|
||||
{
|
||||
EphemeralMarkers.Add(marker);
|
||||
|
||||
if (marker.Type == Marker.EType.SilverCoffer && config.ShowSilverCoffers)
|
||||
if (marker.Type == Marker.EType.SilverCoffer && config.DeepDungeons.SilverCoffers.Show)
|
||||
{
|
||||
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers), config.FillSilverCoffers);
|
||||
CreateRenderElement(marker, elements, DetermineColor(marker, visibleMarkers), config.DeepDungeons.SilverCoffers);
|
||||
}
|
||||
}
|
||||
|
||||
@ -453,12 +459,12 @@ namespace Pal.Client
|
||||
{
|
||||
switch (marker.Type)
|
||||
{
|
||||
case Marker.EType.Trap when PomanderOfSight == PomanderState.Inactive || !Service.Configuration.OnlyVisibleTrapsAfterPomander || visibleMarkers.Any(x => x == marker):
|
||||
return ImGui.ColorConvertFloat4ToU32(Service.Configuration.TrapColor);
|
||||
case Marker.EType.Hoard when PomanderOfIntuition == PomanderState.Inactive || !Service.Configuration.OnlyVisibleHoardAfterPomander || visibleMarkers.Any(x => x == marker):
|
||||
return ImGui.ColorConvertFloat4ToU32(Service.Configuration.HoardColor);
|
||||
case Marker.EType.Trap when PomanderOfSight == PomanderState.Inactive || !Service.Configuration.DeepDungeons.Traps.OnlyVisibleAfterPomander || visibleMarkers.Any(x => x == marker):
|
||||
return Service.Configuration.DeepDungeons.Traps.Color;
|
||||
case Marker.EType.Hoard when PomanderOfIntuition == PomanderState.Inactive || !Service.Configuration.DeepDungeons.HoardCoffers.OnlyVisibleAfterPomander || visibleMarkers.Any(x => x == marker):
|
||||
return Service.Configuration.DeepDungeons.HoardCoffers.Color;
|
||||
case Marker.EType.SilverCoffer:
|
||||
return ImGui.ColorConvertFloat4ToU32(Service.Configuration.SilverCofferColor);
|
||||
return Service.Configuration.DeepDungeons.SilverCoffers.Color;
|
||||
case Marker.EType.Trap:
|
||||
case Marker.EType.Hoard:
|
||||
return ColorInvisible;
|
||||
@ -467,9 +473,12 @@ namespace Pal.Client
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateRenderElement(Marker marker, List<IRenderElement> elements, uint color, bool fill = false)
|
||||
private void CreateRenderElement(Marker marker, List<IRenderElement> elements, uint color, MarkerConfiguration config)
|
||||
{
|
||||
var element = Renderer.CreateElement(marker.Type, marker.Position, color, fill);
|
||||
if (!config.Show)
|
||||
return;
|
||||
|
||||
var element = Renderer.CreateElement(marker.Type, marker.Position, color, config.Fill);
|
||||
marker.RenderElement = element;
|
||||
elements.Add(element);
|
||||
}
|
||||
@ -651,15 +660,15 @@ namespace Pal.Client
|
||||
|
||||
internal void ResetRenderer()
|
||||
{
|
||||
if (Renderer is SplatoonRenderer && Service.Configuration.Renderer == Configuration.ERenderer.Splatoon)
|
||||
if (Renderer is SplatoonRenderer && Service.Configuration.Renderer.SelectedRenderer == ERenderer.Splatoon)
|
||||
return;
|
||||
else if (Renderer is SimpleRenderer && Service.Configuration.Renderer == Configuration.ERenderer.Simple)
|
||||
else if (Renderer is SimpleRenderer && Service.Configuration.Renderer.SelectedRenderer == ERenderer.Simple)
|
||||
return;
|
||||
|
||||
if (Renderer is IDisposable disposable)
|
||||
disposable.Dispose();
|
||||
|
||||
if (Service.Configuration.Renderer == Configuration.ERenderer.Splatoon)
|
||||
if (Service.Configuration.Renderer.SelectedRenderer == ERenderer.Splatoon)
|
||||
Renderer = new SplatoonRenderer(Service.PluginInterface, this);
|
||||
else
|
||||
Renderer = new SimpleRenderer();
|
||||
|
@ -120,7 +120,7 @@ namespace Pal.Client.Rendering
|
||||
{
|
||||
case Marker.EType.Hoard:
|
||||
// ignore distance if this is a found hoard coffer
|
||||
if (Service.Plugin.PomanderOfIntuition == Plugin.PomanderState.Active && Service.Configuration.OnlyVisibleHoardAfterPomander)
|
||||
if (Service.Plugin.PomanderOfIntuition == Plugin.PomanderState.Active && Service.Configuration.DeepDungeons.HoardCoffers.OnlyVisibleAfterPomander)
|
||||
break;
|
||||
|
||||
goto case Marker.EType.Trap;
|
||||
|
@ -8,6 +8,7 @@ using System.Linq;
|
||||
using System.Numerics;
|
||||
using Pal.Client.Extensions;
|
||||
using Pal.Client.Properties;
|
||||
using Pal.Client.Configuration;
|
||||
|
||||
namespace Pal.Client.Scheduled
|
||||
{
|
||||
@ -46,14 +47,14 @@ namespace Pal.Client.Scheduled
|
||||
}
|
||||
|
||||
config.ImportHistory.RemoveAll(hist => oldExportIds.Contains(hist.Id) || hist.Id == _exportId);
|
||||
config.ImportHistory.Add(new Configuration.ImportHistoryEntry
|
||||
config.ImportHistory.Add(new ConfigurationV1.ImportHistoryEntry
|
||||
{
|
||||
Id = _exportId,
|
||||
RemoteUrl = _export.ServerUrl,
|
||||
ExportedAt = _export.CreatedAt.ToDateTime(),
|
||||
ImportedAt = DateTime.UtcNow,
|
||||
});
|
||||
config.Save();
|
||||
Service.ConfigurationManager.Save(config);
|
||||
|
||||
recreateLayout = true;
|
||||
saveMarkers = true;
|
||||
|
@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Pal.Client.Extensions;
|
||||
using Pal.Client.Net;
|
||||
using static Pal.Client.Plugin;
|
||||
|
||||
namespace Pal.Client.Scheduled
|
||||
@ -45,7 +47,7 @@ namespace Pal.Client.Scheduled
|
||||
break;
|
||||
|
||||
case SyncType.MarkSeen:
|
||||
var partialAccountId = Service.RemoteApi.PartialAccountId;
|
||||
var partialAccountId = Service.Configuration.FindAccount(RemoteApi.RemoteUrl)?.AccountId.ToPartialId();
|
||||
if (partialAccountId == null)
|
||||
break;
|
||||
foreach (var remoteMarker in remoteMarkers)
|
||||
|
@ -8,6 +8,7 @@ using Dalamud.Game.Gui;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.Plugin;
|
||||
using Pal.Client.Configuration;
|
||||
using Pal.Client.Net;
|
||||
|
||||
namespace Pal.Client
|
||||
@ -27,7 +28,8 @@ namespace Pal.Client
|
||||
internal static Plugin Plugin { get; set; } = null!;
|
||||
internal static WindowSystem WindowSystem { get; } = new(typeof(Service).AssemblyQualifiedName);
|
||||
internal static RemoteApi RemoteApi { get; } = new();
|
||||
internal static Configuration Configuration { get; set; } = null!;
|
||||
internal static ConfigurationManager ConfigurationManager { get; set; } = null!;
|
||||
internal static IPalacePalConfiguration Configuration { get; set; } = null!;
|
||||
internal static Hooks Hooks { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ namespace Pal.Client.Windows
|
||||
{
|
||||
config.Mode = (Configuration.EMode)_choice;
|
||||
config.FirstUse = false;
|
||||
config.Save();
|
||||
Service.ConfigurationManager.Save(config);
|
||||
|
||||
IsOpen = false;
|
||||
}
|
||||
|
@ -19,23 +19,18 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Pal.Client.Properties;
|
||||
using Pal.Client.Configuration;
|
||||
|
||||
namespace Pal.Client.Windows
|
||||
{
|
||||
internal class ConfigWindow : Window, ILanguageChanged
|
||||
internal class ConfigWindow : Window, ILanguageChanged, IDisposable
|
||||
{
|
||||
private const string WindowId = "###PalPalaceConfig";
|
||||
private int _mode;
|
||||
private int _renderer;
|
||||
private bool _showTraps;
|
||||
private Vector4 _trapColor;
|
||||
private bool _onlyVisibleTrapsAfterPomander;
|
||||
private bool _showHoard;
|
||||
private Vector4 _hoardColor;
|
||||
private bool _onlyVisibleHoardAfterPomander;
|
||||
private bool _showSilverCoffers;
|
||||
private Vector4 _silverCofferColor;
|
||||
private bool _fillSilverCoffers;
|
||||
private ConfigurableMarker _trapConfig = new();
|
||||
private ConfigurableMarker _hoardConfig = new();
|
||||
private ConfigurableMarker _silverConfig = new();
|
||||
|
||||
private string? _connectionText;
|
||||
private bool _switchToCommunityTab;
|
||||
@ -67,20 +62,19 @@ namespace Pal.Client.Windows
|
||||
WindowName = $"{Localization.Palace_Pal} v{version}{WindowId}";
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_testConnectionCts?.Cancel();
|
||||
}
|
||||
|
||||
public override void OnOpen()
|
||||
{
|
||||
var config = Service.Configuration;
|
||||
_mode = (int)config.Mode;
|
||||
_renderer = (int)config.Renderer;
|
||||
_showTraps = config.ShowTraps;
|
||||
_trapColor = config.TrapColor;
|
||||
_onlyVisibleTrapsAfterPomander = config.OnlyVisibleTrapsAfterPomander;
|
||||
_showHoard = config.ShowHoard;
|
||||
_hoardColor = config.HoardColor;
|
||||
_onlyVisibleHoardAfterPomander = config.OnlyVisibleHoardAfterPomander;
|
||||
_showSilverCoffers = config.ShowSilverCoffers;
|
||||
_silverCofferColor = config.SilverCofferColor;
|
||||
_fillSilverCoffers = config.FillSilverCoffers;
|
||||
_renderer = (int)config.Renderer.SelectedRenderer;
|
||||
_trapConfig = new ConfigurableMarker(config.DeepDungeons.Traps);
|
||||
_hoardConfig = new ConfigurableMarker(config.DeepDungeons.HoardCoffers);
|
||||
_silverConfig = new ConfigurableMarker(config.DeepDungeons.SilverCoffers);
|
||||
_connectionText = null;
|
||||
}
|
||||
|
||||
@ -113,18 +107,13 @@ namespace Pal.Client.Windows
|
||||
if (save || saveAndClose)
|
||||
{
|
||||
var config = Service.Configuration;
|
||||
config.Mode = (Configuration.EMode)_mode;
|
||||
config.Renderer = (Configuration.ERenderer)_renderer;
|
||||
config.ShowTraps = _showTraps;
|
||||
config.TrapColor = _trapColor;
|
||||
config.OnlyVisibleTrapsAfterPomander = _onlyVisibleTrapsAfterPomander;
|
||||
config.ShowHoard = _showHoard;
|
||||
config.HoardColor = _hoardColor;
|
||||
config.OnlyVisibleHoardAfterPomander = _onlyVisibleHoardAfterPomander;
|
||||
config.ShowSilverCoffers = _showSilverCoffers;
|
||||
config.SilverCofferColor = _silverCofferColor;
|
||||
config.FillSilverCoffers = _fillSilverCoffers;
|
||||
config.Save();
|
||||
config.Mode = (EMode)_mode;
|
||||
config.Renderer.SelectedRenderer = (ERenderer)_renderer;
|
||||
config.DeepDungeons.Traps = _trapConfig.Build();
|
||||
config.DeepDungeons.HoardCoffers = _hoardConfig.Build();
|
||||
config.DeepDungeons.SilverCoffers = _silverConfig.Build();
|
||||
|
||||
Service.ConfigurationManager.Save(config);
|
||||
|
||||
if (saveAndClose)
|
||||
IsOpen = false;
|
||||
@ -135,12 +124,12 @@ namespace Pal.Client.Windows
|
||||
{
|
||||
if (ImGui.BeginTabItem($"{Localization.ConfigTab_DeepDungeons}###TabDeepDungeons"))
|
||||
{
|
||||
ImGui.Checkbox(Localization.Config_Traps_Show, ref _showTraps);
|
||||
ImGui.Checkbox(Localization.Config_Traps_Show, ref _trapConfig.Show);
|
||||
ImGui.Indent();
|
||||
ImGui.BeginDisabled(!_showTraps);
|
||||
ImGui.BeginDisabled(!_trapConfig.Show);
|
||||
ImGui.Spacing();
|
||||
ImGui.ColorEdit4(Localization.Config_Traps_Color, ref _trapColor, ImGuiColorEditFlags.NoInputs);
|
||||
ImGui.Checkbox(Localization.Config_Traps_HideImpossible, ref _onlyVisibleTrapsAfterPomander);
|
||||
ImGui.ColorEdit4(Localization.Config_Traps_Color, ref _trapConfig.Color, ImGuiColorEditFlags.NoInputs);
|
||||
ImGui.Checkbox(Localization.Config_Traps_HideImpossible, ref _trapConfig.OnlyVisibleAfterPomander);
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker(Localization.Config_Traps_HideImpossible_ToolTip);
|
||||
ImGui.EndDisabled();
|
||||
@ -148,12 +137,12 @@ namespace Pal.Client.Windows
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.Checkbox(Localization.Config_HoardCoffers_Show, ref _showHoard);
|
||||
ImGui.Checkbox(Localization.Config_HoardCoffers_Show, ref _hoardConfig.Show);
|
||||
ImGui.Indent();
|
||||
ImGui.BeginDisabled(!_showHoard);
|
||||
ImGui.BeginDisabled(!_hoardConfig.Show);
|
||||
ImGui.Spacing();
|
||||
ImGui.ColorEdit4(Localization.Config_HoardCoffers_Color, ref _hoardColor, ImGuiColorEditFlags.NoInputs);
|
||||
ImGui.Checkbox(Localization.Config_HoardCoffers_HideImpossible, ref _onlyVisibleHoardAfterPomander);
|
||||
ImGui.ColorEdit4(Localization.Config_HoardCoffers_Color, ref _hoardConfig.Color, ImGuiColorEditFlags.NoInputs);
|
||||
ImGui.Checkbox(Localization.Config_HoardCoffers_HideImpossible, ref _hoardConfig.OnlyVisibleAfterPomander);
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker(Localization.Config_HoardCoffers_HideImpossible_ToolTip);
|
||||
ImGui.EndDisabled();
|
||||
@ -161,13 +150,13 @@ namespace Pal.Client.Windows
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.Checkbox(Localization.Config_SilverCoffer_Show, ref _showSilverCoffers);
|
||||
ImGui.Checkbox(Localization.Config_SilverCoffer_Show, ref _silverConfig.Show);
|
||||
ImGuiComponents.HelpMarker(Localization.Config_SilverCoffers_ToolTip);
|
||||
ImGui.Indent();
|
||||
ImGui.BeginDisabled(!_showSilverCoffers);
|
||||
ImGui.BeginDisabled(!_silverConfig.Show);
|
||||
ImGui.Spacing();
|
||||
ImGui.ColorEdit4(Localization.Config_SilverCoffer_Color, ref _silverCofferColor, ImGuiColorEditFlags.NoInputs);
|
||||
ImGui.Checkbox(Localization.Config_SilverCoffer_Filled, ref _fillSilverCoffers);
|
||||
ImGui.ColorEdit4(Localization.Config_SilverCoffer_Color, ref _silverConfig.Color, ImGuiColorEditFlags.NoInputs);
|
||||
ImGui.Checkbox(Localization.Config_SilverCoffer_Filled, ref _silverConfig.Fill);
|
||||
ImGui.EndDisabled();
|
||||
ImGui.Unindent();
|
||||
|
||||
@ -190,13 +179,13 @@ namespace Pal.Client.Windows
|
||||
ImGui.TextWrapped(Localization.Explanation_3);
|
||||
ImGui.TextWrapped(Localization.Explanation_4);
|
||||
|
||||
ImGui.RadioButton(Localization.Config_UploadMyDiscoveries_ShowOtherTraps, ref _mode, (int)Configuration.EMode.Online);
|
||||
ImGui.RadioButton(Localization.Config_NeverUploadDiscoveries_ShowMyTraps, ref _mode, (int)Configuration.EMode.Offline);
|
||||
ImGui.RadioButton(Localization.Config_UploadMyDiscoveries_ShowOtherTraps, ref _mode, (int)EMode.Online);
|
||||
ImGui.RadioButton(Localization.Config_NeverUploadDiscoveries_ShowMyTraps, ref _mode, (int)EMode.Offline);
|
||||
saveAndClose = ImGui.Button(Localization.SaveAndClose);
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
ImGui.BeginDisabled(Service.Configuration.Mode != Configuration.EMode.Online);
|
||||
ImGui.BeginDisabled(Service.Configuration.Mode != EMode.Online);
|
||||
if (ImGui.Button(Localization.Config_TestConnection))
|
||||
TestConnection();
|
||||
|
||||
@ -294,8 +283,8 @@ namespace Pal.Client.Windows
|
||||
if (ImGui.BeginTabItem($"{Localization.ConfigTab_Renderer}###TabRenderer"))
|
||||
{
|
||||
ImGui.Text(Localization.Config_SelectRenderBackend);
|
||||
ImGui.RadioButton($"{Localization.Config_Renderer_Splatoon} ({Localization.Config_Renderer_Splatoon_Hint})", ref _renderer, (int)Configuration.ERenderer.Splatoon);
|
||||
ImGui.RadioButton($"{Localization.Config_Renderer_Simple} ({Localization.Config_Renderer_Simple_Hint})", ref _renderer, (int)Configuration.ERenderer.Simple);
|
||||
ImGui.RadioButton($"{Localization.Config_Renderer_Splatoon} ({Localization.Config_Renderer_Splatoon_Hint})", ref _renderer, (int)ERenderer.Splatoon);
|
||||
ImGui.RadioButton($"{Localization.Config_Renderer_Simple} ({Localization.Config_Renderer_Simple_Hint})", ref _renderer, (int)ERenderer.Simple);
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
@ -307,7 +296,7 @@ namespace Pal.Client.Windows
|
||||
ImGui.Text(Localization.Config_Splatoon_Test);
|
||||
ImGui.BeginDisabled(!(Service.Plugin.Renderer is IDrawDebugItems));
|
||||
if (ImGui.Button(Localization.Config_Splatoon_DrawCircles))
|
||||
(Service.Plugin.Renderer as IDrawDebugItems)?.DrawDebugItems(_trapColor, _hoardColor);
|
||||
(Service.Plugin.Renderer as IDrawDebugItems)?.DrawDebugItems(_trapConfig.Color, _hoardConfig.Color);
|
||||
ImGui.EndDisabled();
|
||||
|
||||
ImGui.EndTabItem();
|
||||
@ -328,17 +317,17 @@ namespace Pal.Client.Windows
|
||||
ImGui.Indent();
|
||||
if (plugin.FloorMarkers.TryGetValue(plugin.LastTerritory, out var currentFloor))
|
||||
{
|
||||
if (_showTraps)
|
||||
if (_trapConfig.Show)
|
||||
{
|
||||
int traps = currentFloor.Markers.Count(x => x.Type == Marker.EType.Trap);
|
||||
ImGui.Text($"{traps} known trap{(traps == 1 ? "" : "s")}");
|
||||
}
|
||||
if (_showHoard)
|
||||
if (_hoardConfig.Show)
|
||||
{
|
||||
int hoardCoffers = currentFloor.Markers.Count(x => x.Type == Marker.EType.Hoard);
|
||||
ImGui.Text($"{hoardCoffers} known hoard coffer{(hoardCoffers == 1 ? "" : "s")}");
|
||||
}
|
||||
if (_showSilverCoffers)
|
||||
if (_silverConfig.Show)
|
||||
{
|
||||
int silverCoffers = plugin.EphemeralMarkers.Count(x => x.Type == Marker.EType.SilverCoffer);
|
||||
ImGui.Text($"{silverCoffers} silver coffer{(silverCoffers == 1 ? "" : "s")} visible on current floor");
|
||||
@ -440,5 +429,36 @@ namespace Pal.Client.Windows
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class ConfigurableMarker
|
||||
{
|
||||
public bool Show;
|
||||
public Vector4 Color;
|
||||
public bool OnlyVisibleAfterPomander;
|
||||
public bool Fill;
|
||||
|
||||
public ConfigurableMarker()
|
||||
{
|
||||
}
|
||||
|
||||
public ConfigurableMarker(MarkerConfiguration config)
|
||||
{
|
||||
Show = config.Show;
|
||||
Color = ImGui.ColorConvertU32ToFloat4(config.Color);
|
||||
OnlyVisibleAfterPomander = config.OnlyVisibleAfterPomander;
|
||||
Fill = config.Fill;
|
||||
}
|
||||
|
||||
public MarkerConfiguration Build()
|
||||
{
|
||||
return new MarkerConfiguration
|
||||
{
|
||||
Show = Show,
|
||||
Color = ImGui.ColorConvertFloat4ToU32(Color),
|
||||
OnlyVisibleAfterPomander = OnlyVisibleAfterPomander,
|
||||
Fill = Fill
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user