32 Commits

Author SHA1 Message Date
9e5398105e Added a comment and TODO regarding UI bugs in IntroUI.
Some checks failed
.NET Build / build (push) Has been cancelled
2025-08-29 20:53:31 +01:00
7c2f5445e1 Bumped minimum Penumbra version due to recent API changes. 2025-08-29 20:47:15 +01:00
ed4630cd51 Users now need to re-accept the TOS if they only accepted an old version. 2025-08-29 20:47:00 +01:00
ac231ef800 Added age qualifier to TOS. 2025-08-29 20:32:38 +01:00
a3f5ee766a Merge pull request #12 from ProfessorFartsalot/main
Changed display name in advanced config UI
2025-08-29 18:01:52 +01:00
a697301895 Update main ui to match theme of snowcloak sync 2025-08-28 10:29:40 -04:00
27a09aa420 Add discord invite and update catchphrase 2025-08-27 14:16:33 -04:00
86cb7d2221 Update README.md 2025-08-27 13:34:24 -04:00
bbf79bacac Changed display name in advanced config
+ Renamed to snowcloak to support planned api changes
2025-08-27 04:23:46 -04:00
91d4cf8532 Removed logo due to AI
Some checks failed
Create Release / build (push) Has been cancelled
2025-08-26 19:22:05 +01:00
df7e6b2a51 Logo, by Dia 2025-08-26 18:18:02 +01:00
b9ce34bf10 Adjusted triangle threshold for auto pause, and made notifications for syncshell members the default as well. 2025-08-26 15:53:19 +01:00
267fb2d25c Merge pull request #11 from ProfessorFartsalot/main
Fix icons not showing correctly
2025-08-26 13:10:20 +01:00
291f005888 Fix icons not showing correctly 2025-08-26 06:17:54 -04:00
2e1bc4840b 1.8 bump
Some checks failed
Create Release / build (push) Has been cancelled
2025-08-25 18:33:08 +01:00
8526f6c240 Cosmetic "fix" 2025-08-25 18:25:41 +01:00
77d62b68b4 PenumbraAPI 5.12 fixes 2025-08-25 18:21:14 +01:00
bc72660c7f Removed RepoChange service. All configuration is now done locally without a web ping first.
Some checks failed
Create Release / build (push) Has been cancelled
2025-08-23 22:52:52 +01:00
8a27634d06 Fixed repo changer. 2025-08-23 20:02:19 +01:00
d7355c5eb9 Fixes 2025-08-23 19:56:21 +01:00
46558bf4f9 Full removal of Lop's phone home code. 2025-08-23 19:52:46 +01:00
e5dd13bc3e Bluer blue. 2025-08-23 18:04:35 +01:00
a1a3858653 Version bump: 0.1.6
Some checks failed
Create Release / build (push) Has been cancelled
2025-08-23 17:53:09 +01:00
deea0e90b1 Blue progress bar 2025-08-23 17:51:05 +01:00
d8b306148f Set autopause thresholds. Now defaults to automatically on. 500MB VRAM and 175k tris. 2025-08-23 17:45:53 +01:00
702b91b87a Version bump, I'm dumb.
Some checks failed
Create Release / build (push) Has been cancelled
2025-08-23 04:16:06 +01:00
084cfb518a Version bump, I'm dumb. 2025-08-23 04:15:51 +01:00
fa2d647a64 TOS updates to clarify account deletion 2025-08-23 04:13:51 +01:00
4d32abd5fb 100GB default size.
Some checks failed
Create Release / build (push) Has been cancelled
2025-08-22 21:27:59 +01:00
1e7e6d1858 Name fixes. 2025-08-22 21:26:51 +01:00
d749ab343b oops
Some checks failed
Create Release / build (push) Has been cancelled
2025-08-22 21:18:42 +01:00
b564887e80 Removed references to ElezenSync, properly renamed it Snowcloak now.
Some checks failed
Create Release / build (push) Has been cancelled
2025-08-22 21:17:09 +01:00
42 changed files with 168 additions and 680 deletions

View File

@@ -38,7 +38,7 @@ jobs:
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2
with: with:
repo_token: ${{ secrets.RELEASE_KEY }} repo_token: ${{ secrets.RELEASE_KEY }}
file: ./*.zip file: ./SnowcloakClient.zip
file_glob: true file_glob: true
tag: ${{ github.ref }} tag: ${{ github.ref }}
overwrite: true overwrite: true

View File

@@ -122,24 +122,24 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
public bool StorageisNTFS { get; private set; } = false; public bool StorageisNTFS { get; private set; } = false;
public void StartMareWatcher(string? marePath) public void StartMareWatcher(string? snowPath)
{ {
MareWatcher?.Dispose(); MareWatcher?.Dispose();
if (string.IsNullOrEmpty(marePath) || !Directory.Exists(marePath)) if (string.IsNullOrEmpty(snowPath) || !Directory.Exists(snowPath))
{ {
MareWatcher = null; MareWatcher = null;
Logger.LogWarning("Mare file path is not set, cannot start the FSW for Mare."); Logger.LogWarning("Snowcloak file path is not set, cannot start the FSW for Snowcloak.");
return; return;
} }
DriveInfo di = new(new DirectoryInfo(_configService.Current.CacheFolder).Root.FullName); DriveInfo di = new(new DirectoryInfo(_configService.Current.CacheFolder).Root.FullName);
StorageisNTFS = string.Equals("NTFS", di.DriveFormat, StringComparison.OrdinalIgnoreCase); StorageisNTFS = string.Equals("NTFS", di.DriveFormat, StringComparison.OrdinalIgnoreCase);
Logger.LogInformation("Mare Storage is on NTFS drive: {isNtfs}", StorageisNTFS); Logger.LogInformation("Snowcloak Storage is on NTFS drive: {isNtfs}", StorageisNTFS);
Logger.LogDebug("Initializing Mare FSW on {path}", marePath); Logger.LogDebug("Initializing Mare FSW on {path}", snowPath);
MareWatcher = new() MareWatcher = new()
{ {
Path = marePath, Path = snowPath,
InternalBufferSize = 8388608, InternalBufferSize = 8388608,
NotifyFilter = NotifyFilters.CreationTime NotifyFilter = NotifyFilters.CreationTime
| NotifyFilters.LastWrite | NotifyFilters.LastWrite
@@ -161,7 +161,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
if (string.IsNullOrEmpty(substPath)) if (string.IsNullOrEmpty(substPath))
{ {
SubstWatcher = null; SubstWatcher = null;
Logger.LogWarning("Mare file path is not set, cannot start the FSW for Mare."); Logger.LogWarning("Snowcloak file path is not set, cannot start the FSW for Snowcloak.");
return; return;
} }
@@ -197,7 +197,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
private void MareWatcher_FileChanged(object sender, FileSystemEventArgs e) private void MareWatcher_FileChanged(object sender, FileSystemEventArgs e)
{ {
Logger.LogTrace("Mare FSW: FileChanged: {change} => {path}", e.ChangeType, e.FullPath); Logger.LogTrace("Snowcloak FSW: FileChanged: {change} => {path}", e.ChangeType, e.FullPath);
if (!AllowedFileExtensions.Any(ext => e.FullPath.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) return; if (!AllowedFileExtensions.Any(ext => e.FullPath.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) return;
@@ -631,7 +631,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
if (string.IsNullOrEmpty(_configService.Current.CacheFolder) || !Directory.Exists(_configService.Current.CacheFolder)) if (string.IsNullOrEmpty(_configService.Current.CacheFolder) || !Directory.Exists(_configService.Current.CacheFolder))
{ {
cacheDirExists = false; cacheDirExists = false;
Logger.LogWarning("Elezen Cache directory is not set or does not exist."); Logger.LogWarning("Snowcloak Cache directory is not set or does not exist.");
} }
if (!penDirExists || !cacheDirExists) if (!penDirExists || !cacheDirExists)
{ {

View File

@@ -465,7 +465,7 @@ public sealed class FileCacheManager : IHostedService
if (!_ipcManager.Penumbra.APIAvailable || string.IsNullOrEmpty(_ipcManager.Penumbra.ModDirectory)) if (!_ipcManager.Penumbra.APIAvailable || string.IsNullOrEmpty(_ipcManager.Penumbra.ModDirectory))
{ {
_mareMediator.Publish(new NotificationMessage("Penumbra not connected", _mareMediator.Publish(new NotificationMessage("Penumbra not connected",
"Could not load local file cache data. Penumbra is not connected or not properly set up. Please enable and/or configure Penumbra properly to use Elezen. After, reload Elezen in the Plugin installer.", "Could not load local file cache data. Penumbra is not connected or not properly set up. Please enable and/or configure Penumbra properly to use Snowcloak. After, reload Snowcloak in the Plugin installer.",
MareConfiguration.Models.NotificationType.Error)); MareConfiguration.Models.NotificationType.Error));
} }

View File

@@ -109,7 +109,7 @@ public sealed class IpcCallerGlamourer : DisposableMediatorSubscriberBase, IIpcC
if (!apiAvailable && !_shownGlamourerUnavailable) if (!apiAvailable && !_shownGlamourerUnavailable)
{ {
_shownGlamourerUnavailable = true; _shownGlamourerUnavailable = true;
_mareMediator.Publish(new NotificationMessage("Glamourer inactive", "Your Glamourer installation is not active or out of date. Update Glamourer to continue to use Elezen. If you just updated Glamourer, ignore this message.", _mareMediator.Publish(new NotificationMessage("Glamourer inactive", "Your Glamourer installation is not active or out of date. Update Glamourer to continue to use Snowcloak. If you just updated Glamourer, ignore this message.",
NotificationType.Error)); NotificationType.Error));
} }
} }

View File

@@ -114,7 +114,7 @@ public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCa
bool penumbraAvailable = false; bool penumbraAvailable = false;
try try
{ {
penumbraAvailable = _pluginLoaded && _pluginVersion >= new Version(1, 0, 1, 0); penumbraAvailable = _pluginLoaded && _pluginVersion >= new Version(1, 5, 1, 0);
try try
{ {
penumbraAvailable &= _penumbraEnabled.Invoke(); penumbraAvailable &= _penumbraEnabled.Invoke();
@@ -136,7 +136,7 @@ public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCa
{ {
_shownPenumbraUnavailable = true; _shownPenumbraUnavailable = true;
_mareMediator.Publish(new NotificationMessage("Penumbra inactive", _mareMediator.Publish(new NotificationMessage("Penumbra inactive",
"Your Penumbra installation is not active or out of date. Update Penumbra and/or the Enable Mods setting in Penumbra to continue to use Elezen. If you just updated Penumbra, ignore this message.", "Your Penumbra installation is not active or out of date. Update Penumbra and/or the Enable Mods setting in Penumbra to continue to use Snowcloak. If you just updated Penumbra, ignore this message.",
NotificationType.Error)); NotificationType.Error));
} }
} }
@@ -225,9 +225,15 @@ public sealed class IpcCallerPenumbra : DisposableMediatorSubscriberBase, IIpcCa
return await _dalamudUtil.RunOnFrameworkThread(() => return await _dalamudUtil.RunOnFrameworkThread(() =>
{ {
Guid collId;
var collName = "ElfSync_" + uid; var collName = "ElfSync_" + uid;
var collId = _penumbraCreateNamedTemporaryCollection.Invoke(collName); PenumbraApiEc penEC = _penumbraCreateNamedTemporaryCollection.Invoke(uid, collName, out collId);
logger.LogTrace("Creating Temp Collection {collName}, GUID: {collId}", collName, collId); logger.LogTrace("Creating Temp Collection {collName}, GUID: {collId}", collName, collId);
if (penEC != PenumbraApiEc.Success)
{
logger.LogError("Failed to create temporary collection for {collName} with error code {penEC}. Please include this line in any error reports", collName, penEC);
return Guid.Empty;
}
return collId; return collId;
}).ConfigureAwait(false); }).ConfigureAwait(false);

View File

@@ -68,9 +68,9 @@ public class IpcProvider : IHostedService, IMediatorSubscriber
_logger.LogDebug("Starting IpcProvider Service"); _logger.LogDebug("Starting IpcProvider Service");
_loadFileProvider = _pi.GetIpcProvider<string, IGameObject, bool>("ElfSync.LoadMcdf"); _loadFileProvider = _pi.GetIpcProvider<string, IGameObject, bool>("ElfSync.LoadMcdf");
_loadFileProvider.RegisterFunc(LoadMcdf); _loadFileProvider.RegisterFunc(LoadMcdf);
_loadFileAsyncProvider = _pi.GetIpcProvider<string, IGameObject, Task<bool>>("ElezenSync.LoadMcdfAsync"); _loadFileAsyncProvider = _pi.GetIpcProvider<string, IGameObject, Task<bool>>("SnowcloakSync.LoadMcdfAsync");
_loadFileAsyncProvider.RegisterFunc(LoadMcdfAsync); _loadFileAsyncProvider.RegisterFunc(LoadMcdfAsync);
_handledGameAddresses = _pi.GetIpcProvider<List<nint>>("ElezenSync.GetHandledAddresses"); _handledGameAddresses = _pi.GetIpcProvider<List<nint>>("SnowcloakSync.GetHandledAddresses");
_handledGameAddresses.RegisterFunc(GetHandledAddresses); _handledGameAddresses.RegisterFunc(GetHandledAddresses);
_loadFileProviderMare = _pi.GetIpcProvider<string, IGameObject, bool>("MareSynchronos.LoadMcdf"); _loadFileProviderMare = _pi.GetIpcProvider<string, IGameObject, bool>("MareSynchronos.LoadMcdf");

View File

@@ -8,6 +8,6 @@ public static class ConfigurationExtensions
{ {
return configuration.AcceptedAgreement && configuration.InitialScanComplete return configuration.AcceptedAgreement && configuration.InitialScanComplete
&& !string.IsNullOrEmpty(configuration.CacheFolder) && !string.IsNullOrEmpty(configuration.CacheFolder)
&& Directory.Exists(configuration.CacheFolder); && Directory.Exists(configuration.CacheFolder) && configuration.AcceptedTOSVersion == configuration.ExpectedTOSVersion;
} }
} }

View File

@@ -7,6 +7,8 @@ namespace MareSynchronos.MareConfiguration.Configurations;
[Serializable] [Serializable]
public class MareConfig : IMareConfiguration public class MareConfig : IMareConfiguration
{ {
public int ExpectedTOSVersion = 2;
public int AcceptedTOSVersion { get; set; } = 0;
public bool AcceptedAgreement { get; set; } = false; public bool AcceptedAgreement { get; set; } = false;
public string CacheFolder { get; set; } = string.Empty; public string CacheFolder { get; set; } = string.Empty;
public bool DisableOptionalPluginWarnings { get; set; } = false; public bool DisableOptionalPluginWarnings { get; set; } = false;
@@ -31,7 +33,7 @@ public class MareConfig : IMareConfiguration
public bool LogPerformance { get; set; } = false; public bool LogPerformance { get; set; } = false;
public bool LogEvents { get; set; } = true; public bool LogEvents { get; set; } = true;
public bool HoldCombatApplication { get; set; } = false; public bool HoldCombatApplication { get; set; } = false;
public double MaxLocalCacheInGiB { get; set; } = 20; public double MaxLocalCacheInGiB { get; set; } = 100;
public bool OpenGposeImportOnGposeStart { get; set; } = false; public bool OpenGposeImportOnGposeStart { get; set; } = false;
public bool OpenPopupOnAdd { get; set; } = true; public bool OpenPopupOnAdd { get; set; } = true;
public int ParallelDownloads { get; set; } = 10; public int ParallelDownloads { get; set; } = 10;

View File

@@ -5,11 +5,11 @@ namespace MareSynchronos.MareConfiguration.Configurations;
public class PlayerPerformanceConfig : IMareConfiguration public class PlayerPerformanceConfig : IMareConfiguration
{ {
public int Version { get; set; } = 1; public int Version { get; set; } = 1;
public bool AutoPausePlayersExceedingThresholds { get; set; } = false; public bool AutoPausePlayersExceedingThresholds { get; set; } = true;
public bool NotifyAutoPauseDirectPairs { get; set; } = true; public bool NotifyAutoPauseDirectPairs { get; set; } = true;
public bool NotifyAutoPauseGroupPairs { get; set; } = false; public bool NotifyAutoPauseGroupPairs { get; set; } = true;
public int VRAMSizeAutoPauseThresholdMiB { get; set; } = 550; public int VRAMSizeAutoPauseThresholdMiB { get; set; } = 500;
public int TrisAutoPauseThresholdThousands { get; set; } = 375; public int TrisAutoPauseThresholdThousands { get; set; } = 400;
public bool IgnoreDirectPairs { get; set; } = true; public bool IgnoreDirectPairs { get; set; } = true;
public TextureShrinkMode TextureShrinkMode { get; set; } = TextureShrinkMode.Default; public TextureShrinkMode TextureShrinkMode { get; set; } = TextureShrinkMode.Default;
public bool TextureShrinkDeleteOriginal { get; set; } = false; public bool TextureShrinkDeleteOriginal { get; set; } = false;

View File

@@ -10,7 +10,7 @@ public class ServerConfig : IMareConfiguration
public List<ServerStorage> ServerStorage { get; set; } = new() public List<ServerStorage> ServerStorage { get; set; } = new()
{ {
{ new ServerStorage() { ServerName = ApiController.ElezenServer, ServerUri = ApiController.ElezenServiceUri } }, { new ServerStorage() { ServerName = ApiController.SnowcloakServer, ServerUri = ApiController.SnowcloakServiceUri } },
}; };
public int Version { get; set; } = 1; public int Version { get; set; } = 1;

View File

@@ -89,9 +89,9 @@ public class MarePlugin : MediatorSubscriberBase, IHostedService
public Task StartAsync(CancellationToken cancellationToken) public Task StartAsync(CancellationToken cancellationToken)
{ {
var version = Assembly.GetExecutingAssembly().GetName().Version!; var version = Assembly.GetExecutingAssembly().GetName().Version!;
Logger.LogInformation("Launching {name} {major}.{minor}.{build}.{rev}", "Elezen Sync", version.Major, version.Minor, version.Build, version.Revision); Logger.LogInformation("Launching {name} {major}.{minor}.{build}.{rev}", "Snowcloak Sync", version.Major, version.Minor, version.Build, version.Revision);
Mediator.Publish(new EventMessage(new Services.Events.Event(nameof(MarePlugin), Services.Events.EventSeverity.Informational, Mediator.Publish(new EventMessage(new Services.Events.Event(nameof(MarePlugin), Services.Events.EventSeverity.Informational,
$"Starting Elezen Sync {version.Major}.{version.Minor}.{version.Build}.{version.Revision}"))); $"Starting Snowcloak Sync {version.Major}.{version.Minor}.{version.Build}.{version.Revision}")));
Mediator.Subscribe<SwitchToMainUiMessage>(this, (msg) => { if (_launchTask == null || _launchTask.IsCompleted) _launchTask = Task.Run(WaitForPlayerAndLaunchCharacterManager); }); Mediator.Subscribe<SwitchToMainUiMessage>(this, (msg) => { if (_launchTask == null || _launchTask.IsCompleted) _launchTask = Task.Run(WaitForPlayerAndLaunchCharacterManager); });
Mediator.Subscribe<DalamudLoginMessage>(this, (_) => DalamudUtilOnLogIn()); Mediator.Subscribe<DalamudLoginMessage>(this, (_) => DalamudUtilOnLogIn());
@@ -157,7 +157,7 @@ public class MarePlugin : MediatorSubscriberBase, IHostedService
if (_mareConfigService.Current.LogLevel != LogLevel.Information) if (_mareConfigService.Current.LogLevel != LogLevel.Information)
{ {
Mediator.Publish(new NotificationMessage("Abnormal Log Level", Mediator.Publish(new NotificationMessage("Abnormal Log Level",
$"Your log level is set to '{_mareConfigService.Current.LogLevel}' which is not recommended for normal usage. Set it to '{LogLevel.Information}' in \"Elezen Settings -> Debug\" unless instructed otherwise.", $"Your log level is set to '{_mareConfigService.Current.LogLevel}' which is not recommended for normal usage. Set it to '{LogLevel.Information}' in \"Snowcloak Settings -> Debug\" unless instructed otherwise.",
MareConfiguration.Models.NotificationType.Error, TimeSpan.FromSeconds(15000))); MareConfiguration.Models.NotificationType.Error, TimeSpan.FromSeconds(15000)));
} }
#endif #endif

View File

@@ -2,7 +2,7 @@
<Project Sdk="Dalamud.NET.Sdk/13.0.0"> <Project Sdk="Dalamud.NET.Sdk/13.0.0">
<PropertyGroup> <PropertyGroup>
<AssemblyName>Snowcloak</AssemblyName> <AssemblyName>Snowcloak</AssemblyName>
<Version>0.1.1</Version> <Version>0.1.8.1</Version>
<PackageProjectUrl>https://github.com/Eauldane/SnowcloakClient/</PackageProjectUrl> <PackageProjectUrl>https://github.com/Eauldane/SnowcloakClient/</PackageProjectUrl>
</PropertyGroup> </PropertyGroup>
@@ -36,7 +36,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup Condition="!Exists('.\Penumbra.Api\Penumbra.Api.csproj')"> <ItemGroup Condition="!Exists('.\Penumbra.Api\Penumbra.Api.csproj')">
<PackageReference Include="Penumbra.Api" Version="5.10.0" /> <PackageReference Include="Penumbra.Api" Version="5.12.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="Exists('.\Glamourer.Api\Glamourer.Api.csproj')"> <ItemGroup Condition="Exists('.\Glamourer.Api\Glamourer.Api.csproj')">

View File

@@ -86,8 +86,8 @@ public class Pair : DisposableMediatorSubscriberBase
{ {
Name = name, Name = name,
OnClicked = action, OnClicked = action,
PrefixColor = 559, PrefixColor = 526,
PrefixChar = 'L' PrefixChar = 'S'
}); });
} }

View File

@@ -29,7 +29,7 @@ using MareSynchronos.Services.CharaData;
using MareSynchronos; using MareSynchronos;
namespace ElezenSync; namespace Snowcloak;
public sealed class Plugin : IDalamudPlugin public sealed class Plugin : IDalamudPlugin
{ {
@@ -40,7 +40,7 @@ public sealed class Plugin : IDalamudPlugin
#pragma warning restore CA2211, CS8618, MA0069, S1104, S2223 #pragma warning restore CA2211, CS8618, MA0069, S1104, S2223
public Action<IFramework>? RealOnFrameworkUpdate { get; set; } public Action<IFramework>? RealOnFrameworkUpdate { get; set; }
// Proxy function in the ElezenSync namespace to avoid confusion in /xlstats // Proxy function in the SnowcloakSync namespace to avoid confusion in /xlstats
public void OnFrameworkUpdate(IFramework framework) public void OnFrameworkUpdate(IFramework framework)
{ {
RealOnFrameworkUpdate?.Invoke(framework); RealOnFrameworkUpdate?.Invoke(framework);
@@ -126,7 +126,6 @@ public sealed class Plugin : IDalamudPlugin
collection.AddSingleton<BlockedCharacterHandler>(); collection.AddSingleton<BlockedCharacterHandler>();
collection.AddSingleton<IpcProvider>(); collection.AddSingleton<IpcProvider>();
collection.AddSingleton<VisibilityService>(); collection.AddSingleton<VisibilityService>();
collection.AddSingleton<RepoChangeService>();
collection.AddSingleton<EventAggregator>(); collection.AddSingleton<EventAggregator>();
collection.AddSingleton<DalamudUtilService>(); collection.AddSingleton<DalamudUtilService>();
collection.AddSingleton<DtrEntry>(); collection.AddSingleton<DtrEntry>();
@@ -210,7 +209,6 @@ public sealed class Plugin : IDalamudPlugin
collection.AddHostedService(p => p.GetRequiredService<EventAggregator>()); collection.AddHostedService(p => p.GetRequiredService<EventAggregator>());
collection.AddHostedService(p => p.GetRequiredService<MarePlugin>()); collection.AddHostedService(p => p.GetRequiredService<MarePlugin>());
collection.AddHostedService(p => p.GetRequiredService<IpcProvider>()); collection.AddHostedService(p => p.GetRequiredService<IpcProvider>());
collection.AddHostedService(p => p.GetRequiredService<RepoChangeService>());
collection.AddHostedService(p => p.GetRequiredService<NoSnapService>()); collection.AddHostedService(p => p.GetRequiredService<NoSnapService>());
}) })
.Build(); .Build();

View File

@@ -207,7 +207,7 @@ public class ChatService : DisposableMediatorSubscriberBase
} }
} }
_chatGui.PrintError($"[ElezenSync] Syncshell number #{shellNumber} not found"); _chatGui.PrintError($"[SnowcloakSync] Syncshell number #{shellNumber} not found");
} }
public void SendChatShell(int shellNumber, byte[] chatBytes) public void SendChatShell(int shellNumber, byte[] chatBytes)
@@ -236,6 +236,6 @@ public class ChatService : DisposableMediatorSubscriberBase
} }
} }
_chatGui.PrintError($"[ElezenSync] Syncshell number #{shellNumber} not found"); _chatGui.PrintError($"[SnowcloakSync] Syncshell number #{shellNumber} not found");
} }
} }

View File

@@ -15,7 +15,7 @@ namespace MareSynchronos.Services;
public sealed class CommandManagerService : IDisposable public sealed class CommandManagerService : IDisposable
{ {
private const string _commandName = "/sync"; private const string _commandName = "/sync";
private const string _commandName2 = "/elezen"; private const string _commandName2 = "/snowcloak";
private const string _ssCommandPrefix = "/ss"; private const string _ssCommandPrefix = "/ss";
@@ -42,11 +42,11 @@ public sealed class CommandManagerService : IDisposable
_mareConfigService = mareConfigService; _mareConfigService = mareConfigService;
_commandManager.AddHandler(_commandName, new CommandInfo(OnCommand) _commandManager.AddHandler(_commandName, new CommandInfo(OnCommand)
{ {
HelpMessage = "Opens the Elezen UI" HelpMessage = "Opens the Snowcloak UI"
}); });
_commandManager.AddHandler(_commandName2, new CommandInfo(OnCommand) _commandManager.AddHandler(_commandName2, new CommandInfo(OnCommand)
{ {
HelpMessage = "Opens the Elezen UI" HelpMessage = "Opens the Snowcloak UI"
}); });
// Lazy registration of all possible /ss# commands which tbf is what the game does for linkshells anyway // Lazy registration of all possible /ss# commands which tbf is what the game does for linkshells anyway
@@ -86,7 +86,7 @@ public sealed class CommandManagerService : IDisposable
{ {
if (_apiController.ServerState == WebAPI.SignalR.Utils.ServerState.Disconnecting) if (_apiController.ServerState == WebAPI.SignalR.Utils.ServerState.Disconnecting)
{ {
_mediator.Publish(new NotificationMessage("Elezen disconnecting", "Cannot use /toggle while Elezen is still disconnecting", _mediator.Publish(new NotificationMessage("Snowcloak disconnecting", "Cannot use /toggle while Snowcloak is still disconnecting",
NotificationType.Error)); NotificationType.Error));
} }

View File

@@ -462,9 +462,9 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
{ {
_logger.LogInformation("Starting DalamudUtilService"); _logger.LogInformation("Starting DalamudUtilService");
#pragma warning disable S2696 // Instance members should not write to "static" fields #pragma warning disable S2696 // Instance members should not write to "static" fields
ElezenSync.Plugin.Self.RealOnFrameworkUpdate = this.FrameworkOnUpdate; Snowcloak.Plugin.Self.RealOnFrameworkUpdate = this.FrameworkOnUpdate;
#pragma warning restore S2696 #pragma warning restore S2696
_framework.Update += ElezenSync.Plugin.Self.OnFrameworkUpdate; _framework.Update += Snowcloak.Plugin.Self.OnFrameworkUpdate;
if (IsLoggedIn) if (IsLoggedIn)
{ {
_classJobId = _clientState.LocalPlayer!.ClassJob.RowId; _classJobId = _clientState.LocalPlayer!.ClassJob.RowId;
@@ -479,7 +479,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
_logger.LogTrace("Stopping {type}", GetType()); _logger.LogTrace("Stopping {type}", GetType());
Mediator.UnsubscribeAll(this); Mediator.UnsubscribeAll(this);
_framework.Update -= ElezenSync.Plugin.Self.OnFrameworkUpdate; _framework.Update -= Snowcloak.Plugin.Self.OnFrameworkUpdate;
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@@ -41,19 +41,19 @@ public class NotificationService : DisposableMediatorSubscriberBase, IHostedServ
private void PrintErrorChat(string? message) private void PrintErrorChat(string? message)
{ {
SeStringBuilder se = new SeStringBuilder().AddText("[ElezenSync] Error: " + message); SeStringBuilder se = new SeStringBuilder().AddText("[SnowcloakSync] Error: " + message);
_chatGui.PrintError(se.BuiltString); _chatGui.PrintError(se.BuiltString);
} }
private void PrintInfoChat(string? message) private void PrintInfoChat(string? message)
{ {
SeStringBuilder se = new SeStringBuilder().AddText("[ElezenSync] Info: ").AddItalics(message ?? string.Empty); SeStringBuilder se = new SeStringBuilder().AddText("[SnowcloakSync] Info: ").AddItalics(message ?? string.Empty);
_chatGui.Print(se.BuiltString); _chatGui.Print(se.BuiltString);
} }
private void PrintWarnChat(string? message) private void PrintWarnChat(string? message)
{ {
SeStringBuilder se = new SeStringBuilder().AddText("[ElezenSync] ").AddUiForeground("Warning: " + (message ?? string.Empty), 31).AddUiForegroundOff(); SeStringBuilder se = new SeStringBuilder().AddText("[SnowcloakSync] ").AddUiForeground("Warning: " + (message ?? string.Empty), 31).AddUiForegroundOff();
_chatGui.Print(se.BuiltString); _chatGui.Print(se.BuiltString);
} }

View File

@@ -56,112 +56,9 @@ public sealed class RemoteConfigurationService
private async Task DownloadConfig() private async Task DownloadConfig()
{ {
string? jsonResponse = null; // Removed Lop's remote config code. Function exists purely to keep things clean.
LoadConfig();
foreach (var remoteUrl in ConfigSources)
{
try
{
_logger.LogDebug("Fetching {url}", remoteUrl);
using var httpClient = new HttpClient(
new HttpClientHandler
{
AllowAutoRedirect = true,
MaxAutomaticRedirections = 5
}
);
httpClient.Timeout = TimeSpan.FromSeconds(6);
var ver = Assembly.GetExecutingAssembly().GetName().Version;
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MareSynchronos", ver!.Major + "." + ver!.Minor + "." + ver!.Build));
var request = new HttpRequestMessage(HttpMethod.Get, remoteUrl);
if (remoteUrl.Equals(_configService.Current.Origin, StringComparison.Ordinal))
{
if (!string.IsNullOrEmpty(_configService.Current.ETag))
request.Headers.IfNoneMatch.Add(new EntityTagHeaderValue(_configService.Current.ETag));
if (_configService.Current.LastModified != null)
request.Headers.IfModifiedSince = _configService.Current.LastModified;
}
var response = await httpClient.SendAsync(request).ConfigureAwait(false);
if (response.StatusCode == HttpStatusCode.NotModified)
{
_logger.LogDebug("Using cached remote configuration from {url}", remoteUrl);
return;
}
response.EnsureSuccessStatusCode();
var contentType = response.Content.Headers.ContentType?.MediaType;
if (contentType == null || !contentType.Equals("application/json", StringComparison.Ordinal))
{
_logger.LogWarning("HTTP request for remote config failed: wrong MIME type");
continue;
}
_logger.LogInformation("Downloaded new configuration from {url}", remoteUrl);
_configService.Current.Origin = remoteUrl;
_configService.Current.ETag = response.Headers.ETag?.ToString() ?? string.Empty;
try
{
if (response.Content.Headers.Contains("Last-Modified"))
{
var lastModified = response.Content.Headers.GetValues("Last-Modified").First();
_configService.Current.LastModified = DateTimeOffset.Parse(lastModified, System.Globalization.CultureInfo.InvariantCulture);
}
}
catch
{
_configService.Current.LastModified = null;
}
jsonResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
break;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "HTTP request for remote config failed");
if (remoteUrl.Equals(_configService.Current.Origin, StringComparison.Ordinal))
{
_configService.Current.ETag = string.Empty;
_configService.Current.LastModified = null;
_configService.Save();
}
}
}
if (jsonResponse == null)
{
_logger.LogWarning("Could not download remote config");
return;
}
try
{
var jsonDoc = JsonNode.Parse(jsonResponse) as JsonObject;
if (jsonDoc == null)
{
_logger.LogWarning("Downloaded remote config is not a JSON object");
return;
}
LoadConfig(jsonDoc);
}
catch (JsonException ex)
{
_logger.LogWarning(ex, "Invalid JSON in remote config response");
}
} }
private static bool VerifySignature(string message, ulong ts, string signature, string pubKey) private static bool VerifySignature(string message, ulong ts, string signature, string pubKey)
@@ -172,29 +69,12 @@ public sealed class RemoteConfigurationService
return Ed25519.Verify(sig, msg, pub); return Ed25519.Verify(sig, msg, pub);
} }
private void LoadConfig(JsonObject jsonDoc) private void LoadConfig()
{ {
ulong ts = 1755859494; ulong ts = 1755859494;
//if (ts <= _configService.Current.Timestamp) var configString = "{\"mainServer\":{\"api_url\":\"wss://hub.snowcloak-sync.com/\",\"hub_url\":\"wss://hub.snowcloak-sync.com/mare\"},\"noSnap\":{\"listOfPlugins\":[\"Snapper\",\"Snappy\",\"Meddle.Plugin\"]}}";
//{
// _logger.LogDebug("Remote configuration is not newer than cached config");
// return;
//}
var signatures = jsonDoc["sig"]!.AsObject();
var configString = "{\"mainServer\":{\"api_url\":\"wss://hub.snowcloak-sync.com/\",\"hub_url\":\"wss://hub.snowcloak-sync.com/mare\"},\"repoChange\":{\"current_repo\":\"https://hub.snowcloak-sync.com/repo.json\",\"valid_repos\":[\"https://hub.snowcloak-sync.com/repo.json\"]},\"noSnap\":{\"listOfPlugins\":[\"Snapper\",\"Snappy\",\"Meddle.Plugin\"]}}";
// var configString = jsonDoc["config"]!.GetValue<string>();
// bool verified = signatures.Any(sig =>
// ConfigPublicKeys.TryGetValue(sig.Key, out var pubKey) &&
// VerifySignature(configString, ts, sig.Value!.GetValue<string>(), pubKey));
//bool verified = true;
// if (!verified)
// {
// _logger.LogWarning("Could not verify signature for downloaded remote config");
// return;
// }
_configService.Current.Configuration = JsonNode.Parse(configString)!.AsObject(); _configService.Current.Configuration = JsonNode.Parse(configString)!.AsObject();
_configService.Current.Timestamp = ts; _configService.Current.Timestamp = ts;

View File

@@ -1,12 +0,0 @@
using System.Text.Json.Serialization;
namespace MareSynchronos.Services;
public record RepoChangeConfig
{
[JsonPropertyName("current_repo")]
public string? CurrentRepo { get; set; }
[JsonPropertyName("valid_repos")]
public string[]? ValidRepos { get; set; }
}

View File

@@ -1,401 +0,0 @@
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Reflection;
namespace MareSynchronos.Services;
/* Reflection code based almost entirely on ECommons DalamudReflector
MIT License
Copyright (c) 2023 NightmareXIV
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
public sealed class RepoChangeService : IHostedService
{
#region Reflection Helpers
private const BindingFlags AllFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
private const BindingFlags StaticFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
private const BindingFlags InstanceFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
private static object GetFoP(object obj, string name)
{
Type? type = obj.GetType();
while (type != null)
{
var fieldInfo = type.GetField(name, AllFlags);
if (fieldInfo != null)
{
return fieldInfo.GetValue(obj)!;
}
var propertyInfo = type.GetProperty(name, AllFlags);
if (propertyInfo != null)
{
return propertyInfo.GetValue(obj)!;
}
type = type.BaseType;
}
throw new Exception($"Reflection GetFoP failed (not found: {obj.GetType().Name}.{name})");
}
private static T GetFoP<T>(object obj, string name)
{
return (T)GetFoP(obj, name);
}
private static void SetFoP(object obj, string name, object value)
{
var type = obj.GetType();
var field = type.GetField(name, AllFlags);
if (field != null)
{
field.SetValue(obj, value);
}
else
{
var prop = type.GetProperty(name, AllFlags)!;
if (prop == null)
throw new Exception($"Reflection SetFoP failed (not found: {type.Name}.{name})");
prop.SetValue(obj, value);
}
}
private static object? Call(object obj, string name, object[] @params, bool matchExactArgumentTypes = false)
{
MethodInfo? info;
var type = obj.GetType();
if (!matchExactArgumentTypes)
{
info = type.GetMethod(name, AllFlags);
}
else
{
info = type.GetMethod(name, AllFlags, @params.Select(x => x.GetType()).ToArray());
}
if (info == null)
throw new Exception($"Reflection Call failed (not found: {type.Name}.{name})");
return info.Invoke(obj, @params);
}
private static T Call<T>(object obj, string name, object[] @params, bool matchExactArgumentTypes = false)
{
return (T)Call(obj, name, @params, matchExactArgumentTypes)!;
}
#endregion
#region Dalamud Reflection
public object GetService(string serviceFullName)
{
return _pluginInterface.GetType().Assembly.
GetType("Dalamud.Service`1", true)!.MakeGenericType(_pluginInterface.GetType().Assembly.GetType(serviceFullName, true)!).
GetMethod("Get")!.Invoke(null, BindingFlags.Default, null, Array.Empty<object>(), null)!;
}
private object GetPluginManager()
{
return _pluginInterface.GetType().Assembly.
GetType("Dalamud.Service`1", true)!.MakeGenericType(_pluginInterface.GetType().Assembly.GetType("Dalamud.Plugin.Internal.PluginManager", true)!).
GetMethod("Get")!.Invoke(null, BindingFlags.Default, null, Array.Empty<object>(), null)!;
}
private void ReloadPluginMasters()
{
var mgr = GetService("Dalamud.Plugin.Internal.PluginManager");
var pluginReload = mgr.GetType().GetMethod("SetPluginReposFromConfigAsync", BindingFlags.Instance | BindingFlags.Public)!;
pluginReload.Invoke(mgr, [true]);
}
public void SaveDalamudConfig()
{
var conf = GetService("Dalamud.Configuration.Internal.DalamudConfiguration");
var configSave = conf?.GetType().GetMethod("QueueSave", BindingFlags.Instance | BindingFlags.Public);
configSave?.Invoke(conf, null);
}
private IEnumerable<object> GetRepoByURL(string repoURL)
{
var conf = GetService("Dalamud.Configuration.Internal.DalamudConfiguration");
var repolist = (System.Collections.IEnumerable)GetFoP(conf, "ThirdRepoList");
foreach (var r in repolist)
{
if (((string)GetFoP(r, "Url")).Equals(repoURL, StringComparison.OrdinalIgnoreCase))
yield return r;
}
}
private bool HasRepo(string repoURL)
{
var conf = GetService("Dalamud.Configuration.Internal.DalamudConfiguration");
var repolist = (System.Collections.IEnumerable)GetFoP(conf, "ThirdRepoList");
foreach (var r in repolist)
{
if (((string)GetFoP(r, "Url")).Equals(repoURL, StringComparison.OrdinalIgnoreCase))
return true;
}
return false;
}
private void AddRepo(string repoURL, bool enabled)
{
var conf = GetService("Dalamud.Configuration.Internal.DalamudConfiguration");
var repolist = (System.Collections.IEnumerable)GetFoP(conf, "ThirdRepoList");
foreach (var r in repolist)
{
if (((string)GetFoP(r, "Url")).Equals(repoURL, StringComparison.OrdinalIgnoreCase))
return;
}
var instance = Activator.CreateInstance(_pluginInterface.GetType().Assembly.GetType("Dalamud.Configuration.ThirdPartyRepoSettings")!)!;
SetFoP(instance, "Url", repoURL);
SetFoP(instance, "IsEnabled", enabled);
GetFoP<System.Collections.IList>(conf, "ThirdRepoList").Add(instance!);
}
private void RemoveRepo(string repoURL)
{
var toRemove = new List<object>();
var conf = GetService("Dalamud.Configuration.Internal.DalamudConfiguration");
var repolist = (System.Collections.IList)GetFoP(conf, "ThirdRepoList");
foreach (var r in repolist)
{
if (((string)GetFoP(r, "Url")).Equals(repoURL, StringComparison.OrdinalIgnoreCase))
toRemove.Add(r);
}
foreach (var r in toRemove)
repolist.Remove(r);
}
public List<(object LocalPlugin, string InstalledFromUrl)> GetLocalPluginsByName(string internalName)
{
List<(object LocalPlugin, string RepoURL)> result = [];
var pluginManager = GetPluginManager();
var installedPlugins = (System.Collections.IList)pluginManager.GetType().GetProperty("InstalledPlugins")!.GetValue(pluginManager)!;
foreach (var plugin in installedPlugins)
{
if (((string)plugin.GetType().GetProperty("InternalName")!.GetValue(plugin)!).Equals(internalName, StringComparison.Ordinal))
{
var type = plugin.GetType();
if (type.Name.Equals("LocalDevPlugin", StringComparison.Ordinal))
continue;
var manifest = GetFoP(plugin, "manifest");
string installedFromUrl = (string)GetFoP(manifest, "InstalledFromUrl");
result.Add((plugin, installedFromUrl));
}
}
return result;
}
#endregion
private readonly ILogger<RepoChangeService> _logger;
private readonly RemoteConfigurationService _remoteConfig;
private readonly IDalamudPluginInterface _pluginInterface;
private readonly IFramework _framework;
public RepoChangeService(ILogger<RepoChangeService> logger, RemoteConfigurationService remoteConfig, IDalamudPluginInterface pluginInterface, IFramework framework)
{
_logger = logger;
_remoteConfig = remoteConfig;
_pluginInterface = pluginInterface;
_framework = framework;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogDebug("Starting RepoChange Service");
var repoChangeConfig = await _remoteConfig.GetConfigAsync<RepoChangeConfig>("repoChange").ConfigureAwait(false) ?? new();
var currentRepo = repoChangeConfig.CurrentRepo;
var validRepos = (repoChangeConfig.ValidRepos ?? []).ToList();
if (!currentRepo.IsNullOrEmpty() && !validRepos.Contains(currentRepo, StringComparer.Ordinal))
validRepos.Add(currentRepo);
if (validRepos.Count == 0)
{
_logger.LogInformation("No valid repos configured, skipping");
return;
}
await _framework.RunOnTick(() =>
{
try
{
var internalName = Assembly.GetExecutingAssembly().GetName().Name!;
var localPlugins = GetLocalPluginsByName(internalName);
var suffix = string.Empty;
if (localPlugins.Count == 0)
{
_logger.LogInformation("Skipping: No intalled plugin found");
return;
}
var hasValidCustomRepoUrl = false;
foreach (var vr in validRepos)
{
var vrCN = vr.Replace(".json", "_CN.json", StringComparison.Ordinal);
var vrKR = vr.Replace(".json", "_KR.json", StringComparison.Ordinal);
if (HasRepo(vr) || HasRepo(vrCN) || HasRepo(vrKR))
{
hasValidCustomRepoUrl = true;
break;
}
}
List<string> oldRepos = [];
var pluginRepoUrl = localPlugins[0].InstalledFromUrl;
if (pluginRepoUrl.Contains("_CN.json", StringComparison.Ordinal))
suffix = "_CN";
else if (pluginRepoUrl.Contains("_KR.json", StringComparison.Ordinal))
suffix = "_KR";
bool hasOldPluginRepoUrl = false;
foreach (var plugin in localPlugins)
{
foreach (var vr in validRepos)
{
var validRepo = vr.Replace(".json", $"{suffix}.json");
if (!plugin.InstalledFromUrl.Equals(validRepo, StringComparison.Ordinal))
{
oldRepos.Add(plugin.InstalledFromUrl);
hasOldPluginRepoUrl = true;
}
}
}
if (hasValidCustomRepoUrl)
{
if (hasOldPluginRepoUrl)
_logger.LogInformation("Result: Repo URL is up to date, but plugin install source is incorrect");
else
_logger.LogInformation("Result: Repo URL is up to date");
}
else
{
_logger.LogInformation("Result: Repo URL needs to be replaced");
}
if (currentRepo.IsNullOrEmpty())
{
_logger.LogWarning("No current repo URL configured");
return;
}
// Pre-test plugin repo url rewriting to ensure it succeeds before replacing the custom repo URL
if (hasOldPluginRepoUrl)
{
foreach (var plugin in localPlugins)
{
var manifest = GetFoP(plugin.LocalPlugin, "manifest");
if (manifest == null)
throw new Exception("Plugin manifest is null");
var manifestFile = GetFoP(plugin.LocalPlugin, "manifestFile");
if (manifestFile == null)
throw new Exception("Plugin manifestFile is null");
var repo = GetFoP(manifest, "InstalledFromUrl");
if (((string)repo).IsNullOrEmpty())
throw new Exception("Plugin repo url is null or empty");
SetFoP(manifest, "InstalledFromUrl", repo);
}
}
if (!hasValidCustomRepoUrl)
{
try
{
foreach (var oldRepo in oldRepos)
{
_logger.LogInformation("* Removing old repo: {r}", oldRepo);
RemoveRepo(oldRepo);
}
}
finally
{
_logger.LogInformation("* Adding current repo: {r}", currentRepo);
AddRepo(currentRepo, true);
}
}
// This time do it for real, and crash the game if we fail, to avoid saving a broken state
if (hasOldPluginRepoUrl)
{
try
{
_logger.LogInformation("* Updating plugins");
foreach (var plugin in localPlugins)
{
var manifest = GetFoP(plugin.LocalPlugin, "manifest");
if (manifest == null)
throw new Exception("Plugin manifest is null");
var manifestFile = GetFoP(plugin.LocalPlugin, "manifestFile");
if (manifestFile == null)
throw new Exception("Plugin manifestFile is null");
var repo = GetFoP(manifest, "InstalledFromUrl");
if (((string)repo).IsNullOrEmpty())
throw new Exception("Plugin repo url is null or empty");
SetFoP(manifest, "InstalledFromUrl", currentRepo);
Call(manifest, "Save", [manifestFile, "RepoChange"]);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception while changing plugin install repo");
foreach (var oldRepo in oldRepos)
{
_logger.LogInformation("* Restoring old repo: {r}", oldRepo);
AddRepo(oldRepo, true);
}
}
}
if (!hasValidCustomRepoUrl || hasOldPluginRepoUrl)
{
_logger.LogInformation("* Saving dalamud config");
SaveDalamudConfig();
_logger.LogInformation("* Reloading plugin masters");
ReloadPluginMasters();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception in RepoChangeService");
}
}, default, 10, cancellationToken).ConfigureAwait(false);
_logger.LogInformation("Started RepoChangeService");
}
public Task StopAsync(CancellationToken cancellationToken)
{
_ = cancellationToken;
_logger.LogDebug("Stopping RepoChange Service");
return Task.CompletedTask;
}
}

View File

@@ -500,13 +500,13 @@ public class ServerConfigurationManager
for (int i = 0; i < _configService.Current.ServerStorage.Count; ++i) for (int i = 0; i < _configService.Current.ServerStorage.Count; ++i)
{ {
var x = _configService.Current.ServerStorage[i]; var x = _configService.Current.ServerStorage[i];
if (x.ServerUri.Equals(ApiController.ElezenServiceUri, StringComparison.OrdinalIgnoreCase)) if (x.ServerUri.Equals(ApiController.SnowcloakServiceUri, StringComparison.OrdinalIgnoreCase))
elfExists = true; elfExists = true;
} }
if (!elfExists) if (!elfExists)
{ {
_logger.LogDebug("Re-adding missing server {uri}", ApiController.ElezenServiceUri); _logger.LogDebug("Re-adding missing server {uri}", ApiController.SnowcloakServiceUri);
_configService.Current.ServerStorage.Insert(0, new ServerStorage() { ServerUri = ApiController.ElezenServiceUri, ServerName = ApiController.ElezenServer }); _configService.Current.ServerStorage.Insert(0, new ServerStorage() { ServerUri = ApiController.SnowcloakServiceUri, ServerName = ApiController.SnowcloakServer });
if (_configService.Current.CurrentServer >= 0) if (_configService.Current.CurrentServer >= 0)
_configService.Current.CurrentServer++; _configService.Current.CurrentServer++;
} }

View File

@@ -8,7 +8,7 @@
"Tags": [ "Tags": [
"customization" "customization"
], ],
"IconUrl": "https://i.imgur.com/cMKeOjm.jpeg", "IconUrl": "https://raw.githubusercontent.com/Eauldane/SnowcloakClient/refs/heads/main/MareSynchronos/images/logo.png",
"RepoUrl": "https://github.com/Eauldane/SnowcloakClient", "RepoUrl": "https://github.com/Eauldane/SnowcloakClient",
"CanUnloadAsync": true "CanUnloadAsync": true
} }

View File

@@ -79,7 +79,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
UiSharedService uiSharedService, ServerConfigurationManager serverConfigurationManager, UiSharedService uiSharedService, ServerConfigurationManager serverConfigurationManager,
DalamudUtilService dalamudUtilService, FileDialogManager fileDialogManager, PairManager pairManager, DalamudUtilService dalamudUtilService, FileDialogManager fileDialogManager, PairManager pairManager,
CharaDataGposeTogetherManager charaDataGposeTogetherManager) CharaDataGposeTogetherManager charaDataGposeTogetherManager)
: base(logger, mediator, "Elezen Character Data Hub###ElezenCharaDataUI", performanceCollectorService) : base(logger, mediator, "Snowcloak Character Data Hub###SnowcloakCharaDataUI", performanceCollectorService)
{ {
SetWindowSizeConstraints(); SetWindowSizeConstraints();

View File

@@ -60,7 +60,7 @@ public class CompactUi : WindowMediatorSubscriberBase
public CompactUi(ILogger<CompactUi> logger, UiSharedService uiShared, MareConfigService configService, ApiController apiController, PairManager pairManager, ChatService chatService, public CompactUi(ILogger<CompactUi> logger, UiSharedService uiShared, MareConfigService configService, ApiController apiController, PairManager pairManager, ChatService chatService,
ServerConfigurationManager serverManager, MareMediator mediator, FileUploadManager fileTransferManager, UidDisplayHandler uidDisplayHandler, CharaDataManager charaDataManager, ServerConfigurationManager serverManager, MareMediator mediator, FileUploadManager fileTransferManager, UidDisplayHandler uidDisplayHandler, CharaDataManager charaDataManager,
PerformanceCollectorService performanceCollectorService) PerformanceCollectorService performanceCollectorService)
: base(logger, mediator, "###ElezenSyncMainUI", performanceCollectorService) : base(logger, mediator, "###SnowcloakSyncMainUI", performanceCollectorService)
{ {
_uiSharedService = uiShared; _uiSharedService = uiShared;
_configService = configService; _configService = configService;
@@ -80,11 +80,11 @@ public class CompactUi : WindowMediatorSubscriberBase
#if DEBUG #if DEBUG
string dev = "Dev Build"; string dev = "Dev Build";
var ver = Assembly.GetExecutingAssembly().GetName().Version!; var ver = Assembly.GetExecutingAssembly().GetName().Version!;
WindowName = $"Elezen Sync {dev} ({ver.Major}.{ver.Minor}.{ver.Build})###ElezenSyncMainUIDev"; WindowName = $"Snowcloak Sync {dev} ({ver.Major}.{ver.Minor}.{ver.Build})###SnowcloakSyncMainUIDev";
Toggle(); Toggle();
#else #else
var ver = Assembly.GetExecutingAssembly().GetName().Version!; var ver = Assembly.GetExecutingAssembly().GetName().Version!;
WindowName = "Elezen Sync " + ver.Major + "." + ver.Minor + "." + ver.Build + "###ElezenSyncMainUI"; WindowName = "Snowcloak Sync " + ver.Major + "." + ver.Minor + "." + ver.Build + "###SnowcloakSyncMainUI";
#endif #endif
Mediator.Subscribe<SwitchToMainUiMessage>(this, (_) => IsOpen = true); Mediator.Subscribe<SwitchToMainUiMessage>(this, (_) => IsOpen = true);
Mediator.Subscribe<SwitchToIntroUiMessage>(this, (_) => IsOpen = false); Mediator.Subscribe<SwitchToIntroUiMessage>(this, (_) => IsOpen = false);
@@ -104,8 +104,8 @@ public class CompactUi : WindowMediatorSubscriberBase
protected override void DrawInternal() protected override void DrawInternal()
{ {
if (_serverManager.CurrentApiUrl.Equals(ApiController.ElezenServiceUri, StringComparison.Ordinal)) if (_serverManager.CurrentApiUrl.Equals(ApiController.SnowcloakServiceUri, StringComparison.Ordinal))
UiSharedService.AccentColor = new Vector4(1.0f, 0.8666f, 0.06666f, 1.0f); UiSharedService.AccentColor = new(0.4275f, 0.6863f, 1f, 1f);
else else
UiSharedService.AccentColor = ImGuiColors.ParsedGreen; UiSharedService.AccentColor = ImGuiColors.ParsedGreen;
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetStyle().WindowPadding.Y - 1f * ImGuiHelpers.GlobalScale + ImGui.GetStyle().ItemSpacing.Y); ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetStyle().WindowPadding.Y - 1f * ImGuiHelpers.GlobalScale + ImGui.GetStyle().ItemSpacing.Y);
@@ -121,8 +121,8 @@ public class CompactUi : WindowMediatorSubscriberBase
ImGui.AlignTextToFramePadding(); ImGui.AlignTextToFramePadding();
ImGui.TextColored(ImGuiColors.DalamudRed, unsupported); ImGui.TextColored(ImGuiColors.DalamudRed, unsupported);
} }
UiSharedService.ColorTextWrapped($"Your Elezen installation is out of date, the current version is {ver.Major}.{ver.Minor}.{ver.Build}. " + UiSharedService.ColorTextWrapped($"Your Snowcloak installation is out of date, the current version is {ver.Major}.{ver.Minor}.{ver.Build}. " +
$"It is highly recommended to keep Elezen up to date. Open /xlplugins and update the plugin.", ImGuiColors.DalamudRed); $"It is highly recommended to keep Snowcloak up to date. Open /xlplugins and update the plugin.", ImGuiColors.DalamudRed);
} }
using (ImRaii.PushId("header")) DrawUIDHeader(); using (ImRaii.PushId("header")) DrawUIDHeader();
@@ -525,7 +525,7 @@ public class CompactUi : WindowMediatorSubscriberBase
{ {
Mediator.Publish(new OpenSettingsUiMessage()); Mediator.Publish(new OpenSettingsUiMessage());
} }
UiSharedService.AttachToolTip("Open the Elezen Settings"); UiSharedService.AttachToolTip("Open the Snowcloak Settings");
ImGui.SameLine(); //Important to draw the uidText consistently ImGui.SameLine(); //Important to draw the uidText consistently
ImGui.SetCursorPos(originalPos); ImGui.SetCursorPos(originalPos);

View File

@@ -23,7 +23,7 @@ public class DownloadUi : WindowMediatorSubscriberBase
public DownloadUi(ILogger<DownloadUi> logger, DalamudUtilService dalamudUtilService, MareConfigService configService, public DownloadUi(ILogger<DownloadUi> logger, DalamudUtilService dalamudUtilService, MareConfigService configService,
FileUploadManager fileTransferManager, MareMediator mediator, UiSharedService uiShared, PerformanceCollectorService performanceCollectorService) FileUploadManager fileTransferManager, MareMediator mediator, UiSharedService uiShared, PerformanceCollectorService performanceCollectorService)
: base(logger, mediator, "Elezen Downloads", performanceCollectorService) : base(logger, mediator, "Snowcloak Downloads", performanceCollectorService)
{ {
_dalamudUtilService = dalamudUtilService; _dalamudUtilService = dalamudUtilService;
_configService = configService; _configService = configService;
@@ -163,13 +163,13 @@ public class DownloadUi : WindowMediatorSubscriberBase
UiSharedService.Color(0, 0, 0, transparency), 1); UiSharedService.Color(0, 0, 0, transparency), 1);
drawList.AddRectFilled(dlBarStart with { X = dlBarStart.X - dlBarBorder, Y = dlBarStart.Y - dlBarBorder }, drawList.AddRectFilled(dlBarStart with { X = dlBarStart.X - dlBarBorder, Y = dlBarStart.Y - dlBarBorder },
dlBarEnd with { X = dlBarEnd.X + dlBarBorder, Y = dlBarEnd.Y + dlBarBorder }, dlBarEnd with { X = dlBarEnd.X + dlBarBorder, Y = dlBarEnd.Y + dlBarBorder },
UiSharedService.Color(220, 220, 220, transparency), 1); UiSharedService.Color(220, 220, 255, transparency), 1);
drawList.AddRectFilled(dlBarStart, dlBarEnd, drawList.AddRectFilled(dlBarStart, dlBarEnd,
UiSharedService.Color(0, 0, 0, transparency), 1); UiSharedService.Color(0, 0, 0, transparency), 1);
var dlProgressPercent = transferredBytes / (double)totalBytes; var dlProgressPercent = transferredBytes / (double)totalBytes;
drawList.AddRectFilled(dlBarStart, drawList.AddRectFilled(dlBarStart,
dlBarEnd with { X = dlBarStart.X + (float)(dlProgressPercent * dlBarWidth) }, dlBarEnd with { X = dlBarStart.X + (float)(dlProgressPercent * dlBarWidth) },
UiSharedService.Color(50, 205, 50, transparency), 1); UiSharedService.Color(100, 100, 255, transparency), 1);
if (_configService.Current.TransferBarsShowText) if (_configService.Current.TransferBarsShowText)
{ {

View File

@@ -104,7 +104,7 @@ public sealed class DtrEntry : IDisposable, IHostedService
private IDtrBarEntry CreateEntry() private IDtrBarEntry CreateEntry()
{ {
_logger.LogTrace("Creating new DtrBar entry"); _logger.LogTrace("Creating new DtrBar entry");
var entry = _dtrBar.Get("Elezen"); var entry = _dtrBar.Get("Snowcloak");
entry.OnClick = _ => _mareMediator.Publish(new UiToggleMessage(typeof(CompactUi))); entry.OnClick = _ => _mareMediator.Publish(new UiToggleMessage(typeof(CompactUi)));
return entry; return entry;
@@ -163,19 +163,19 @@ public sealed class DtrEntry : IDisposable, IHostedService
.Select(x => string.Format("{0}", _configService.Current.PreferNoteInDtrTooltip ? x.GetNoteOrName() : x.PlayerName)); .Select(x => string.Format("{0}", _configService.Current.PreferNoteInDtrTooltip ? x.GetNoteOrName() : x.PlayerName));
} }
tooltip = $"Elezen: Connected{Environment.NewLine}----------{Environment.NewLine}{string.Join(Environment.NewLine, visiblePairs)}"; tooltip = $"Snowcloak: Connected{Environment.NewLine}----------{Environment.NewLine}{string.Join(Environment.NewLine, visiblePairs)}";
colors = _configService.Current.DtrColorsPairsInRange; colors = _configService.Current.DtrColorsPairsInRange;
} }
else else
{ {
tooltip = "Elezen: Connected"; tooltip = "Snowcloak: Connected";
colors = _configService.Current.DtrColorsDefault; colors = _configService.Current.DtrColorsDefault;
} }
} }
else else
{ {
text = RenderDtrStyle(_configService.Current.DtrStyle, "\uE04C"); text = RenderDtrStyle(_configService.Current.DtrStyle, "\uE04C");
tooltip = "Elezen: Not Connected"; tooltip = "Snowcloak: Not Connected";
colors = _configService.Current.DtrColorsNotConnected; colors = _configService.Current.DtrColorsNotConnected;
} }

View File

@@ -35,7 +35,7 @@ public class EditProfileUi : WindowMediatorSubscriberBase
ApiController apiController, UiSharedService uiSharedService, FileDialogManager fileDialogManager, ApiController apiController, UiSharedService uiSharedService, FileDialogManager fileDialogManager,
ServerConfigurationManager serverConfigurationManager, ServerConfigurationManager serverConfigurationManager,
MareProfileManager mareProfileManager, PerformanceCollectorService performanceCollectorService) MareProfileManager mareProfileManager, PerformanceCollectorService performanceCollectorService)
: base(logger, mediator, "Elezen Edit Profile###ElezenSyncEditProfileUI", performanceCollectorService) : base(logger, mediator, "Snowcloak Edit Profile###SnowcloakSyncEditProfileUI", performanceCollectorService)
{ {
IsOpen = false; IsOpen = false;
this.SizeConstraints = new() this.SizeConstraints = new()

View File

@@ -38,7 +38,7 @@ public partial class IntroUi : WindowMediatorSubscriberBase
public IntroUi(ILogger<IntroUi> logger, UiSharedService uiShared, MareConfigService configService, public IntroUi(ILogger<IntroUi> logger, UiSharedService uiShared, MareConfigService configService,
CacheMonitor fileCacheManager, ServerConfigurationManager serverConfigurationManager, MareMediator mareMediator, CacheMonitor fileCacheManager, ServerConfigurationManager serverConfigurationManager, MareMediator mareMediator,
PerformanceCollectorService performanceCollectorService, DalamudUtilService dalamudUtilService, AccountRegistrationService registerService) : base(logger, mareMediator, "Elezen Setup", performanceCollectorService) PerformanceCollectorService performanceCollectorService, DalamudUtilService dalamudUtilService, AccountRegistrationService registerService) : base(logger, mareMediator, "Snowcloak Setup", performanceCollectorService)
{ {
_uiShared = uiShared; _uiShared = uiShared;
_configService = configService; _configService = configService;
@@ -106,11 +106,12 @@ public partial class IntroUi : WindowMediatorSubscriberBase
{ {
if (_uiShared.IsInGpose) return; if (_uiShared.IsInGpose) return;
if (!_configService.Current.AcceptedAgreement && !_readFirstPage) if ((!_configService.Current.AcceptedAgreement || _configService.Current.AcceptedTOSVersion != _configService.Current.ExpectedTOSVersion) && !_readFirstPage)
{ {
_uiShared.BigText("Welcome to Elezen"); // TODO: The UI bugs hard if this page *isn't* shown before the new TOS. There's probably a way around it.
_uiShared.BigText("Welcome to Snowcloak");
ImGui.Separator(); ImGui.Separator();
UiSharedService.TextWrapped("Elezen is a plugin that will replicate your full current character state including all Penumbra mods to other paired users. " + UiSharedService.TextWrapped("Snowcloak is a plugin that will replicate your full current character state including all Penumbra mods to other paired users. " +
"Note that you will have to have Penumbra as well as Glamourer installed to use this plugin."); "Note that you will have to have Penumbra as well as Glamourer installed to use this plugin.");
UiSharedService.TextWrapped("We will have to setup a few things first before you can start using this plugin. Click on next to continue."); UiSharedService.TextWrapped("We will have to setup a few things first before you can start using this plugin. Click on next to continue.");
@@ -125,7 +126,7 @@ public partial class IntroUi : WindowMediatorSubscriberBase
#if !DEBUG #if !DEBUG
_timeoutTask = Task.Run(async () => _timeoutTask = Task.Run(async () =>
{ {
for (int i = 10; i > 0; i--) for (int i = 45; i > 0; i--)
{ {
_timeoutLabel = $"'I agree' button will be available in {i}s"; _timeoutLabel = $"'I agree' button will be available in {i}s";
await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
@@ -136,7 +137,7 @@ public partial class IntroUi : WindowMediatorSubscriberBase
#endif #endif
} }
} }
else if (!_configService.Current.AcceptedAgreement && _readFirstPage) else if ((!_configService.Current.AcceptedAgreement || _configService.Current.AcceptedTOSVersion != _configService.Current.ExpectedTOSVersion) && _readFirstPage)
{ {
using (_uiShared.UidFont.Push()) using (_uiShared.UidFont.Push())
{ {
@@ -152,6 +153,9 @@ public partial class IntroUi : WindowMediatorSubscriberBase
ImGui.SetWindowFontScale(1.0f); ImGui.SetWindowFontScale(1.0f);
ImGui.Separator(); ImGui.Separator();
UiSharedService.TextWrapped("""
To use Snowcloak, you must be over the age of 18, or 21 in some jurisdictions.
""");
UiSharedService.TextWrapped(""" UiSharedService.TextWrapped("""
All of the mod files currently active on your character as well as your current character state will be uploaded to the service you registered yourself at automatically. The plugin will exclusively upload the necessary mod files and not the whole mod. All of the mod files currently active on your character as well as your current character state will be uploaded to the service you registered yourself at automatically. The plugin will exclusively upload the necessary mod files and not the whole mod.
"""); """);
@@ -167,6 +171,15 @@ The plugin creator tried their best to keep you secure. However, there is no gua
UiSharedService.TextWrapped(""" UiSharedService.TextWrapped("""
Mod files that are saved on the service will remain on the service as long as there are requests for the files from clients. After a period of not being used, the mod files will be automatically deleted. Mod files that are saved on the service will remain on the service as long as there are requests for the files from clients. After a period of not being used, the mod files will be automatically deleted.
"""); """);
UiSharedService.TextWrapped("""
Accounts that are inactive for ninety (90) days will be deleted for privacy reasons.
""");
UiSharedService.TextWrapped("""
Snowcloak is operated from servers located in the European Union. You agree not to upload any content to the service that violates EU law; and more specifically, German law.
""");
UiSharedService.TextWrapped("""
You may delete your account at any time from within the Settings panel of the plugin. Any mods unique to you will then be removed from the server within 14 days.
""");
UiSharedService.TextWrapped(""" UiSharedService.TextWrapped("""
This service is provided as-is. This service is provided as-is.
"""); """);
@@ -177,6 +190,7 @@ This service is provided as-is.
if (ImGui.Button("I agree##toSetup")) if (ImGui.Button("I agree##toSetup"))
{ {
_configService.Current.AcceptedAgreement = true; _configService.Current.AcceptedAgreement = true;
_configService.Current.AcceptedTOSVersion = _configService.Current.ExpectedTOSVersion;
_configService.Save(); _configService.Save();
} }
} }
@@ -185,7 +199,7 @@ This service is provided as-is.
UiSharedService.TextWrapped(_timeoutLabel); UiSharedService.TextWrapped(_timeoutLabel);
} }
} }
else if (_configService.Current.AcceptedAgreement else if ((!_configService.Current.AcceptedAgreement || _configService.Current.AcceptedTOSVersion != _configService.Current.ExpectedTOSVersion)
&& (string.IsNullOrEmpty(_configService.Current.CacheFolder) && (string.IsNullOrEmpty(_configService.Current.CacheFolder)
|| !_configService.Current.InitialScanComplete || !_configService.Current.InitialScanComplete
|| !Directory.Exists(_configService.Current.CacheFolder))) || !Directory.Exists(_configService.Current.CacheFolder)))
@@ -201,11 +215,11 @@ This service is provided as-is.
} }
else else
{ {
UiSharedService.TextWrapped("To not unnecessary download files already present on your computer, Elezen will have to scan your Penumbra mod directory. " + UiSharedService.TextWrapped("To not unnecessary download files already present on your computer, Snowcloak will have to scan your Penumbra mod directory. " +
"Additionally, a local storage folder must be set where Elezen will download other character files to. " + "Additionally, a local storage folder must be set where Snowcloak will download other character files to. " +
"Once the storage folder is set and the scan complete, this page will automatically forward to registration at a service."); "Once the storage folder is set and the scan complete, this page will automatically forward to registration at a service.");
UiSharedService.TextWrapped("Note: The initial scan, depending on the amount of mods you have, might take a while. Please wait until it is completed."); UiSharedService.TextWrapped("Note: The initial scan, depending on the amount of mods you have, might take a while. Please wait until it is completed.");
UiSharedService.ColorTextWrapped("Warning: once past this step you should not delete the FileCache.csv of Elezen in the Plugin Configurations folder of Dalamud. " + UiSharedService.ColorTextWrapped("Warning: once past this step you should not delete the FileCache.csv of Snowcloak in the Plugin Configurations folder of Dalamud. " +
"Otherwise on the next launch a full re-scan of the file cache database will be initiated.", ImGuiColors.DalamudYellow); "Otherwise on the next launch a full re-scan of the file cache database will be initiated.", ImGuiColors.DalamudYellow);
UiSharedService.ColorTextWrapped("Warning: if the scan is hanging and does nothing for a long time, chances are high your Penumbra folder is not set up properly.", ImGuiColors.DalamudYellow); UiSharedService.ColorTextWrapped("Warning: if the scan is hanging and does nothing for a long time, chances are high your Penumbra folder is not set up properly.", ImGuiColors.DalamudYellow);
_uiShared.DrawCacheDirectorySetting(); _uiShared.DrawCacheDirectorySetting();
@@ -230,8 +244,8 @@ This service is provided as-is.
_configService.Current.UseCompactor = useFileCompactor; _configService.Current.UseCompactor = useFileCompactor;
_configService.Save(); _configService.Save();
} }
UiSharedService.ColorTextWrapped("The File Compactor can save a tremendeous amount of space on the hard disk for downloads through Elezen. It will incur a minor CPU penalty on download but can speed up " + UiSharedService.ColorTextWrapped("The File Compactor can save a tremendeous amount of space on the hard disk for downloads through Snowcloak. It will incur a minor CPU penalty on download but can speed up " +
"loading of other characters. It is recommended to keep it enabled. You can change this setting later anytime in the Elezen settings.", ImGuiColors.DalamudYellow); "loading of other characters. It is recommended to keep it enabled. You can change this setting later anytime in the Snowcloak settings.", ImGuiColors.DalamudYellow);
} }
} }
else if (!_uiShared.ApiController.IsConnected) else if (!_uiShared.ApiController.IsConnected)
@@ -239,7 +253,7 @@ This service is provided as-is.
using (_uiShared.UidFont.Push()) using (_uiShared.UidFont.Push())
ImGui.TextUnformatted("Service Registration"); ImGui.TextUnformatted("Service Registration");
ImGui.Separator(); ImGui.Separator();
UiSharedService.TextWrapped("To be able to use Elezen you will have to register an account."); UiSharedService.TextWrapped("To be able to use Snowcloak you will have to register an account.");
UiSharedService.TextWrapped("Refer to the instructions at the location you obtained this plugin for more information or support."); UiSharedService.TextWrapped("Refer to the instructions at the location you obtained this plugin for more information or support.");
ImGui.Separator(); ImGui.Separator();
@@ -251,8 +265,8 @@ This service is provided as-is.
{ {
ImGui.BeginDisabled(_registrationInProgress || _registrationSuccess || _secretKey.Length > 0); ImGui.BeginDisabled(_registrationInProgress || _registrationSuccess || _secretKey.Length > 0);
ImGui.Separator(); ImGui.Separator();
ImGui.TextUnformatted("If you have not used Elezen before, click below to register a new account."); ImGui.TextUnformatted("If you have not used Snowcloak before, click below to register a new account.");
if (_uiShared.IconTextButton(FontAwesomeIcon.Plus, "Register a new Elezen account")) if (_uiShared.IconTextButton(FontAwesomeIcon.Plus, "Register a new Snowcloak account"))
{ {
_registrationInProgress = true; _registrationInProgress = true;
_ = Task.Run(async () => { _ = Task.Run(async () => {

View File

@@ -22,7 +22,7 @@ public class PermissionWindowUI : WindowMediatorSubscriberBase
public PermissionWindowUI(ILogger<PermissionWindowUI> logger, Pair pair, MareMediator mediator, UiSharedService uiSharedService, public PermissionWindowUI(ILogger<PermissionWindowUI> logger, Pair pair, MareMediator mediator, UiSharedService uiSharedService,
ApiController apiController, PerformanceCollectorService performanceCollectorService) ApiController apiController, PerformanceCollectorService performanceCollectorService)
: base(logger, mediator, "Permissions for " + pair.UserData.AliasOrUID + "###ElezenSyncPermissions" + pair.UserData.UID, performanceCollectorService) : base(logger, mediator, "Permissions for " + pair.UserData.AliasOrUID + "###SnowcloakSyncPermissions" + pair.UserData.UID, performanceCollectorService)
{ {
Pair = pair; Pair = pair;
_uiSharedService = uiSharedService; _uiSharedService = uiSharedService;

View File

@@ -24,7 +24,7 @@ public class PlayerAnalysisUI : WindowMediatorSubscriberBase
public PlayerAnalysisUI(ILogger<PlayerAnalysisUI> logger, Pair pair, MareMediator mediator, UiSharedService uiSharedService, public PlayerAnalysisUI(ILogger<PlayerAnalysisUI> logger, Pair pair, MareMediator mediator, UiSharedService uiSharedService,
PerformanceCollectorService performanceCollectorService) PerformanceCollectorService performanceCollectorService)
: base(logger, mediator, "Character Data Analysis for " + pair.UserData.AliasOrUID + "###ElezenPairAnalysis" + pair.UserData.UID, performanceCollectorService) : base(logger, mediator, "Character Data Analysis for " + pair.UserData.AliasOrUID + "###SnowcloakPairAnalysis" + pair.UserData.UID, performanceCollectorService)
{ {
Pair = pair; Pair = pair;
_uiSharedService = uiSharedService; _uiSharedService = uiSharedService;

View File

@@ -29,7 +29,7 @@ public class PopoutProfileUi : WindowMediatorSubscriberBase
public PopoutProfileUi(ILogger<PopoutProfileUi> logger, MareMediator mediator, UiSharedService uiSharedService, public PopoutProfileUi(ILogger<PopoutProfileUi> logger, MareMediator mediator, UiSharedService uiSharedService,
ServerConfigurationManager serverManager, MareConfigService mareConfigService, ServerConfigurationManager serverManager, MareConfigService mareConfigService,
MareProfileManager mareProfileManager, PairManager pairManager, PerformanceCollectorService performanceCollectorService) : base(logger, mediator, "###ElezenSyncPopoutProfileUI", performanceCollectorService) MareProfileManager mareProfileManager, PairManager pairManager, PerformanceCollectorService performanceCollectorService) : base(logger, mediator, "###SnowcloakSyncPopoutProfileUI", performanceCollectorService)
{ {
_uiSharedService = uiSharedService; _uiSharedService = uiSharedService;
_serverManager = serverManager; _serverManager = serverManager;

View File

@@ -76,7 +76,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
FileCacheManager fileCacheManager, FileCacheManager fileCacheManager,
FileCompactor fileCompactor, ApiController apiController, FileCompactor fileCompactor, ApiController apiController,
IpcManager ipcManager, IpcProvider ipcProvider, CacheMonitor cacheMonitor, IpcManager ipcManager, IpcProvider ipcProvider, CacheMonitor cacheMonitor,
DalamudUtilService dalamudUtilService, AccountRegistrationService registerService) : base(logger, mediator, "Elezen Settings", performanceCollector) DalamudUtilService dalamudUtilService, AccountRegistrationService registerService) : base(logger, mediator, "Snowcloak Settings", performanceCollector)
{ {
_configService = configService; _configService = configService;
_pairManager = pairManager; _pairManager = pairManager;
@@ -581,32 +581,32 @@ public class SettingsUi : WindowMediatorSubscriberBase
_uiShared.BigText("Advanced"); _uiShared.BigText("Advanced");
bool mareApi = _configService.Current.MareAPI; bool mareApi = _configService.Current.MareAPI;
if (ImGui.Checkbox("Enable Mare Synchronos API", ref mareApi)) if (ImGui.Checkbox("Enable Snowcloak Sync API", ref mareApi))
{ {
_configService.Current.MareAPI = mareApi; _configService.Current.MareAPI = mareApi;
_configService.Save(); _configService.Save();
_ipcProvider.HandleMareImpersonation(); _ipcProvider.HandleMareImpersonation();
} }
_uiShared.DrawHelpText("Enables handling of the Mare Synchronos API. This currently includes:\n\n" + _uiShared.DrawHelpText("Enables handling of the Snowcloak Sync API. This currently includes:\n\n" +
" - MCDF loading support for other plugins\n" + " - MCDF loading support for other plugins\n" +
" - Blocking Moodles applications to paired users\n\n" + " - Blocking Moodles applications to paired users\n\n" +
"If the Mare Synchronos plugin is loaded while this option is enabled, control of its API will be relinquished."); "If the Snowcloak Sync plugin is loaded while this option is enabled, control of its API will be relinquished.");
using (_ = ImRaii.PushIndent()) using (_ = ImRaii.PushIndent())
{ {
ImGui.SameLine(300.0f * ImGuiHelpers.GlobalScale); ImGui.SameLine(300.0f * ImGuiHelpers.GlobalScale);
if (_ipcProvider.ImpersonationActive) if (_ipcProvider.ImpersonationActive)
{ {
UiSharedService.ColorTextWrapped("Mare API active!", ImGuiColors.HealerGreen); UiSharedService.ColorTextWrapped("Snowcloak API active!", ImGuiColors.HealerGreen);
} }
else else
{ {
if (!mareApi) if (!mareApi)
UiSharedService.ColorTextWrapped("Mare API inactive: Option is disabled", ImGuiColors.DalamudYellow); UiSharedService.ColorTextWrapped("Snowcloak API inactive: Option is disabled", ImGuiColors.DalamudYellow);
else if (_ipcProvider.MarePluginEnabled) else if (_ipcProvider.MarePluginEnabled)
UiSharedService.ColorTextWrapped("Mare API inactive: Mare plugin is loaded", ImGuiColors.DalamudYellow); UiSharedService.ColorTextWrapped("Snowcloak API inactive: Snowcloak plugin is loaded", ImGuiColors.DalamudYellow);
else else
UiSharedService.ColorTextWrapped("Mare API inactive: Unknown reason", ImGuiColors.DalamudRed); UiSharedService.ColorTextWrapped("Snowcloak API inactive: Unknown reason", ImGuiColors.DalamudRed);
} }
} }
@@ -728,7 +728,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
_uiShared.BigText("Storage"); _uiShared.BigText("Storage");
UiSharedService.TextWrapped("Elezen stores downloaded files from paired people permanently. This is to improve loading performance and requiring less downloads. " + UiSharedService.TextWrapped("Snowcloak stores downloaded files from paired people permanently. This is to improve loading performance and requiring less downloads. " +
"The storage governs itself by clearing data beyond the set storage size. Please set the storage size accordingly. It is not necessary to manually clear the storage."); "The storage governs itself by clearing data beyond the set storage size. Please set the storage size accordingly. It is not necessary to manually clear the storage.");
_uiShared.DrawFileScanState(); _uiShared.DrawFileScanState();
@@ -745,7 +745,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
} }
ImGui.AlignTextToFramePadding(); ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Monitoring Elezen Storage Folder: " + (_cacheMonitor.MareWatcher?.Path ?? "Not monitoring")); ImGui.TextUnformatted("Monitoring Snowcloak Storage Folder: " + (_cacheMonitor.MareWatcher?.Path ?? "Not monitoring"));
if (string.IsNullOrEmpty(_cacheMonitor.MareWatcher?.Path)) if (string.IsNullOrEmpty(_cacheMonitor.MareWatcher?.Path))
{ {
ImGui.SameLine(); ImGui.SameLine();
@@ -763,7 +763,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
_cacheMonitor.StartPenumbraWatcher(_ipcManager.Penumbra.ModDirectory); _cacheMonitor.StartPenumbraWatcher(_ipcManager.Penumbra.ModDirectory);
_cacheMonitor.InvokeScan(); _cacheMonitor.InvokeScan();
} }
UiSharedService.AttachToolTip("Attempts to resume monitoring for both Penumbra and Elezen Storage. " UiSharedService.AttachToolTip("Attempts to resume monitoring for both Penumbra and Snowcloak Storage. "
+ "Resuming the monitoring will also force a full scan to run." + Environment.NewLine + "Resuming the monitoring will also force a full scan to run." + Environment.NewLine
+ "If the button remains present after clicking it, consult /xllog for errors"); + "If the button remains present after clicking it, consult /xllog for errors");
} }
@@ -776,8 +776,8 @@ public class SettingsUi : WindowMediatorSubscriberBase
_cacheMonitor.StopMonitoring(); _cacheMonitor.StopMonitoring();
} }
} }
UiSharedService.AttachToolTip("Stops the monitoring for both Penumbra and Elezen Storage. " UiSharedService.AttachToolTip("Stops the monitoring for both Penumbra and Snowcloak Storage. "
+ "Do not stop the monitoring, unless you plan to move the Penumbra and Elezen Storage folders, to ensure correct functionality of Elezen." + Environment.NewLine + "Do not stop the monitoring, unless you plan to move the Penumbra and Snowcloak Storage folders, to ensure correct functionality of Snowcloak." + Environment.NewLine
+ "If you stop the monitoring to move folders around, resume it after you are finished moving the files." + "If you stop the monitoring to move folders around, resume it after you are finished moving the files."
+ UiSharedService.TooltipSeparator + "Hold CTRL to enable this button"); + UiSharedService.TooltipSeparator + "Hold CTRL to enable this button");
} }
@@ -794,7 +794,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
bool useFileCompactor = _configService.Current.UseCompactor; bool useFileCompactor = _configService.Current.UseCompactor;
if (!useFileCompactor && !isLinux) if (!useFileCompactor && !isLinux)
{ {
UiSharedService.ColorTextWrapped("Hint: To free up space when using Elezen consider enabling the File Compactor", ImGuiColors.DalamudYellow); UiSharedService.ColorTextWrapped("Hint: To free up space when using Snowcloak consider enabling the File Compactor", ImGuiColors.DalamudYellow);
} }
if (isLinux || !_cacheMonitor.StorageisNTFS) ImGui.BeginDisabled(); if (isLinux || !_cacheMonitor.StorageisNTFS) ImGui.BeginDisabled();
if (ImGui.Checkbox("Use file compactor", ref useFileCompactor)) if (ImGui.Checkbox("Use file compactor", ref useFileCompactor))
@@ -903,7 +903,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
} }
UiSharedService.AttachToolTip("You normally do not need to do this. THIS IS NOT SOMETHING YOU SHOULD BE DOING TO TRY TO FIX SYNC ISSUES." + Environment.NewLine UiSharedService.AttachToolTip("You normally do not need to do this. THIS IS NOT SOMETHING YOU SHOULD BE DOING TO TRY TO FIX SYNC ISSUES." + Environment.NewLine
+ "This will solely remove all downloaded data from all players and will require you to re-download everything again." + Environment.NewLine + "This will solely remove all downloaded data from all players and will require you to re-download everything again." + Environment.NewLine
+ "Elezen's storage is self-clearing and will not surpass the limit you have set it to." + Environment.NewLine + "Snowcloak's storage is self-clearing and will not surpass the limit you have set it to." + Environment.NewLine
+ "If you still think you need to do this hold CTRL while pressing the button."); + "If you still think you need to do this hold CTRL while pressing the button.");
if (!_readClearCache) if (!_readClearCache)
ImGui.EndDisabled(); ImGui.EndDisabled();
@@ -975,14 +975,14 @@ public class SettingsUi : WindowMediatorSubscriberBase
_configService.Current.EnableRightClickMenus = enableRightClickMenu; _configService.Current.EnableRightClickMenus = enableRightClickMenu;
_configService.Save(); _configService.Save();
} }
_uiShared.DrawHelpText("This will add Elezen related right click menu entries in the game UI on paired players."); _uiShared.DrawHelpText("This will add Snowcloak related right click menu entries in the game UI on paired players.");
if (ImGui.Checkbox("Display status and visible pair count in Server Info Bar", ref enableDtrEntry)) if (ImGui.Checkbox("Display status and visible pair count in Server Info Bar", ref enableDtrEntry))
{ {
_configService.Current.EnableDtrEntry = enableDtrEntry; _configService.Current.EnableDtrEntry = enableDtrEntry;
_configService.Save(); _configService.Save();
} }
_uiShared.DrawHelpText("This will add Elezen connection status and visible pair count in the Server Info Bar.\nYou can further configure this through your Dalamud Settings."); _uiShared.DrawHelpText("This will add Snowcloak connection status and visible pair count in the Server Info Bar.\nYou can further configure this through your Dalamud Settings.");
using (ImRaii.Disabled(!enableDtrEntry)) using (ImRaii.Disabled(!enableDtrEntry))
{ {
@@ -1744,7 +1744,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
if (true) // Enable registration button for all servers if (true) // Enable registration button for all servers
{ {
ImGui.SameLine(); ImGui.SameLine();
if (_uiShared.IconTextButton(FontAwesomeIcon.Plus, "Register a new Elezen account")) if (_uiShared.IconTextButton(FontAwesomeIcon.Plus, "Register a new Snowcloak account"))
{ {
_registrationInProgress = true; _registrationInProgress = true;
_ = Task.Run(async () => { _ = Task.Run(async () => {
@@ -1800,7 +1800,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
{ {
var serverName = selectedServer.ServerName; var serverName = selectedServer.ServerName;
var serverUri = selectedServer.ServerUri; var serverUri = selectedServer.ServerUri;
var isMain = string.Equals(serverName, ApiController.ElezenServer, StringComparison.OrdinalIgnoreCase); var isMain = string.Equals(serverName, ApiController.SnowcloakServer, StringComparison.OrdinalIgnoreCase);
var flags = isMain ? ImGuiInputTextFlags.ReadOnly : ImGuiInputTextFlags.None; var flags = isMain ? ImGuiInputTextFlags.ReadOnly : ImGuiInputTextFlags.None;
if (ImGui.InputText("Service URI", ref serverUri, 255, flags)) if (ImGui.InputText("Service URI", ref serverUri, 255, flags))

View File

@@ -26,7 +26,7 @@ public class StandaloneProfileUi : WindowMediatorSubscriberBase
public StandaloneProfileUi(ILogger<StandaloneProfileUi> logger, MareMediator mediator, UiSharedService uiBuilder, public StandaloneProfileUi(ILogger<StandaloneProfileUi> logger, MareMediator mediator, UiSharedService uiBuilder,
ServerConfigurationManager serverManager, MareProfileManager mareProfileManager, PairManager pairManager, Pair pair, ServerConfigurationManager serverManager, MareProfileManager mareProfileManager, PairManager pairManager, Pair pair,
PerformanceCollectorService performanceCollector) PerformanceCollectorService performanceCollector)
: base(logger, mediator, "Profile of " + pair.UserData.AliasOrUID + "##ElezenSyncStandaloneProfileUI" + pair.UserData.AliasOrUID, performanceCollector) : base(logger, mediator, "Profile of " + pair.UserData.AliasOrUID + "##SnowcloakSyncStandaloneProfileUI" + pair.UserData.AliasOrUID, performanceCollector)
{ {
_uiSharedService = uiBuilder; _uiSharedService = uiBuilder;
_serverManager = serverManager; _serverManager = serverManager;

View File

@@ -534,7 +534,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
public void DrawCacheDirectorySetting() public void DrawCacheDirectorySetting()
{ {
ColorTextWrapped("Note: The storage folder should be somewhere close to root (i.e. C:\\ElezenStorage) in a new empty folder. DO NOT point this to your game folder. DO NOT point this to your Penumbra folder.", ImGuiColors.DalamudYellow); ColorTextWrapped("Note: The storage folder should be somewhere close to root (i.e. C:\\SnowcloakStorage) in a new empty folder. DO NOT point this to your game folder. DO NOT point this to your Penumbra folder.", ImGuiColors.DalamudYellow);
var cacheDirectory = _configService.Current.CacheFolder; var cacheDirectory = _configService.Current.CacheFolder;
ImGui.SetNextItemWidth(400 * ImGuiHelpers.GlobalScale); ImGui.SetNextItemWidth(400 * ImGuiHelpers.GlobalScale);
ImGui.InputText("Storage Folder##cache", ref cacheDirectory, 255, ImGuiInputTextFlags.ReadOnly); ImGui.InputText("Storage Folder##cache", ref cacheDirectory, 255, ImGuiInputTextFlags.ReadOnly);
@@ -544,7 +544,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
{ {
if (IconButton(FontAwesomeIcon.Folder)) if (IconButton(FontAwesomeIcon.Folder))
{ {
FileDialogManager.OpenFolderDialog("Pick Elezen Storage Folder", (success, path) => FileDialogManager.OpenFolderDialog("Pick Snowcloak Storage Folder", (success, path) =>
{ {
if (!success) return; if (!success) return;
@@ -604,7 +604,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
} }
else if (_cacheDirectoryHasOtherFilesThanCache) else if (_cacheDirectoryHasOtherFilesThanCache)
{ {
ColorTextWrapped("Your selected directory has files or directories inside that are not Elezen related. Use an empty directory or a previous storage directory only.", ImGuiColors.DalamudRed); ColorTextWrapped("Your selected directory has files or directories inside that are not Snowcloak related. Use an empty directory or a previous storage directory only.", ImGuiColors.DalamudRed);
} }
else if (!_cacheDirectoryIsValidPath) else if (!_cacheDirectoryIsValidPath)
{ {
@@ -619,7 +619,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
_configService.Current.MaxLocalCacheInGiB = maxCacheSize; _configService.Current.MaxLocalCacheInGiB = maxCacheSize;
_configService.Save(); _configService.Save();
} }
DrawHelpText("The storage is automatically governed by Elezen. It will clear itself automatically once it reaches the set capacity by removing the oldest unused files. You typically do not need to clear it yourself."); DrawHelpText("The storage is automatically governed by Snowcloak. It will clear itself automatically once it reaches the set capacity by removing the oldest unused files. You typically do not need to clear it yourself.");
} }
public T? DrawCombo<T>(string comboName, IEnumerable<T> comboItems, Func<T, string> toName, public T? DrawCombo<T>(string comboName, IEnumerable<T> comboItems, Func<T, string> toName,
@@ -848,7 +848,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
if (!_penumbraExists || !_glamourerExists) if (!_penumbraExists || !_glamourerExists)
{ {
ImGui.TextColored(ImGuiColors.DalamudRed, "You need to install both Penumbra and Glamourer and keep them up to date to use Elezen."); ImGui.TextColored(ImGuiColors.DalamudRed, "You need to install both Penumbra and Glamourer and keep them up to date to use Snowcloak.");
return false; return false;
} }
else if (NoSnapService.AnyLoaded) else if (NoSnapService.AnyLoaded)

View File

@@ -50,13 +50,13 @@ public sealed class AccountRegistrationService : IDisposable
var authApiUrl = _serverManager.CurrentApiUrl; var authApiUrl = _serverManager.CurrentApiUrl;
// Override the API URL used for auth from remote config, if one is available // Override the API URL used for auth from remote config, if one is available
if (authApiUrl.Equals(ApiController.ElezenServiceUri, StringComparison.Ordinal)) if (authApiUrl.Equals(ApiController.SnowcloakServiceUri, StringComparison.Ordinal))
{ {
var config = await _remoteConfig.GetConfigAsync<HubConnectionConfig>("mainServer").ConfigureAwait(false) ?? new(); var config = await _remoteConfig.GetConfigAsync<HubConnectionConfig>("mainServer").ConfigureAwait(false) ?? new();
if (!string.IsNullOrEmpty(config.ApiUrl)) if (!string.IsNullOrEmpty(config.ApiUrl))
authApiUrl = config.ApiUrl; authApiUrl = config.ApiUrl;
else else
authApiUrl = ApiController.ElezenServiceApiUri; authApiUrl = ApiController.SnowcloakServiceApiUri;
} }
var secretKey = GenerateSecretKey(); var secretKey = GenerateSecretKey();

View File

@@ -21,10 +21,10 @@ namespace MareSynchronos.WebAPI;
#pragma warning disable MA0040 #pragma warning disable MA0040
public sealed partial class ApiController : DisposableMediatorSubscriberBase, IMareHubClient public sealed partial class ApiController : DisposableMediatorSubscriberBase, IMareHubClient
{ {
public const string ElezenServer = "Snowcloak Main Server"; public const string SnowcloakServer = "Snowcloak Main Server";
public const string ElezenServiceUri = "wss://hub.snowcloak-sync.com"; public const string SnowcloakServiceUri = "wss://hub.snowcloak-sync.com";
public const string ElezenServiceApiUri = "wss://hub.snowcloak-sync.com/"; public const string SnowcloakServiceApiUri = "wss://hub.snowcloak-sync.com/";
public const string ElezenServiceHubUri = "wss://hub.snowcloak-sync.com/mare"; public const string SnowcloakServiceHubUri = "wss://hub.snowcloak-sync.com/mare";
private readonly DalamudUtilService _dalamudUtil; private readonly DalamudUtilService _dalamudUtil;
private readonly HubFactory _hubFactory; private readonly HubFactory _hubFactory;
@@ -194,7 +194,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
Mediator.Publish(new NotificationMessage("Client incompatible", Mediator.Publish(new NotificationMessage("Client incompatible",
$"Your client is outdated ({currentClientVer.Major}.{currentClientVer.Minor}.{currentClientVer.Build}), current is: " + $"Your client is outdated ({currentClientVer.Major}.{currentClientVer.Minor}.{currentClientVer.Build}), current is: " +
$"{_connectionDto.CurrentClientVersion.Major}.{_connectionDto.CurrentClientVersion.Minor}.{_connectionDto.CurrentClientVersion.Build}. " + $"{_connectionDto.CurrentClientVersion.Major}.{_connectionDto.CurrentClientVersion.Minor}.{_connectionDto.CurrentClientVersion.Build}. " +
$"This client version is incompatible and will not be able to connect. Please update your Elezen client.", $"This client version is incompatible and will not be able to connect. Please update your Snowcloak client.",
NotificationType.Error)); NotificationType.Error));
} }
await StopConnection(ServerState.VersionMisMatch).ConfigureAwait(false); await StopConnection(ServerState.VersionMisMatch).ConfigureAwait(false);
@@ -206,7 +206,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
Mediator.Publish(new NotificationMessage("Client outdated", Mediator.Publish(new NotificationMessage("Client outdated",
$"Your client is outdated ({currentClientVer.Major}.{currentClientVer.Minor}.{currentClientVer.Build}), current is: " + $"Your client is outdated ({currentClientVer.Major}.{currentClientVer.Minor}.{currentClientVer.Build}), current is: " +
$"{_connectionDto.CurrentClientVersion.Major}.{_connectionDto.CurrentClientVersion.Minor}.{_connectionDto.CurrentClientVersion.Build}. " + $"{_connectionDto.CurrentClientVersion.Major}.{_connectionDto.CurrentClientVersion.Minor}.{_connectionDto.CurrentClientVersion.Build}. " +
$"Please keep your Elezen client up-to-date.", $"Please keep your Snowcloak client up-to-date.",
NotificationType.Warning, TimeSpan.FromSeconds(15))); NotificationType.Warning, TimeSpan.FromSeconds(15)));
} }

View File

@@ -87,14 +87,14 @@ public class HubFactory : MediatorSubscriberBase
}; };
} }
if (_serverConfigurationManager.CurrentApiUrl.Equals(ApiController.ElezenServiceUri, StringComparison.Ordinal)) if (_serverConfigurationManager.CurrentApiUrl.Equals(ApiController.SnowcloakServiceUri, StringComparison.Ordinal))
{ {
var mainServerConfig = await _remoteConfig.GetConfigAsync<HubConnectionConfig>("mainServer").ConfigureAwait(false) ?? new(); var mainServerConfig = await _remoteConfig.GetConfigAsync<HubConnectionConfig>("mainServer").ConfigureAwait(false) ?? new();
defaultConfig = mainServerConfig; defaultConfig = mainServerConfig;
if (string.IsNullOrEmpty(mainServerConfig.ApiUrl)) if (string.IsNullOrEmpty(mainServerConfig.ApiUrl))
defaultConfig.ApiUrl = ApiController.ElezenServiceApiUri; defaultConfig.ApiUrl = ApiController.SnowcloakServiceApiUri;
if (string.IsNullOrEmpty(mainServerConfig.HubUrl)) if (string.IsNullOrEmpty(mainServerConfig.HubUrl))
defaultConfig.HubUrl = ApiController.ElezenServiceHubUri; defaultConfig.HubUrl = ApiController.SnowcloakServiceHubUri;
} }
string jsonResponse; string jsonResponse;
@@ -115,7 +115,7 @@ public class HubFactory : MediatorSubscriberBase
_ => apiUrl.Scheme _ => apiUrl.Scheme
}; };
var wellKnownUrl = $"{httpScheme}://{apiUrl.Host}/.well-known/Elezen/client"; var wellKnownUrl = $"{httpScheme}://{apiUrl.Host}/.well-known/Snowcloak/client";
Logger.LogTrace("Fetching hub config for {uri} via {wk}", _serverConfigurationManager.CurrentApiUrl, wellKnownUrl); Logger.LogTrace("Fetching hub config for {uri} via {wk}", _serverConfigurationManager.CurrentApiUrl, wellKnownUrl);
using var httpClient = new HttpClient( using var httpClient = new HttpClient(

View File

@@ -73,13 +73,13 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber
var authApiUrl = _serverManager.CurrentApiUrl; var authApiUrl = _serverManager.CurrentApiUrl;
// Override the API URL used for auth from remote config, if one is available // Override the API URL used for auth from remote config, if one is available
if (authApiUrl.Equals(ApiController.ElezenServiceUri, StringComparison.Ordinal)) if (authApiUrl.Equals(ApiController.SnowcloakServiceUri, StringComparison.Ordinal))
{ {
var config = await _remoteConfig.GetConfigAsync<HubConnectionConfig>("mainServer").ConfigureAwait(false) ?? new(); var config = await _remoteConfig.GetConfigAsync<HubConnectionConfig>("mainServer").ConfigureAwait(false) ?? new();
if (!string.IsNullOrEmpty(config.ApiUrl)) if (!string.IsNullOrEmpty(config.ApiUrl))
authApiUrl = config.ApiUrl; authApiUrl = config.ApiUrl;
else else
authApiUrl = ApiController.ElezenServiceApiUri; authApiUrl = ApiController.SnowcloakServiceApiUri;
} }
try try

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -113,9 +113,9 @@
}, },
"Penumbra.Api": { "Penumbra.Api": {
"type": "Direct", "type": "Direct",
"requested": "[5.10.0, )", "requested": "[5.12.0, )",
"resolved": "5.10.0", "resolved": "5.12.0",
"contentHash": "ZRIIXQCluNlLoI4I4gNYuYXqb7p48OR1P2/LcL27owToR/A/IG0mH8Ks2HguB/Kjq4RpCinaVkyufpGxGspbTA==" "contentHash": "XGWviAZgokj2djpH50FWgM24jOTpKUuDHvd0HwrzBRY6BEMmpb3HfGIl8+BDE/DqbpH63u6aO2TvzUV6BmXT5w=="
}, },
"SonarAnalyzer.CSharp": { "SonarAnalyzer.CSharp": {
"type": "Direct", "type": "Direct",

View File

@@ -1,5 +1,6 @@
# Snowcloak Sync # Snowcloak Sync
The snow may cloak the world in silence, but come in, warm up, and reveal your true colours.
Come in from the cold, and be your true self.
A Dalamud plugin. A Dalamud plugin.
[![Discord](https://img.shields.io/discord/1408265972720078990?color=5865F2&label=discord&logo=discord&logoColor=white)](https://discord.gg/snowcloak)