remove old ref + update gitsubmodule + update 0.1.0.0 + add NoSnapService + pimpmymod + Licence AGPLv3
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,15 +2,13 @@
|
|||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
##
|
##
|
||||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
.idea
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.rsuser
|
*.rsuser
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
*.userosscache
|
*.userosscache
|
||||||
*.sln.docstates
|
*.sln.docstates
|
||||||
*.bak
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
*.userprefs
|
*.userprefs
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2022 Mare Synchronos
|
Copyright (c) 2022 Penumbra-Sync
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -5,7 +5,7 @@ VisualStudioVersion = 17.1.32328.378
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MareSynchronos", "MareSynchronos\MareSynchronos.csproj", "{13C812E9-0D42-4B95-8646-40EEBF30636F}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MareSynchronos", "MareSynchronos\MareSynchronos.csproj", "{13C812E9-0D42-4B95-8646-40EEBF30636F}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MareSynchronos.API", "UmbraAPI\MareSynchronosAPI\MareSynchronos.API.csproj", "{5A0B7434-8D89-4E90-B55C-B4A7AE1A6ADE}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MareSynchronos.API", "MareAPI\MareSynchronosAPI\MareSynchronos.API.csproj", "{5A0B7434-8D89-4E90-B55C-B4A7AE1A6ADE}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{585B740D-BA2C-429B-9CF3-B2D223423748}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{585B740D-BA2C-429B-9CF3-B2D223423748}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
|||||||
BIN
MareSynchronos/.DS_Store
vendored
Normal file
BIN
MareSynchronos/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -236,6 +236,7 @@ public sealed class FileCacheManager : IHostedService
|
|||||||
|
|
||||||
foreach (var entry in cleanedPaths)
|
foreach (var entry in cleanedPaths)
|
||||||
{
|
{
|
||||||
|
//_logger.LogDebug("Checking {path}", entry.Value);
|
||||||
|
|
||||||
if (dict.TryGetValue(entry.Value, out var entity))
|
if (dict.TryGetValue(entry.Value, out var entity))
|
||||||
{
|
{
|
||||||
@@ -365,6 +366,7 @@ public sealed class FileCacheManager : IHostedService
|
|||||||
|
|
||||||
if (!entries.Exists(u => string.Equals(u.PrefixedFilePath, fileCache.PrefixedFilePath, StringComparison.OrdinalIgnoreCase)))
|
if (!entries.Exists(u => string.Equals(u.PrefixedFilePath, fileCache.PrefixedFilePath, StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
|
//_logger.LogTrace("Adding to DB: {hash} => {path}", fileCache.Hash, fileCache.PrefixedFilePath);
|
||||||
entries.Add(fileCache);
|
entries.Add(fileCache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,6 +389,7 @@ public sealed class FileCacheManager : IHostedService
|
|||||||
private FileCacheEntity? GetValidatedFileCache(FileCacheEntity fileCache)
|
private FileCacheEntity? GetValidatedFileCache(FileCacheEntity fileCache)
|
||||||
{
|
{
|
||||||
var resultingFileCache = ReplacePathPrefixes(fileCache);
|
var resultingFileCache = ReplacePathPrefixes(fileCache);
|
||||||
|
//_logger.LogTrace("Validating {path}", fileCache.PrefixedFilePath);
|
||||||
resultingFileCache = Validate(resultingFileCache);
|
resultingFileCache = Validate(resultingFileCache);
|
||||||
return resultingFileCache;
|
return resultingFileCache;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ public sealed class IpcCallerBrio : IIpcCaller
|
|||||||
if (gameObject == null) return default;
|
if (gameObject == null) return default;
|
||||||
var data = await _dalamudUtilService.RunOnFrameworkThread(() => _brioGetModelTransform.InvokeFunc(gameObject)).ConfigureAwait(false);
|
var data = await _dalamudUtilService.RunOnFrameworkThread(() => _brioGetModelTransform.InvokeFunc(gameObject)).ConfigureAwait(false);
|
||||||
if (data.Item1 == null || data.Item2 == null || data.Item3 == null) return default;
|
if (data.Item1 == null || data.Item2 == null || data.Item3 == null) return default;
|
||||||
|
//_logger.LogDebug("Getting Transform from Actor {actor}", gameObject.Name.TextValue);
|
||||||
|
|
||||||
return new WorldData()
|
return new WorldData()
|
||||||
{
|
{
|
||||||
PositionX = data.Item1.Value.X,
|
PositionX = data.Item1.Value.X,
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ public sealed class IpcCallerMoodles : IIpcCaller
|
|||||||
|
|
||||||
_moodlesApiVersion = pi.GetIpcSubscriber<int>("Moodles.Version");
|
_moodlesApiVersion = pi.GetIpcSubscriber<int>("Moodles.Version");
|
||||||
_moodlesOnChange = pi.GetIpcSubscriber<IPlayerCharacter, object>("Moodles.StatusManagerModified");
|
_moodlesOnChange = pi.GetIpcSubscriber<IPlayerCharacter, object>("Moodles.StatusManagerModified");
|
||||||
_moodlesGetStatus = pi.GetIpcSubscriber<nint, string>("Moodles.GetStatusManagerByPtrV2");
|
_moodlesGetStatus = pi.GetIpcSubscriber<nint, string>("Moodles.GetStatusManagerByPtr");
|
||||||
_moodlesSetStatus = pi.GetIpcSubscriber<nint, string, object>("Moodles.SetStatusManagerByPtrV2");
|
_moodlesSetStatus = pi.GetIpcSubscriber<nint, string, object>("Moodles.SetStatusManagerByPtr");
|
||||||
_moodlesRevertStatus = pi.GetIpcSubscriber<nint, object>("Moodles.ClearStatusManagerByPtrV2");
|
_moodlesRevertStatus = pi.GetIpcSubscriber<nint, object>("Moodles.ClearStatusManagerByPtr");
|
||||||
|
|
||||||
_moodlesOnChange.Subscribe(OnMoodlesChange);
|
_moodlesOnChange.Subscribe(OnMoodlesChange);
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ public sealed class IpcCallerMoodles : IIpcCaller
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
APIAvailable = _moodlesApiVersion.InvokeFunc() == 3;
|
APIAvailable = _moodlesApiVersion.InvokeFunc() == 1;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ public sealed class IpcCallerPetNames : IIpcCaller
|
|||||||
_dalamudUtil = dalamudUtil;
|
_dalamudUtil = dalamudUtil;
|
||||||
_mareMediator = mareMediator;
|
_mareMediator = mareMediator;
|
||||||
|
|
||||||
_petnamesReady = pi.GetIpcSubscriber<object>("PetRenamer.OnReady");
|
_petnamesReady = pi.GetIpcSubscriber<object>("PetRenamer.Ready");
|
||||||
_petnamesDisposing = pi.GetIpcSubscriber<object>("PetRenamer.OnDisposing");
|
_petnamesDisposing = pi.GetIpcSubscriber<object>("PetRenamer.Disposing");
|
||||||
_apiVersion = pi.GetIpcSubscriber<(uint, uint)>("PetRenamer.ApiVersion");
|
_apiVersion = pi.GetIpcSubscriber<(uint, uint)>("PetRenamer.ApiVersion");
|
||||||
_enabled = pi.GetIpcSubscriber<bool>("PetRenamer.IsEnabled");
|
_enabled = pi.GetIpcSubscriber<bool>("PetRenamer.Enabled");
|
||||||
|
|
||||||
_playerDataChanged = pi.GetIpcSubscriber<string, object>("PetRenamer.OnPlayerDataChanged");
|
_playerDataChanged = pi.GetIpcSubscriber<string, object>("PetRenamer.PlayerDataChanged");
|
||||||
_getPlayerData = pi.GetIpcSubscriber<string>("PetRenamer.GetPlayerData");
|
_getPlayerData = pi.GetIpcSubscriber<string>("PetRenamer.GetPlayerData");
|
||||||
_setPlayerData = pi.GetIpcSubscriber<string, object>("PetRenamer.SetPlayerData");
|
_setPlayerData = pi.GetIpcSubscriber<string, object>("PetRenamer.SetPlayerData");
|
||||||
_clearPlayerData = pi.GetIpcSubscriber<ushort, object>("PetRenamer.ClearPlayerData");
|
_clearPlayerData = pi.GetIpcSubscriber<ushort, object>("PetRenamer.ClearPlayerData");
|
||||||
@@ -56,7 +56,7 @@ public sealed class IpcCallerPetNames : IIpcCaller
|
|||||||
APIAvailable = _enabled?.InvokeFunc() ?? false;
|
APIAvailable = _enabled?.InvokeFunc() ?? false;
|
||||||
if (APIAvailable)
|
if (APIAvailable)
|
||||||
{
|
{
|
||||||
APIAvailable = _apiVersion?.InvokeFunc() is { Item1: 4, Item2: >= 0 };
|
APIAvailable = _apiVersion?.InvokeFunc() is { Item1: 3, Item2: >= 1 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project Sdk="Dalamud.NET.Sdk/13.0.0">
|
<Project Sdk="Dalamud.NET.Sdk/13.0.0">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyName>UmbraSync</AssemblyName>
|
<AssemblyName>UmbraSync</AssemblyName>
|
||||||
<RootNamespace>UmbraSync</RootNamespace>
|
<Version>0.1.0.0</Version>
|
||||||
<Version>0.0.6</Version>
|
<PackageProjectUrl>https://git.umbra-sync.net/SirConstance/UmbraClient</PackageProjectUrl>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="PlayerData\Export\**" />
|
<Compile Remove="PlayerData\Export\**" />
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\UmbraAPI\MareSynchronosAPI\MareSynchronos.API.csproj" />
|
<ProjectReference Include="..\MareAPI\MareSynchronosAPI\MareSynchronos.API.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -27,13 +27,14 @@ public class PairHandlerFactory
|
|||||||
private readonly PluginWarningNotificationService _pluginWarningNotificationManager;
|
private readonly PluginWarningNotificationService _pluginWarningNotificationManager;
|
||||||
private readonly PairAnalyzerFactory _pairAnalyzerFactory;
|
private readonly PairAnalyzerFactory _pairAnalyzerFactory;
|
||||||
private readonly VisibilityService _visibilityService;
|
private readonly VisibilityService _visibilityService;
|
||||||
|
private readonly NoSnapService _noSnapService;
|
||||||
|
|
||||||
public PairHandlerFactory(ILoggerFactory loggerFactory, GameObjectHandlerFactory gameObjectHandlerFactory, IpcManager ipcManager,
|
public PairHandlerFactory(ILoggerFactory loggerFactory, GameObjectHandlerFactory gameObjectHandlerFactory, IpcManager ipcManager,
|
||||||
FileDownloadManagerFactory fileDownloadManagerFactory, DalamudUtilService dalamudUtilService,
|
FileDownloadManagerFactory fileDownloadManagerFactory, DalamudUtilService dalamudUtilService,
|
||||||
PluginWarningNotificationService pluginWarningNotificationManager, IHostApplicationLifetime hostApplicationLifetime,
|
PluginWarningNotificationService pluginWarningNotificationManager, IHostApplicationLifetime hostApplicationLifetime,
|
||||||
FileCacheManager fileCacheManager, MareMediator mareMediator, PlayerPerformanceService playerPerformanceService,
|
FileCacheManager fileCacheManager, MareMediator mareMediator, PlayerPerformanceService playerPerformanceService,
|
||||||
ServerConfigurationManager serverConfigManager, PairAnalyzerFactory pairAnalyzerFactory,
|
ServerConfigurationManager serverConfigManager, PairAnalyzerFactory pairAnalyzerFactory,
|
||||||
MareConfigService configService, VisibilityService visibilityService)
|
MareConfigService configService, VisibilityService visibilityService, NoSnapService noSnapService)
|
||||||
{
|
{
|
||||||
_loggerFactory = loggerFactory;
|
_loggerFactory = loggerFactory;
|
||||||
_gameObjectHandlerFactory = gameObjectHandlerFactory;
|
_gameObjectHandlerFactory = gameObjectHandlerFactory;
|
||||||
@@ -49,12 +50,13 @@ public class PairHandlerFactory
|
|||||||
_pairAnalyzerFactory = pairAnalyzerFactory;
|
_pairAnalyzerFactory = pairAnalyzerFactory;
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_visibilityService = visibilityService;
|
_visibilityService = visibilityService;
|
||||||
|
_noSnapService = noSnapService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PairHandler Create(Pair pair)
|
public PairHandler Create(Pair pair)
|
||||||
{
|
{
|
||||||
return new PairHandler(_loggerFactory.CreateLogger<PairHandler>(), pair, _pairAnalyzerFactory.Create(pair), _gameObjectHandlerFactory,
|
return new PairHandler(_loggerFactory.CreateLogger<PairHandler>(), pair, _pairAnalyzerFactory.Create(pair), _gameObjectHandlerFactory,
|
||||||
_ipcManager, _fileDownloadManagerFactory.Create(), _pluginWarningNotificationManager, _dalamudUtilService, _hostApplicationLifetime,
|
_ipcManager, _fileDownloadManagerFactory.Create(), _pluginWarningNotificationManager, _dalamudUtilService, _hostApplicationLifetime,
|
||||||
_fileCacheManager, _mareMediator, _playerPerformanceService, _serverConfigManager, _configService, _visibilityService);
|
_fileCacheManager, _mareMediator, _playerPerformanceService, _serverConfigManager, _configService, _visibilityService, _noSnapService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,6 +32,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
|
|||||||
private readonly ServerConfigurationManager _serverConfigManager;
|
private readonly ServerConfigurationManager _serverConfigManager;
|
||||||
private readonly PluginWarningNotificationService _pluginWarningNotificationManager;
|
private readonly PluginWarningNotificationService _pluginWarningNotificationManager;
|
||||||
private readonly VisibilityService _visibilityService;
|
private readonly VisibilityService _visibilityService;
|
||||||
|
private readonly NoSnapService _noSnapService;
|
||||||
private CancellationTokenSource? _applicationCancellationTokenSource = new();
|
private CancellationTokenSource? _applicationCancellationTokenSource = new();
|
||||||
private Guid _applicationId;
|
private Guid _applicationId;
|
||||||
private Task? _applicationTask;
|
private Task? _applicationTask;
|
||||||
@@ -54,7 +55,8 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
|
|||||||
FileCacheManager fileDbManager, MareMediator mediator,
|
FileCacheManager fileDbManager, MareMediator mediator,
|
||||||
PlayerPerformanceService playerPerformanceService,
|
PlayerPerformanceService playerPerformanceService,
|
||||||
ServerConfigurationManager serverConfigManager,
|
ServerConfigurationManager serverConfigManager,
|
||||||
MareConfigService configService, VisibilityService visibilityService) : base(logger, mediator)
|
MareConfigService configService, VisibilityService visibilityService,
|
||||||
|
NoSnapService noSnapService) : base(logger, mediator)
|
||||||
{
|
{
|
||||||
Pair = pair;
|
Pair = pair;
|
||||||
PairAnalyzer = pairAnalyzer;
|
PairAnalyzer = pairAnalyzer;
|
||||||
@@ -68,6 +70,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
|
|||||||
_serverConfigManager = serverConfigManager;
|
_serverConfigManager = serverConfigManager;
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_visibilityService = visibilityService;
|
_visibilityService = visibilityService;
|
||||||
|
_noSnapService = noSnapService;
|
||||||
|
|
||||||
_visibilityService.StartTracking(Pair.Ident);
|
_visibilityService.StartTracking(Pair.Ident);
|
||||||
|
|
||||||
@@ -316,6 +319,24 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RegisterGposeClones()
|
||||||
|
{
|
||||||
|
var name = PlayerName;
|
||||||
|
if (name == null)
|
||||||
|
return;
|
||||||
|
_ = _dalamudUtil.RunOnFrameworkThread(() =>
|
||||||
|
{
|
||||||
|
foreach (var actor in _dalamudUtil.GetGposeCharactersFromObjectTable())
|
||||||
|
{
|
||||||
|
if (actor == null) continue;
|
||||||
|
var gposeName = actor.Name.TextValue;
|
||||||
|
if (!name.Equals(gposeName, StringComparison.Ordinal))
|
||||||
|
continue;
|
||||||
|
_noSnapService.AddGposer(actor.ObjectIndex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async Task UndoApplicationAsync(Guid applicationId = default)
|
private async Task UndoApplicationAsync(Guid applicationId = default)
|
||||||
{
|
{
|
||||||
Logger.LogDebug($"Undoing application of {Pair.UserPair}");
|
Logger.LogDebug($"Undoing application of {Pair.UserPair}");
|
||||||
@@ -332,6 +353,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
|
|||||||
{
|
{
|
||||||
await _ipcManager.Penumbra.RemoveTemporaryCollectionAsync(Logger, applicationId, _penumbraCollection).ConfigureAwait(false);
|
await _ipcManager.Penumbra.RemoveTemporaryCollectionAsync(Logger, applicationId, _penumbraCollection).ConfigureAwait(false);
|
||||||
_penumbraCollection = Guid.Empty;
|
_penumbraCollection = Guid.Empty;
|
||||||
|
RegisterGposeClones();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dalamudUtil is { IsZoning: false, IsInCutscene: false } && !string.IsNullOrEmpty(name))
|
if (_dalamudUtil is { IsZoning: false, IsInCutscene: false } && !string.IsNullOrEmpty(name))
|
||||||
@@ -363,6 +385,10 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (_dalamudUtil.IsInCutscene && !string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
_noSnapService.AddGposerNamed(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -171,6 +171,11 @@ public class Pair : DisposableMediatorSubscriberBase
|
|||||||
if (_serverConfigurationManager.IsUidBlacklisted(UserData.UID))
|
if (_serverConfigurationManager.IsUidBlacklisted(UserData.UID))
|
||||||
HoldApplication("Blacklist", maxValue: 1);
|
HoldApplication("Blacklist", maxValue: 1);
|
||||||
|
|
||||||
|
if (NoSnapService.AnyLoaded)
|
||||||
|
HoldApplication("NoSnap", maxValue: 1);
|
||||||
|
else
|
||||||
|
UnholdApplication("NoSnap", skipApplication: true);
|
||||||
|
|
||||||
CachedPlayer.ApplyCharacterData(Guid.NewGuid(), RemoveNotSyncedFiles(LastReceivedCharacterData.DeepClone())!, forced);
|
CachedPlayer.ApplyCharacterData(Guid.NewGuid(), RemoveNotSyncedFiles(LastReceivedCharacterData.DeepClone())!, forced);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
public static Plugin Self;
|
public static Plugin Self;
|
||||||
#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 UmbraSync namespace to avoid confusion in /xlstats
|
||||||
public void OnFrameworkUpdate(IFramework framework)
|
public void OnFrameworkUpdate(IFramework framework)
|
||||||
{
|
{
|
||||||
RealOnFrameworkUpdate?.Invoke(framework);
|
RealOnFrameworkUpdate?.Invoke(framework);
|
||||||
@@ -140,6 +142,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
collection.AddSingleton<IpcCallerMare>();
|
collection.AddSingleton<IpcCallerMare>();
|
||||||
collection.AddSingleton<IpcManager>();
|
collection.AddSingleton<IpcManager>();
|
||||||
collection.AddSingleton<NotificationService>();
|
collection.AddSingleton<NotificationService>();
|
||||||
|
collection.AddSingleton<NoSnapService>();
|
||||||
|
|
||||||
collection.AddSingleton((s) => new MareConfigService(pluginInterface.ConfigDirectory.FullName));
|
collection.AddSingleton((s) => new MareConfigService(pluginInterface.ConfigDirectory.FullName));
|
||||||
collection.AddSingleton((s) => new ServerConfigService(pluginInterface.ConfigDirectory.FullName));
|
collection.AddSingleton((s) => new ServerConfigService(pluginInterface.ConfigDirectory.FullName));
|
||||||
@@ -165,6 +168,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
collection.AddSingleton<IConfigService<IMareConfiguration>>(s => s.GetRequiredService<RemoteConfigCacheService>());
|
collection.AddSingleton<IConfigService<IMareConfiguration>>(s => s.GetRequiredService<RemoteConfigCacheService>());
|
||||||
collection.AddSingleton<ConfigurationMigrator>();
|
collection.AddSingleton<ConfigurationMigrator>();
|
||||||
collection.AddSingleton<ConfigurationSaveService>();
|
collection.AddSingleton<ConfigurationSaveService>();
|
||||||
|
collection.AddSingleton<RemoteConfigurationService>();
|
||||||
|
|
||||||
collection.AddSingleton<HubFactory>();
|
collection.AddSingleton<HubFactory>();
|
||||||
|
|
||||||
@@ -205,6 +209,7 @@ 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<NoSnapService>());
|
||||||
})
|
})
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
|||||||
@@ -13,18 +13,20 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase
|
|||||||
private readonly GameObjectHandlerFactory _gameObjectHandlerFactory;
|
private readonly GameObjectHandlerFactory _gameObjectHandlerFactory;
|
||||||
private readonly DalamudUtilService _dalamudUtilService;
|
private readonly DalamudUtilService _dalamudUtilService;
|
||||||
private readonly IpcManager _ipcManager;
|
private readonly IpcManager _ipcManager;
|
||||||
|
private readonly NoSnapService _noSnapService;
|
||||||
private readonly Dictionary<string, HandledCharaDataEntry> _handledCharaData = new(StringComparer.Ordinal);
|
private readonly Dictionary<string, HandledCharaDataEntry> _handledCharaData = new(StringComparer.Ordinal);
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, HandledCharaDataEntry> HandledCharaData => _handledCharaData;
|
public IReadOnlyDictionary<string, HandledCharaDataEntry> HandledCharaData => _handledCharaData;
|
||||||
|
|
||||||
public CharaDataCharacterHandler(ILogger<CharaDataCharacterHandler> logger, MareMediator mediator,
|
public CharaDataCharacterHandler(ILogger<CharaDataCharacterHandler> logger, MareMediator mediator,
|
||||||
GameObjectHandlerFactory gameObjectHandlerFactory, DalamudUtilService dalamudUtilService,
|
GameObjectHandlerFactory gameObjectHandlerFactory, DalamudUtilService dalamudUtilService,
|
||||||
IpcManager ipcManager)
|
IpcManager ipcManager, NoSnapService noSnapService)
|
||||||
: base(logger, mediator)
|
: base(logger, mediator)
|
||||||
{
|
{
|
||||||
_gameObjectHandlerFactory = gameObjectHandlerFactory;
|
_gameObjectHandlerFactory = gameObjectHandlerFactory;
|
||||||
_dalamudUtilService = dalamudUtilService;
|
_dalamudUtilService = dalamudUtilService;
|
||||||
_ipcManager = ipcManager;
|
_ipcManager = ipcManager;
|
||||||
|
_noSnapService = noSnapService;
|
||||||
mediator.Subscribe<GposeEndMessage>(this, msg =>
|
mediator.Subscribe<GposeEndMessage>(this, msg =>
|
||||||
{
|
{
|
||||||
foreach (var chara in _handledCharaData)
|
foreach (var chara in _handledCharaData)
|
||||||
@@ -92,6 +94,7 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase
|
|||||||
_handledCharaData.Remove(handled.Name);
|
_handledCharaData.Remove(handled.Name);
|
||||||
await _dalamudUtilService.RunOnFrameworkThread(async () =>
|
await _dalamudUtilService.RunOnFrameworkThread(async () =>
|
||||||
{
|
{
|
||||||
|
RemoveGposer(handled);
|
||||||
await RevertChara(handled.Name, handled.CustomizePlus).ConfigureAwait(false);
|
await RevertChara(handled.Name, handled.CustomizePlus).ConfigureAwait(false);
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
return true;
|
return true;
|
||||||
@@ -100,6 +103,7 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase
|
|||||||
internal void AddHandledChara(HandledCharaDataEntry handledCharaDataEntry)
|
internal void AddHandledChara(HandledCharaDataEntry handledCharaDataEntry)
|
||||||
{
|
{
|
||||||
_handledCharaData.Add(handledCharaDataEntry.Name, handledCharaDataEntry);
|
_handledCharaData.Add(handledCharaDataEntry.Name, handledCharaDataEntry);
|
||||||
|
_ = _dalamudUtilService.RunOnFrameworkThread(() => AddGposer(handledCharaDataEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateHandledData(Dictionary<string, CharaDataMetaInfoExtendedDto?> newData)
|
public void UpdateHandledData(Dictionary<string, CharaDataMetaInfoExtendedDto?> newData)
|
||||||
@@ -130,4 +134,23 @@ public sealed class CharaDataCharacterHandler : DisposableMediatorSubscriberBase
|
|||||||
if (handler.Address == nint.Zero) return null;
|
if (handler.Address == nint.Zero) return null;
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int GetGposerObjectIndex(string name)
|
||||||
|
{
|
||||||
|
return _dalamudUtilService.GetGposeCharacterFromObjectTableByName(name, _dalamudUtilService.IsInGpose)?.ObjectIndex ?? -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddGposer(HandledCharaDataEntry handled)
|
||||||
|
{
|
||||||
|
int objectIndex = GetGposerObjectIndex(handled.Name);
|
||||||
|
if (objectIndex > 0)
|
||||||
|
_noSnapService.AddGposer(objectIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveGposer(HandledCharaDataEntry handled)
|
||||||
|
{
|
||||||
|
int objectIndex = GetGposerObjectIndex(handled.Name);
|
||||||
|
if (objectIndex > 0)
|
||||||
|
_noSnapService.RemoveGposer(objectIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public class ChatService : DisposableMediatorSubscriberBase
|
|||||||
{
|
{
|
||||||
var chatMsg = message.ChatMsg;
|
var chatMsg = message.ChatMsg;
|
||||||
var prefix = new SeStringBuilder();
|
var prefix = new SeStringBuilder();
|
||||||
prefix.AddText("[UmbraChat] ");
|
prefix.AddText("[BnnuyChat] ");
|
||||||
_chatGui.Print(new XivChatEntry{
|
_chatGui.Print(new XivChatEntry{
|
||||||
MessageBytes = [..prefix.Build().Encode(), ..message.ChatMsg.PayloadContent],
|
MessageBytes = [..prefix.Build().Encode(), ..message.ChatMsg.PayloadContent],
|
||||||
Name = chatMsg.SenderName,
|
Name = chatMsg.SenderName,
|
||||||
@@ -207,7 +207,7 @@ public class ChatService : DisposableMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_chatGui.PrintError($"[UmbraSync] Syncshell number #{shellNumber} not found");
|
_chatGui.PrintError($"[Umbra] 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($"[UmbraSync] Syncshell number #{shellNumber} not found");
|
_chatGui.PrintError($"[Umbra] Syncshell number #{shellNumber} not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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 = "/umbra";
|
private const string _commandName2 = "/snowcloak";
|
||||||
|
|
||||||
private const string _ssCommandPrefix = "/ss";
|
private const string _ssCommandPrefix = "/ss";
|
||||||
|
|
||||||
|
|||||||
226
MareSynchronos/Services/NoSnapService.cs
Normal file
226
MareSynchronos/Services/NoSnapService.cs
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
using Dalamud.Plugin;
|
||||||
|
using MareSynchronos.Interop.Ipc;
|
||||||
|
using MareSynchronos.MareConfiguration.Models;
|
||||||
|
using MareSynchronos.Services.Mediator;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace MareSynchronos.Services;
|
||||||
|
|
||||||
|
public sealed class NoSnapService : IHostedService, IMediatorSubscriber
|
||||||
|
{
|
||||||
|
private record NoSnapConfig
|
||||||
|
{
|
||||||
|
[JsonPropertyName("listOfPlugins")]
|
||||||
|
public string[]? ListOfPlugins { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly ILogger<NoSnapService> _logger;
|
||||||
|
private readonly IDalamudPluginInterface _pluginInterface;
|
||||||
|
private readonly Dictionary<string, bool> _listOfPlugins = new(StringComparer.Ordinal)
|
||||||
|
{
|
||||||
|
["Snapper"] = false,
|
||||||
|
["Snappy"] = false,
|
||||||
|
["Meddle.Plugin"] = false,
|
||||||
|
};
|
||||||
|
private static readonly HashSet<int> _gposers = new();
|
||||||
|
private static readonly HashSet<string> _gposersNamed = new(StringComparer.Ordinal);
|
||||||
|
private readonly IHostApplicationLifetime _hostApplicationLifetime;
|
||||||
|
private readonly DalamudUtilService _dalamudUtilService;
|
||||||
|
private readonly IpcManager _ipcManager;
|
||||||
|
private readonly RemoteConfigurationService _remoteConfig;
|
||||||
|
|
||||||
|
public static bool AnyLoaded { get; private set; } = false;
|
||||||
|
public static string ActivePlugins { get; private set; } = string.Empty;
|
||||||
|
|
||||||
|
public MareMediator Mediator { get; init; }
|
||||||
|
|
||||||
|
public NoSnapService(ILogger<NoSnapService> logger, IDalamudPluginInterface pluginInterface, MareMediator mediator,
|
||||||
|
IHostApplicationLifetime hostApplicationLifetime, DalamudUtilService dalamudUtilService, IpcManager ipcManager,
|
||||||
|
RemoteConfigurationService remoteConfig)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_pluginInterface = pluginInterface;
|
||||||
|
Mediator = mediator;
|
||||||
|
_hostApplicationLifetime = hostApplicationLifetime;
|
||||||
|
_dalamudUtilService = dalamudUtilService;
|
||||||
|
_ipcManager = ipcManager;
|
||||||
|
_remoteConfig = remoteConfig;
|
||||||
|
|
||||||
|
Mediator.Subscribe<GposeEndMessage>(this, msg => ClearGposeList());
|
||||||
|
Mediator.Subscribe<CutsceneEndMessage>(this, msg => ClearGposeList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddGposer(int objectIndex)
|
||||||
|
{
|
||||||
|
if (AnyLoaded || _hostApplicationLifetime.ApplicationStopping.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
_logger.LogTrace("Immediately reverting object index {id}", objectIndex);
|
||||||
|
RevertAndRedraw(objectIndex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogTrace("Registering gposer object index {id}", objectIndex);
|
||||||
|
lock (_gposers)
|
||||||
|
_gposers.Add(objectIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveGposer(int objectIndex)
|
||||||
|
{
|
||||||
|
_logger.LogTrace("Un-registering gposer object index {id}", objectIndex);
|
||||||
|
lock (_gposers)
|
||||||
|
_gposers.Remove(objectIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddGposerNamed(string name)
|
||||||
|
{
|
||||||
|
if (AnyLoaded || _hostApplicationLifetime.ApplicationStopping.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
_logger.LogTrace("Immediately reverting {name}", name);
|
||||||
|
RevertAndRedraw(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogTrace("Registering gposer {name}", name);
|
||||||
|
lock (_gposers)
|
||||||
|
_gposersNamed.Add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearGposeList()
|
||||||
|
{
|
||||||
|
if (_gposers.Count > 0 || _gposersNamed.Count > 0)
|
||||||
|
_logger.LogTrace("Clearing gposer list");
|
||||||
|
lock (_gposers)
|
||||||
|
_gposers.Clear();
|
||||||
|
lock (_gposersNamed)
|
||||||
|
_gposersNamed.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RevertAndRedraw(int objIndex, Guid applicationId = default)
|
||||||
|
{
|
||||||
|
if (applicationId == default)
|
||||||
|
applicationId = Guid.NewGuid();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_ipcManager.Glamourer.RevertNow(_logger, applicationId, objIndex);
|
||||||
|
_ipcManager.Penumbra.RedrawNow(_logger, applicationId, objIndex);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RevertAndRedraw(string name, Guid applicationId = default)
|
||||||
|
{
|
||||||
|
if (applicationId == default)
|
||||||
|
applicationId = Guid.NewGuid();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_ipcManager.Glamourer.RevertByNameNow(_logger, applicationId, name);
|
||||||
|
var addr = _dalamudUtilService.GetPlayerCharacterFromCachedTableByName(name);
|
||||||
|
if (addr != 0)
|
||||||
|
{
|
||||||
|
var obj = _dalamudUtilService.CreateGameObject(addr);
|
||||||
|
if (obj != null)
|
||||||
|
_ipcManager.Penumbra.RedrawNow(_logger, applicationId, obj.ObjectIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RevertGposers()
|
||||||
|
{
|
||||||
|
List<int>? gposersList = null;
|
||||||
|
List<string>? gposersList2 = null;
|
||||||
|
|
||||||
|
lock (_gposers)
|
||||||
|
{
|
||||||
|
if (_gposers.Count > 0)
|
||||||
|
{
|
||||||
|
gposersList = _gposers.ToList();
|
||||||
|
_gposers.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (_gposersNamed)
|
||||||
|
{
|
||||||
|
if (_gposersNamed.Count > 0)
|
||||||
|
{
|
||||||
|
gposersList2 = _gposersNamed.ToList();
|
||||||
|
_gposersNamed.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gposersList == null && gposersList2 == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_logger.LogInformation("Reverting gposers");
|
||||||
|
|
||||||
|
_dalamudUtilService.RunOnFrameworkThread(() =>
|
||||||
|
{
|
||||||
|
Guid applicationId = Guid.NewGuid();
|
||||||
|
|
||||||
|
foreach (var gposer in gposersList ?? [])
|
||||||
|
RevertAndRedraw(gposer, applicationId);
|
||||||
|
|
||||||
|
foreach (var gposerName in gposersList2 ?? [])
|
||||||
|
RevertAndRedraw(gposerName, applicationId);
|
||||||
|
}).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StartAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var config = await _remoteConfig.GetConfigAsync<NoSnapConfig>("noSnap").ConfigureAwait(false) ?? new();
|
||||||
|
|
||||||
|
if (config.ListOfPlugins != null)
|
||||||
|
{
|
||||||
|
_listOfPlugins.Clear();
|
||||||
|
foreach (var pluginName in config.ListOfPlugins)
|
||||||
|
_listOfPlugins.TryAdd(pluginName, value: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var pluginName in _listOfPlugins.Keys)
|
||||||
|
{
|
||||||
|
_listOfPlugins[pluginName] = PluginWatcherService.GetInitialPluginState(_pluginInterface, pluginName)?.IsLoaded ?? false;
|
||||||
|
Mediator.SubscribeKeyed<PluginChangeMessage>(this, pluginName, (msg) =>
|
||||||
|
{
|
||||||
|
_listOfPlugins[pluginName] = msg.IsLoaded;
|
||||||
|
_logger.LogDebug("{pluginName} isLoaded = {isLoaded}", pluginName, msg.IsLoaded);
|
||||||
|
Update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task StopAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
RevertGposers();
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
bool anyLoadedNow = _listOfPlugins.Values.Any(p => p);
|
||||||
|
|
||||||
|
if (AnyLoaded != anyLoadedNow)
|
||||||
|
{
|
||||||
|
AnyLoaded = anyLoadedNow;
|
||||||
|
Mediator.Publish(new RecalculatePerformanceMessage(null));
|
||||||
|
|
||||||
|
if (AnyLoaded)
|
||||||
|
{
|
||||||
|
RevertGposers();
|
||||||
|
var pluginList = string.Join(", ", _listOfPlugins.Where(p => p.Value).Select(p => p.Key));
|
||||||
|
Mediator.Publish(new NotificationMessage("Incompatible plugin loaded", $"Synced player appearances will not apply until incompatible plugins are disabled: {pluginList}.",
|
||||||
|
NotificationType.Error));
|
||||||
|
ActivePlugins = pluginList;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ActivePlugins = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,19 +41,19 @@ public class NotificationService : DisposableMediatorSubscriberBase, IHostedServ
|
|||||||
|
|
||||||
private void PrintErrorChat(string? message)
|
private void PrintErrorChat(string? message)
|
||||||
{
|
{
|
||||||
SeStringBuilder se = new SeStringBuilder().AddText("[UmbraSync] Error: " + message);
|
SeStringBuilder se = new SeStringBuilder().AddText("[Umbra] 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("[UmbraSync] Info: ").AddItalics(message ?? string.Empty);
|
SeStringBuilder se = new SeStringBuilder().AddText("[Umbra] 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("[UmbraSync] ").AddUiForeground("Warning: " + (message ?? string.Empty), 31).AddUiForegroundOff();
|
SeStringBuilder se = new SeStringBuilder().AddText("[Umbra] ").AddUiForeground("Warning: " + (message ?? string.Empty), 31).AddUiForegroundOff();
|
||||||
_chatGui.Print(se.BuiltString);
|
_chatGui.Print(se.BuiltString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
MareSynchronos/Services/RemoteConfigurationService.cs
Normal file
21
MareSynchronos/Services/RemoteConfigurationService.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace MareSynchronos.Services
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Stub minimal : renvoie toujours null (pas de conf distante).
|
||||||
|
/// </summary>
|
||||||
|
public class RemoteConfigurationService
|
||||||
|
{
|
||||||
|
private readonly ILogger<RemoteConfigurationService> _logger;
|
||||||
|
|
||||||
|
public RemoteConfigurationService(ILogger<RemoteConfigurationService> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<T?> GetConfigAsync<T>(string key) where T : class
|
||||||
|
=> Task.FromResult<T?>(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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, "###UmbraSyncSyncMainUI", performanceCollectorService)
|
: base(logger, mediator, "###UmbraSyncMainUI", 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 = $"UmbraSync {dev} ({ver.Major}.{ver.Minor}.{ver.Build})###UmbraSyncSyncMainUIDev";
|
WindowName = $"Umbra Sync {dev} ({ver.Major}.{ver.Minor}.{ver.Build})###UmbraSyncMainUIDev";
|
||||||
Toggle();
|
Toggle();
|
||||||
#else
|
#else
|
||||||
var ver = Assembly.GetExecutingAssembly().GetName().Version!;
|
var ver = Assembly.GetExecutingAssembly().GetName().Version!;
|
||||||
WindowName = "UmbraSync " + ver.Major + "." + ver.Minor + "." + ver.Build + "###UmbraSyncSyncMainUI";
|
WindowName = "Umbra Sync " + ver.Major + "." + ver.Minor + "." + ver.Build + "###UmbraSyncMainUI";
|
||||||
#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,7 +104,10 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
|
|
||||||
protected override void DrawInternal()
|
protected override void DrawInternal()
|
||||||
{
|
{
|
||||||
UiSharedService.AccentColor = new Vector4(0.2f, 0.6f, 1f, 1f); // custom blue
|
if (_serverManager.CurrentApiUrl.Equals(ApiController.UmbraServiceUri, StringComparison.Ordinal))
|
||||||
|
UiSharedService.AccentColor = new(0.4275f, 0.6863f, 1f, 1f);
|
||||||
|
else
|
||||||
|
UiSharedService.AccentColor = new Vector4(0.6f, 0.4f, 0.8f, 1f);
|
||||||
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);
|
||||||
WindowContentWidth = UiSharedService.GetWindowContentRegionWidth();
|
WindowContentWidth = UiSharedService.GetWindowContentRegionWidth();
|
||||||
if (!_apiController.IsCurrentVersion)
|
if (!_apiController.IsCurrentVersion)
|
||||||
@@ -118,8 +121,8 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGui.TextColored(ImGuiColors.DalamudRed, unsupported);
|
ImGui.TextColored(ImGuiColors.DalamudRed, unsupported);
|
||||||
}
|
}
|
||||||
UiSharedService.ColorTextWrapped($"Your UmbraSync installation is out of date, the current version is {ver.Major}.{ver.Minor}.{ver.Build}. " +
|
UiSharedService.ColorTextWrapped($"Your Umbra installation is out of date, the current version is {ver.Major}.{ver.Minor}.{ver.Build}. " +
|
||||||
$"It is highly recommended to keep UmbraSync up to date. Open /xlplugins and update the plugin.", ImGuiColors.DalamudRed);
|
$"It is highly recommended to keep Umbra up to date. Open /xlplugins and update the plugin.", ImGuiColors.DalamudRed);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (ImRaii.PushId("header")) DrawUIDHeader();
|
using (ImRaii.PushId("header")) DrawUIDHeader();
|
||||||
@@ -384,7 +387,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
{
|
{
|
||||||
ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth()) / 2 - (userSize.X + textSize.X) / 2 - ImGui.GetStyle().ItemSpacing.X / 2);
|
ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth()) / 2 - (userSize.X + textSize.X) / 2 - ImGui.GetStyle().ItemSpacing.X / 2);
|
||||||
if (!printShard) ImGui.AlignTextToFramePadding();
|
if (!printShard) ImGui.AlignTextToFramePadding();
|
||||||
ImGui.TextColored(ImGuiColors.ParsedBlue, userCount);
|
ImGui.TextColored(new Vector4(0.6f, 0.4f, 0.8f, 1f), userCount);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (!printShard) ImGui.AlignTextToFramePadding();
|
if (!printShard) ImGui.AlignTextToFramePadding();
|
||||||
ImGui.TextUnformatted("Users Online");
|
ImGui.TextUnformatted("Users Online");
|
||||||
@@ -407,7 +410,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
{
|
{
|
||||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((userSize.Y + textSize.Y) / 2 + shardTextSize.Y) / 2 - ImGui.GetStyle().ItemSpacing.Y + buttonSize.Y / 2);
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((userSize.Y + textSize.Y) / 2 + shardTextSize.Y) / 2 - ImGui.GetStyle().ItemSpacing.Y + buttonSize.Y / 2);
|
||||||
}
|
}
|
||||||
var color = UiSharedService.GetBoolColor(!_serverManager.CurrentServer!.FullPause);
|
var color = !_serverManager.CurrentServer!.FullPause ? new Vector4(0.6f, 0.4f, 0.8f, 1f) : ImGuiColors.DalamudRed;
|
||||||
var connectedIcon = !_serverManager.CurrentServer.FullPause ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink;
|
var connectedIcon = !_serverManager.CurrentServer.FullPause ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink;
|
||||||
|
|
||||||
if (_apiController.ServerState is ServerState.Connected)
|
if (_apiController.ServerState is ServerState.Connected)
|
||||||
@@ -522,7 +525,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
{
|
{
|
||||||
Mediator.Publish(new OpenSettingsUiMessage());
|
Mediator.Publish(new OpenSettingsUiMessage());
|
||||||
}
|
}
|
||||||
UiSharedService.AttachToolTip("Open the UmbraSync Settings");
|
UiSharedService.AttachToolTip("Open the Umbra Settings");
|
||||||
|
|
||||||
ImGui.SameLine(); //Important to draw the uidText consistently
|
ImGui.SameLine(); //Important to draw the uidText consistently
|
||||||
ImGui.SetCursorPos(originalPos);
|
ImGui.SetCursorPos(originalPos);
|
||||||
@@ -592,7 +595,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
{
|
{
|
||||||
ServerState.Connecting => ImGuiColors.DalamudYellow,
|
ServerState.Connecting => ImGuiColors.DalamudYellow,
|
||||||
ServerState.Reconnecting => ImGuiColors.DalamudRed,
|
ServerState.Reconnecting => ImGuiColors.DalamudRed,
|
||||||
ServerState.Connected => new Vector4(0.2f, 0.6f, 1f, 1f), // custom blue
|
ServerState.Connected => UiSharedService.AccentColor,
|
||||||
ServerState.Disconnected => ImGuiColors.DalamudYellow,
|
ServerState.Disconnected => ImGuiColors.DalamudYellow,
|
||||||
ServerState.Disconnecting => ImGuiColors.DalamudYellow,
|
ServerState.Disconnecting => ImGuiColors.DalamudYellow,
|
||||||
ServerState.Unauthorized => ImGuiColors.DalamudRed,
|
ServerState.Unauthorized => ImGuiColors.DalamudRed,
|
||||||
|
|||||||
@@ -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, 255, transparency), 1);
|
UiSharedService.Color(200, 170, 230, 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(100, 100, 255, transparency), 1);
|
UiSharedService.Color(153, 102, 204, transparency), 1);
|
||||||
|
|
||||||
if (_configService.Current.TransferBarsShowText)
|
if (_configService.Current.TransferBarsShowText)
|
||||||
{
|
{
|
||||||
@@ -198,7 +198,7 @@ public class DownloadUi : WindowMediatorSubscriberBase
|
|||||||
var drawList = ImGui.GetBackgroundDrawList();
|
var drawList = ImGui.GetBackgroundDrawList();
|
||||||
UiSharedService.DrawOutlinedFont(drawList, uploadText,
|
UiSharedService.DrawOutlinedFont(drawList, uploadText,
|
||||||
screenPos with { X = screenPos.X - textSize.X / 2f - 1, Y = screenPos.Y - textSize.Y / 2f - 1 },
|
screenPos with { X = screenPos.X - textSize.X / 2f - 1, Y = screenPos.Y - textSize.Y / 2f - 1 },
|
||||||
UiSharedService.Color(255, 255, 0, transparency),
|
UiSharedService.Color(153, 102, 204, transparency),
|
||||||
UiSharedService.Color(0, 0, 0, transparency), 2);
|
UiSharedService.Color(0, 0, 0, transparency), 2);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|||||||
@@ -106,8 +106,9 @@ 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)
|
||||||
{
|
{
|
||||||
|
// 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 Umbra");
|
_uiShared.BigText("Welcome to Umbra");
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
UiSharedService.TextWrapped("Umbra is a plugin that will replicate your full current character state including all Penumbra mods to other paired users. " +
|
UiSharedService.TextWrapped("Umbra is a plugin that will replicate your full current character state including all Penumbra mods to other paired users. " +
|
||||||
@@ -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())
|
||||||
{
|
{
|
||||||
@@ -151,6 +152,7 @@ public partial class IntroUi : WindowMediatorSubscriberBase
|
|||||||
UiSharedService.ColorText(readThis, ImGuiColors.DalamudRed);
|
UiSharedService.ColorText(readThis, ImGuiColors.DalamudRed);
|
||||||
ImGui.SetWindowFontScale(1.0f);
|
ImGui.SetWindowFontScale(1.0f);
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
UiSharedService.TextWrapped("""
|
UiSharedService.TextWrapped("""
|
||||||
To use Umbra, you must be over the age of 18, or 21 in some jurisdictions.
|
To use Umbra, you must be over the age of 18, or 21 in some jurisdictions.
|
||||||
""");
|
""");
|
||||||
@@ -170,10 +172,7 @@ public partial class IntroUi : WindowMediatorSubscriberBase
|
|||||||
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("""
|
UiSharedService.TextWrapped("""
|
||||||
Accounts that are inactive for ninety (90) days will be deleted for privacy reasons.
|
Umbra is operated from servers located in the European Union and Switzerland. You agree not to upload any content to the service that violates EU and CH law; and more specifically, German law for EU.
|
||||||
""");
|
|
||||||
UiSharedService.TextWrapped("""
|
|
||||||
Umbra 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("""
|
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.
|
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.
|
||||||
@@ -188,6 +187,7 @@ public partial class IntroUi : WindowMediatorSubscriberBase
|
|||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,7 +196,7 @@ public partial class IntroUi : WindowMediatorSubscriberBase
|
|||||||
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)))
|
||||||
|
|||||||
@@ -851,6 +851,16 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
ImGui.TextColored(ImGuiColors.DalamudRed, "You need to install both Penumbra and Glamourer and keep them up to date to use Umbra.");
|
ImGui.TextColored(ImGuiColors.DalamudRed, "You need to install both Penumbra and Glamourer and keep them up to date to use Umbra.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (NoSnapService.AnyLoaded)
|
||||||
|
{
|
||||||
|
IconText(FontAwesomeIcon.ExclamationTriangle, ImGuiColors.DalamudYellow);
|
||||||
|
ImGui.SameLine();
|
||||||
|
var cursorX = ImGui.GetCursorPosX();
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudYellow, "Synced player appearances will not apply until incompatible plugins are disabled:");
|
||||||
|
ImGui.SetCursorPosX(cursorX + 16.0f);
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudYellow, NoSnapService.ActivePlugins);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,18 @@ public sealed class AccountRegistrationService : IDisposable
|
|||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly ILogger<AccountRegistrationService> _logger;
|
private readonly ILogger<AccountRegistrationService> _logger;
|
||||||
private readonly ServerConfigurationManager _serverManager;
|
private readonly ServerConfigurationManager _serverManager;
|
||||||
|
private readonly RemoteConfigurationService _remoteConfig;
|
||||||
|
|
||||||
private string GenerateSecretKey()
|
private string GenerateSecretKey()
|
||||||
{
|
{
|
||||||
return Convert.ToHexString(SHA256.HashData(RandomNumberGenerator.GetBytes(64)));
|
return Convert.ToHexString(SHA256.HashData(RandomNumberGenerator.GetBytes(64)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccountRegistrationService(ILogger<AccountRegistrationService> logger, ServerConfigurationManager serverManager)
|
public AccountRegistrationService(ILogger<AccountRegistrationService> logger, ServerConfigurationManager serverManager, RemoteConfigurationService remoteConfig)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_serverManager = serverManager;
|
_serverManager = serverManager;
|
||||||
|
_remoteConfig = remoteConfig;
|
||||||
_httpClient = new(
|
_httpClient = new(
|
||||||
new HttpClientHandler
|
new HttpClientHandler
|
||||||
{
|
{
|
||||||
@@ -45,10 +47,22 @@ public sealed class AccountRegistrationService : IDisposable
|
|||||||
|
|
||||||
public async Task<RegisterReplyDto> RegisterAccount(CancellationToken token)
|
public async Task<RegisterReplyDto> RegisterAccount(CancellationToken token)
|
||||||
{
|
{
|
||||||
|
var authApiUrl = _serverManager.CurrentApiUrl;
|
||||||
|
|
||||||
|
// Override the API URL used for auth from remote config, if one is available
|
||||||
|
if (authApiUrl.Equals(ApiController.UmbraServiceUri, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
var config = await _remoteConfig.GetConfigAsync<HubConnectionConfig>("mainServer").ConfigureAwait(false) ?? new();
|
||||||
|
if (!string.IsNullOrEmpty(config.ApiUrl))
|
||||||
|
authApiUrl = config.ApiUrl;
|
||||||
|
else
|
||||||
|
authApiUrl = ApiController.UmbraServiceApiUri;
|
||||||
|
}
|
||||||
|
|
||||||
var secretKey = GenerateSecretKey();
|
var secretKey = GenerateSecretKey();
|
||||||
var hashedSecretKey = secretKey.GetHash256();
|
var hashedSecretKey = secretKey.GetHash256();
|
||||||
|
|
||||||
Uri postUri = MareAuth.AuthRegisterV2FullPath(new Uri(_serverManager.CurrentApiUrl
|
Uri postUri = MareAuth.AuthRegisterV2FullPath(new Uri(authApiUrl
|
||||||
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
|
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
|
||||||
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
|
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ 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 UmbraServer = "UmbraSync Main Server (BETA)";
|
public const string UmbraServer = "Umbra Main Server (BETA)";
|
||||||
public const string UmbraServiceUri = "wss://umbra-sync.net/";
|
public const string UmbraServiceUri = "wss://umbra-sync.net";
|
||||||
public const string UmbraServiceApiUri = "wss://umbra-sync.net/";
|
public const string UmbraServiceApiUri = "wss://umbra-sync.net/";
|
||||||
public const string UmbraServiceHubUri = "wss://umbra-sync.net/mare";
|
public const string UmbraServiceHubUri = "wss://umbra-sync.net/mare";
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ using Microsoft.AspNetCore.Http.Connections;
|
|||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
namespace MareSynchronos.WebAPI.SignalR;
|
namespace MareSynchronos.WebAPI.SignalR;
|
||||||
|
|
||||||
@@ -19,6 +16,7 @@ public class HubFactory : MediatorSubscriberBase
|
|||||||
{
|
{
|
||||||
private readonly ILoggerProvider _loggingProvider;
|
private readonly ILoggerProvider _loggingProvider;
|
||||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||||
|
private readonly RemoteConfigurationService _remoteConfig;
|
||||||
private readonly TokenProvider _tokenProvider;
|
private readonly TokenProvider _tokenProvider;
|
||||||
private HubConnection? _instance;
|
private HubConnection? _instance;
|
||||||
private string _cachedConfigFor = string.Empty;
|
private string _cachedConfigFor = string.Empty;
|
||||||
@@ -26,10 +24,11 @@ public class HubFactory : MediatorSubscriberBase
|
|||||||
private bool _isDisposed = false;
|
private bool _isDisposed = false;
|
||||||
|
|
||||||
public HubFactory(ILogger<HubFactory> logger, MareMediator mediator,
|
public HubFactory(ILogger<HubFactory> logger, MareMediator mediator,
|
||||||
ServerConfigurationManager serverConfigurationManager,
|
ServerConfigurationManager serverConfigurationManager, RemoteConfigurationService remoteConfig,
|
||||||
TokenProvider tokenProvider, ILoggerProvider pluginLog) : base(logger, mediator)
|
TokenProvider tokenProvider, ILoggerProvider pluginLog) : base(logger, mediator)
|
||||||
{
|
{
|
||||||
_serverConfigurationManager = serverConfigurationManager;
|
_serverConfigurationManager = serverConfigurationManager;
|
||||||
|
_remoteConfig = remoteConfig;
|
||||||
_tokenProvider = tokenProvider;
|
_tokenProvider = tokenProvider;
|
||||||
_loggingProvider = pluginLog;
|
_loggingProvider = pluginLog;
|
||||||
}
|
}
|
||||||
@@ -66,98 +65,28 @@ public class HubFactory : MediatorSubscriberBase
|
|||||||
|
|
||||||
private async Task<HubConnectionConfig> ResolveHubConfig()
|
private async Task<HubConnectionConfig> ResolveHubConfig()
|
||||||
{
|
{
|
||||||
var stapledWellKnown = _tokenProvider.GetStapledWellKnown(_serverConfigurationManager.CurrentApiUrl);
|
|
||||||
|
|
||||||
var apiUrl = new Uri(_serverConfigurationManager.CurrentApiUrl);
|
|
||||||
|
|
||||||
HubConnectionConfig defaultConfig;
|
|
||||||
|
|
||||||
if (_cachedConfig != null && _serverConfigurationManager.CurrentApiUrl.Equals(_cachedConfigFor, StringComparison.Ordinal))
|
if (_cachedConfig != null && _serverConfigurationManager.CurrentApiUrl.Equals(_cachedConfigFor, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
defaultConfig = _cachedConfig;
|
return _cachedConfig;
|
||||||
}
|
}
|
||||||
else
|
var defaultConfig = new HubConnectionConfig
|
||||||
{
|
|
||||||
defaultConfig = new HubConnectionConfig
|
|
||||||
{
|
{
|
||||||
HubUrl = _serverConfigurationManager.CurrentApiUrl.TrimEnd('/') + IMareHub.Path,
|
HubUrl = _serverConfigurationManager.CurrentApiUrl.TrimEnd('/') + IMareHub.Path,
|
||||||
Transports = []
|
Transports = []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (_serverConfigurationManager.CurrentApiUrl.Equals(ApiController.UmbraServiceUri, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
var mainServerConfig = await _remoteConfig.GetConfigAsync<HubConnectionConfig>("mainServer").ConfigureAwait(false) ?? new();
|
||||||
|
if (string.IsNullOrEmpty(mainServerConfig.ApiUrl))
|
||||||
|
mainServerConfig.ApiUrl = ApiController.UmbraServiceApiUri;
|
||||||
|
if (string.IsNullOrEmpty(mainServerConfig.HubUrl))
|
||||||
|
mainServerConfig.HubUrl = ApiController.UmbraServiceHubUri;
|
||||||
|
|
||||||
|
mainServerConfig.Transports ??= defaultConfig.Transports ?? [];
|
||||||
|
return mainServerConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
string jsonResponse;
|
|
||||||
|
|
||||||
if (stapledWellKnown != null)
|
|
||||||
{
|
|
||||||
jsonResponse = stapledWellKnown;
|
|
||||||
Logger.LogTrace("Using stapled hub config for {url}", _serverConfigurationManager.CurrentApiUrl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var httpScheme = apiUrl.Scheme.ToLowerInvariant() switch
|
|
||||||
{
|
|
||||||
"ws" => "http",
|
|
||||||
"wss" => "https",
|
|
||||||
_ => apiUrl.Scheme
|
|
||||||
};
|
|
||||||
|
|
||||||
var wellKnownUrl = $"{httpScheme}://{apiUrl.Host}/.well-known/Umbra/client";
|
|
||||||
Logger.LogTrace("Fetching hub config for {uri} via {wk}", _serverConfigurationManager.CurrentApiUrl, wellKnownUrl);
|
|
||||||
|
|
||||||
using var httpClient = new HttpClient(
|
|
||||||
new HttpClientHandler
|
|
||||||
{
|
|
||||||
AllowAutoRedirect = true,
|
|
||||||
MaxAutomaticRedirections = 5
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
var ver = Assembly.GetExecutingAssembly().GetName().Version;
|
|
||||||
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MareSynchronos", ver!.Major + "." + ver!.Minor + "." + ver!.Build));
|
|
||||||
|
|
||||||
var response = await httpClient.GetAsync(wellKnownUrl).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
return defaultConfig;
|
return defaultConfig;
|
||||||
|
|
||||||
var contentType = response.Content.Headers.ContentType?.MediaType;
|
|
||||||
|
|
||||||
if (contentType == null || !contentType.Equals("application/json", StringComparison.Ordinal))
|
|
||||||
return defaultConfig;
|
|
||||||
|
|
||||||
jsonResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (HttpRequestException ex)
|
|
||||||
{
|
|
||||||
Logger.LogWarning(ex, "HTTP request failed for .well-known");
|
|
||||||
return defaultConfig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var config = JsonSerializer.Deserialize<HubConnectionConfig>(jsonResponse);
|
|
||||||
|
|
||||||
if (config == null)
|
|
||||||
return defaultConfig;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(config.ApiUrl))
|
|
||||||
config.ApiUrl = defaultConfig.ApiUrl;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(config.HubUrl))
|
|
||||||
config.HubUrl = defaultConfig.HubUrl;
|
|
||||||
|
|
||||||
config.Transports ??= defaultConfig.Transports ?? [];
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
catch (JsonException ex)
|
|
||||||
{
|
|
||||||
Logger.LogWarning(ex, "Invalid JSON in .well-known response");
|
|
||||||
return defaultConfig;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private HubConnection BuildHubConnection(HubConnectionConfig hubConfig, CancellationToken ct)
|
private HubConnection BuildHubConnection(HubConnectionConfig hubConfig, CancellationToken ct)
|
||||||
@@ -177,13 +106,11 @@ public class HubFactory : MediatorSubscriberBase
|
|||||||
var resolver = CompositeResolver.Create(StandardResolverAllowPrivate.Instance,
|
var resolver = CompositeResolver.Create(StandardResolverAllowPrivate.Instance,
|
||||||
BuiltinResolver.Instance,
|
BuiltinResolver.Instance,
|
||||||
AttributeFormatterResolver.Instance,
|
AttributeFormatterResolver.Instance,
|
||||||
// replace enum resolver
|
|
||||||
DynamicEnumAsStringResolver.Instance,
|
DynamicEnumAsStringResolver.Instance,
|
||||||
DynamicGenericResolver.Instance,
|
DynamicGenericResolver.Instance,
|
||||||
DynamicUnionResolver.Instance,
|
DynamicUnionResolver.Instance,
|
||||||
DynamicObjectResolver.Instance,
|
DynamicObjectResolver.Instance,
|
||||||
PrimitiveObjectResolver.Instance,
|
PrimitiveObjectResolver.Instance,
|
||||||
// final fallback(last priority)
|
|
||||||
StandardResolver.Instance);
|
StandardResolver.Instance);
|
||||||
|
|
||||||
opt.SerializerOptions =
|
opt.SerializerOptions =
|
||||||
|
|||||||
@@ -20,14 +20,16 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber
|
|||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly ILogger<TokenProvider> _logger;
|
private readonly ILogger<TokenProvider> _logger;
|
||||||
private readonly ServerConfigurationManager _serverManager;
|
private readonly ServerConfigurationManager _serverManager;
|
||||||
|
private readonly RemoteConfigurationService _remoteConfig;
|
||||||
private readonly ConcurrentDictionary<JwtIdentifier, string> _tokenCache = new();
|
private readonly ConcurrentDictionary<JwtIdentifier, string> _tokenCache = new();
|
||||||
private readonly ConcurrentDictionary<string, string?> _wellKnownCache = new(StringComparer.Ordinal);
|
private readonly ConcurrentDictionary<string, string?> _wellKnownCache = new(StringComparer.Ordinal);
|
||||||
|
|
||||||
public TokenProvider(ILogger<TokenProvider> logger, ServerConfigurationManager serverManager,
|
public TokenProvider(ILogger<TokenProvider> logger, ServerConfigurationManager serverManager, RemoteConfigurationService remoteConfig,
|
||||||
DalamudUtilService dalamudUtil, MareMediator mareMediator)
|
DalamudUtilService dalamudUtil, MareMediator mareMediator)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_serverManager = serverManager;
|
_serverManager = serverManager;
|
||||||
|
_remoteConfig = remoteConfig;
|
||||||
_dalamudUtil = dalamudUtil;
|
_dalamudUtil = dalamudUtil;
|
||||||
_httpClient = new(
|
_httpClient = new(
|
||||||
new HttpClientHandler
|
new HttpClientHandler
|
||||||
@@ -68,11 +70,23 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber
|
|||||||
Uri tokenUri;
|
Uri tokenUri;
|
||||||
HttpResponseMessage result;
|
HttpResponseMessage result;
|
||||||
|
|
||||||
|
var authApiUrl = _serverManager.CurrentApiUrl;
|
||||||
|
|
||||||
|
// Override the API URL used for auth from remote config, if one is available
|
||||||
|
if (authApiUrl.Equals(ApiController.UmbraServiceUri, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
var config = await _remoteConfig.GetConfigAsync<HubConnectionConfig>("mainServer").ConfigureAwait(false) ?? new();
|
||||||
|
if (!string.IsNullOrEmpty(config.ApiUrl))
|
||||||
|
authApiUrl = config.ApiUrl;
|
||||||
|
else
|
||||||
|
authApiUrl = ApiController.UmbraServiceApiUri;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logger.LogDebug("GetNewToken: Requesting");
|
_logger.LogDebug("GetNewToken: Requesting");
|
||||||
|
|
||||||
tokenUri = MareAuth.AuthV2FullPath(new Uri(_serverManager.CurrentApiUrl
|
tokenUri = MareAuth.AuthV2FullPath(new Uri(authApiUrl
|
||||||
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
|
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
|
||||||
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
|
.Replace("ws://", "http://", StringComparison.OrdinalIgnoreCase)));
|
||||||
var secretKey = _serverManager.GetSecretKey(out _)!;
|
var secretKey = _serverManager.GetSecretKey(out _)!;
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 928 KiB |
@@ -1,2 +1,4 @@
|
|||||||
# UmbraClient
|
# Umbra Sync
|
||||||
|
|
||||||
|
🇫🇷
|
||||||
|
Ce projet est basé sur Mare Synchronos de DarkArchon. Le code original est sous licence MIT ; voir le fichier LICENSE_MIT pour plus de détails. Les commits après celui-ci sont sous licence AGPL v3.
|
||||||
350
UmbraAPI/.gitignore
vendored
350
UmbraAPI/.gitignore
vendored
@@ -1,350 +0,0 @@
|
|||||||
## Ignore Visual Studio temporary files, build results, and
|
|
||||||
## files generated by popular Visual Studio add-ons.
|
|
||||||
##
|
|
||||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
|
||||||
|
|
||||||
# User-specific files
|
|
||||||
*.rsuser
|
|
||||||
*.suo
|
|
||||||
*.user
|
|
||||||
*.userosscache
|
|
||||||
*.sln.docstates
|
|
||||||
|
|
||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
|
||||||
*.userprefs
|
|
||||||
|
|
||||||
# Mono auto generated files
|
|
||||||
mono_crash.*
|
|
||||||
|
|
||||||
# Build results
|
|
||||||
[Dd]ebug/
|
|
||||||
[Dd]ebugPublic/
|
|
||||||
[Rr]elease/
|
|
||||||
[Rr]eleases/
|
|
||||||
x64/
|
|
||||||
x86/
|
|
||||||
[Aa][Rr][Mm]/
|
|
||||||
[Aa][Rr][Mm]64/
|
|
||||||
bld/
|
|
||||||
[Bb]in/
|
|
||||||
[Oo]bj/
|
|
||||||
[Ll]og/
|
|
||||||
[Ll]ogs/
|
|
||||||
|
|
||||||
# Visual Studio 2015/2017 cache/options directory
|
|
||||||
.vs/
|
|
||||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
|
||||||
#wwwroot/
|
|
||||||
|
|
||||||
# Visual Studio 2017 auto generated files
|
|
||||||
Generated\ Files/
|
|
||||||
|
|
||||||
# MSTest test Results
|
|
||||||
[Tt]est[Rr]esult*/
|
|
||||||
[Bb]uild[Ll]og.*
|
|
||||||
|
|
||||||
# NUnit
|
|
||||||
*.VisualState.xml
|
|
||||||
TestResult.xml
|
|
||||||
nunit-*.xml
|
|
||||||
|
|
||||||
# Build Results of an ATL Project
|
|
||||||
[Dd]ebugPS/
|
|
||||||
[Rr]eleasePS/
|
|
||||||
dlldata.c
|
|
||||||
|
|
||||||
# Benchmark Results
|
|
||||||
BenchmarkDotNet.Artifacts/
|
|
||||||
|
|
||||||
# .NET Core
|
|
||||||
project.lock.json
|
|
||||||
project.fragment.lock.json
|
|
||||||
artifacts/
|
|
||||||
|
|
||||||
# StyleCop
|
|
||||||
StyleCopReport.xml
|
|
||||||
|
|
||||||
# Files built by Visual Studio
|
|
||||||
*_i.c
|
|
||||||
*_p.c
|
|
||||||
*_h.h
|
|
||||||
*.ilk
|
|
||||||
*.meta
|
|
||||||
*.obj
|
|
||||||
*.iobj
|
|
||||||
*.pch
|
|
||||||
*.pdb
|
|
||||||
*.ipdb
|
|
||||||
*.pgc
|
|
||||||
*.pgd
|
|
||||||
*.rsp
|
|
||||||
*.sbr
|
|
||||||
*.tlb
|
|
||||||
*.tli
|
|
||||||
*.tlh
|
|
||||||
*.tmp
|
|
||||||
*.tmp_proj
|
|
||||||
*_wpftmp.csproj
|
|
||||||
*.log
|
|
||||||
*.vspscc
|
|
||||||
*.vssscc
|
|
||||||
.builds
|
|
||||||
*.pidb
|
|
||||||
*.svclog
|
|
||||||
*.scc
|
|
||||||
|
|
||||||
# Chutzpah Test files
|
|
||||||
_Chutzpah*
|
|
||||||
|
|
||||||
# Visual C++ cache files
|
|
||||||
ipch/
|
|
||||||
*.aps
|
|
||||||
*.ncb
|
|
||||||
*.opendb
|
|
||||||
*.opensdf
|
|
||||||
*.sdf
|
|
||||||
*.cachefile
|
|
||||||
*.VC.db
|
|
||||||
*.VC.VC.opendb
|
|
||||||
|
|
||||||
# Visual Studio profiler
|
|
||||||
*.psess
|
|
||||||
*.vsp
|
|
||||||
*.vspx
|
|
||||||
*.sap
|
|
||||||
|
|
||||||
# Visual Studio Trace Files
|
|
||||||
*.e2e
|
|
||||||
|
|
||||||
# TFS 2012 Local Workspace
|
|
||||||
$tf/
|
|
||||||
|
|
||||||
# Guidance Automation Toolkit
|
|
||||||
*.gpState
|
|
||||||
|
|
||||||
# ReSharper is a .NET coding add-in
|
|
||||||
_ReSharper*/
|
|
||||||
*.[Rr]e[Ss]harper
|
|
||||||
*.DotSettings.user
|
|
||||||
|
|
||||||
# TeamCity is a build add-in
|
|
||||||
_TeamCity*
|
|
||||||
|
|
||||||
# DotCover is a Code Coverage Tool
|
|
||||||
*.dotCover
|
|
||||||
|
|
||||||
# AxoCover is a Code Coverage Tool
|
|
||||||
.axoCover/*
|
|
||||||
!.axoCover/settings.json
|
|
||||||
|
|
||||||
# Visual Studio code coverage results
|
|
||||||
*.coverage
|
|
||||||
*.coveragexml
|
|
||||||
|
|
||||||
# NCrunch
|
|
||||||
_NCrunch_*
|
|
||||||
.*crunch*.local.xml
|
|
||||||
nCrunchTemp_*
|
|
||||||
|
|
||||||
# MightyMoose
|
|
||||||
*.mm.*
|
|
||||||
AutoTest.Net/
|
|
||||||
|
|
||||||
# Web workbench (sass)
|
|
||||||
.sass-cache/
|
|
||||||
|
|
||||||
# Installshield output folder
|
|
||||||
[Ee]xpress/
|
|
||||||
|
|
||||||
# DocProject is a documentation generator add-in
|
|
||||||
DocProject/buildhelp/
|
|
||||||
DocProject/Help/*.HxT
|
|
||||||
DocProject/Help/*.HxC
|
|
||||||
DocProject/Help/*.hhc
|
|
||||||
DocProject/Help/*.hhk
|
|
||||||
DocProject/Help/*.hhp
|
|
||||||
DocProject/Help/Html2
|
|
||||||
DocProject/Help/html
|
|
||||||
|
|
||||||
# Click-Once directory
|
|
||||||
publish/
|
|
||||||
|
|
||||||
# Publish Web Output
|
|
||||||
*.[Pp]ublish.xml
|
|
||||||
*.azurePubxml
|
|
||||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
|
||||||
# but database connection strings (with potential passwords) will be unencrypted
|
|
||||||
*.pubxml
|
|
||||||
*.publishproj
|
|
||||||
|
|
||||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
|
||||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
|
||||||
# in these scripts will be unencrypted
|
|
||||||
PublishScripts/
|
|
||||||
|
|
||||||
# NuGet Packages
|
|
||||||
*.nupkg
|
|
||||||
# NuGet Symbol Packages
|
|
||||||
*.snupkg
|
|
||||||
# The packages folder can be ignored because of Package Restore
|
|
||||||
**/[Pp]ackages/*
|
|
||||||
# except build/, which is used as an MSBuild target.
|
|
||||||
!**/[Pp]ackages/build/
|
|
||||||
# Uncomment if necessary however generally it will be regenerated when needed
|
|
||||||
#!**/[Pp]ackages/repositories.config
|
|
||||||
# NuGet v3's project.json files produces more ignorable files
|
|
||||||
*.nuget.props
|
|
||||||
*.nuget.targets
|
|
||||||
|
|
||||||
# Microsoft Azure Build Output
|
|
||||||
csx/
|
|
||||||
*.build.csdef
|
|
||||||
|
|
||||||
# Microsoft Azure Emulator
|
|
||||||
ecf/
|
|
||||||
rcf/
|
|
||||||
|
|
||||||
# Windows Store app package directories and files
|
|
||||||
AppPackages/
|
|
||||||
BundleArtifacts/
|
|
||||||
Package.StoreAssociation.xml
|
|
||||||
_pkginfo.txt
|
|
||||||
*.appx
|
|
||||||
*.appxbundle
|
|
||||||
*.appxupload
|
|
||||||
|
|
||||||
# Visual Studio cache files
|
|
||||||
# files ending in .cache can be ignored
|
|
||||||
*.[Cc]ache
|
|
||||||
# but keep track of directories ending in .cache
|
|
||||||
!?*.[Cc]ache/
|
|
||||||
|
|
||||||
# Others
|
|
||||||
ClientBin/
|
|
||||||
~$*
|
|
||||||
*~
|
|
||||||
*.dbmdl
|
|
||||||
*.dbproj.schemaview
|
|
||||||
*.jfm
|
|
||||||
*.pfx
|
|
||||||
*.publishsettings
|
|
||||||
orleans.codegen.cs
|
|
||||||
|
|
||||||
# Including strong name files can present a security risk
|
|
||||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
|
||||||
#*.snk
|
|
||||||
|
|
||||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
|
||||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
|
||||||
#bower_components/
|
|
||||||
|
|
||||||
# RIA/Silverlight projects
|
|
||||||
Generated_Code/
|
|
||||||
|
|
||||||
# Backup & report files from converting an old project file
|
|
||||||
# to a newer Visual Studio version. Backup files are not needed,
|
|
||||||
# because we have git ;-)
|
|
||||||
_UpgradeReport_Files/
|
|
||||||
Backup*/
|
|
||||||
UpgradeLog*.XML
|
|
||||||
UpgradeLog*.htm
|
|
||||||
ServiceFabricBackup/
|
|
||||||
*.rptproj.bak
|
|
||||||
|
|
||||||
# SQL Server files
|
|
||||||
*.mdf
|
|
||||||
*.ldf
|
|
||||||
*.ndf
|
|
||||||
|
|
||||||
# Business Intelligence projects
|
|
||||||
*.rdl.data
|
|
||||||
*.bim.layout
|
|
||||||
*.bim_*.settings
|
|
||||||
*.rptproj.rsuser
|
|
||||||
*- [Bb]ackup.rdl
|
|
||||||
*- [Bb]ackup ([0-9]).rdl
|
|
||||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
|
||||||
|
|
||||||
# Microsoft Fakes
|
|
||||||
FakesAssemblies/
|
|
||||||
|
|
||||||
# GhostDoc plugin setting file
|
|
||||||
*.GhostDoc.xml
|
|
||||||
|
|
||||||
# Node.js Tools for Visual Studio
|
|
||||||
.ntvs_analysis.dat
|
|
||||||
node_modules/
|
|
||||||
|
|
||||||
# Visual Studio 6 build log
|
|
||||||
*.plg
|
|
||||||
|
|
||||||
# Visual Studio 6 workspace options file
|
|
||||||
*.opt
|
|
||||||
|
|
||||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
|
||||||
*.vbw
|
|
||||||
|
|
||||||
# Visual Studio LightSwitch build output
|
|
||||||
**/*.HTMLClient/GeneratedArtifacts
|
|
||||||
**/*.DesktopClient/GeneratedArtifacts
|
|
||||||
**/*.DesktopClient/ModelManifest.xml
|
|
||||||
**/*.Server/GeneratedArtifacts
|
|
||||||
**/*.Server/ModelManifest.xml
|
|
||||||
_Pvt_Extensions
|
|
||||||
|
|
||||||
# Paket dependency manager
|
|
||||||
.paket/paket.exe
|
|
||||||
paket-files/
|
|
||||||
|
|
||||||
# FAKE - F# Make
|
|
||||||
.fake/
|
|
||||||
|
|
||||||
# CodeRush personal settings
|
|
||||||
.cr/personal
|
|
||||||
|
|
||||||
# Python Tools for Visual Studio (PTVS)
|
|
||||||
__pycache__/
|
|
||||||
*.pyc
|
|
||||||
|
|
||||||
# Cake - Uncomment if you are using it
|
|
||||||
# tools/**
|
|
||||||
# !tools/packages.config
|
|
||||||
|
|
||||||
# Tabs Studio
|
|
||||||
*.tss
|
|
||||||
|
|
||||||
# Telerik's JustMock configuration file
|
|
||||||
*.jmconfig
|
|
||||||
|
|
||||||
# BizTalk build output
|
|
||||||
*.btp.cs
|
|
||||||
*.btm.cs
|
|
||||||
*.odx.cs
|
|
||||||
*.xsd.cs
|
|
||||||
|
|
||||||
# OpenCover UI analysis results
|
|
||||||
OpenCover/
|
|
||||||
|
|
||||||
# Azure Stream Analytics local run output
|
|
||||||
ASALocalRun/
|
|
||||||
|
|
||||||
# MSBuild Binary and Structured Log
|
|
||||||
*.binlog
|
|
||||||
|
|
||||||
# NVidia Nsight GPU debugger configuration file
|
|
||||||
*.nvuser
|
|
||||||
|
|
||||||
# MFractors (Xamarin productivity tool) working folder
|
|
||||||
.mfractor/
|
|
||||||
|
|
||||||
# Local History for Visual Studio
|
|
||||||
.localhistory/
|
|
||||||
|
|
||||||
# BeatPulse healthcheck temp database
|
|
||||||
healthchecksdb
|
|
||||||
|
|
||||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
|
||||||
MigrationBackup/
|
|
||||||
|
|
||||||
# Ionide (cross platform F# VS Code tools) working folder
|
|
||||||
.ionide/
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
using MessagePack;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public class CharacterData
|
|
||||||
{
|
|
||||||
public CharacterData()
|
|
||||||
{
|
|
||||||
DataHash = new(() =>
|
|
||||||
{
|
|
||||||
var json = JsonSerializer.Serialize(this);
|
|
||||||
#pragma warning disable SYSLIB0021 // Type or member is obsolete
|
|
||||||
using SHA256CryptoServiceProvider cryptoProvider = new();
|
|
||||||
#pragma warning restore SYSLIB0021 // Type or member is obsolete
|
|
||||||
return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(json))).Replace("-", "", StringComparison.Ordinal);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<ObjectKind, string> CustomizePlusData { get; set; } = new();
|
|
||||||
[JsonIgnore]
|
|
||||||
public Lazy<string> DataHash { get; }
|
|
||||||
|
|
||||||
public Dictionary<ObjectKind, List<FileReplacementData>> FileReplacements { get; set; } = new();
|
|
||||||
public Dictionary<ObjectKind, string> GlamourerData { get; set; } = new();
|
|
||||||
public string HeelsData { get; set; } = string.Empty;
|
|
||||||
public string HonorificData { get; set; } = string.Empty;
|
|
||||||
public string ManipulationData { get; set; } = string.Empty;
|
|
||||||
public string MoodlesData { get; set; } = string.Empty;
|
|
||||||
public string PetNamesData { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record ChatMessage
|
|
||||||
{
|
|
||||||
public string SenderName { get; set; } = string.Empty;
|
|
||||||
public uint SenderHomeWorldId { get; set; } = 0;
|
|
||||||
public byte[] PayloadContent { get; set; } = [];
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Data.Comparer;
|
|
||||||
|
|
||||||
public class GroupDataComparer : IEqualityComparer<GroupData>
|
|
||||||
{
|
|
||||||
public static GroupDataComparer Instance => _instance;
|
|
||||||
private static GroupDataComparer _instance = new GroupDataComparer();
|
|
||||||
|
|
||||||
private GroupDataComparer() { }
|
|
||||||
public bool Equals(GroupData? x, GroupData? y)
|
|
||||||
{
|
|
||||||
if (x == null || y == null) return false;
|
|
||||||
return x.GID.Equals(y.GID, StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetHashCode(GroupData obj)
|
|
||||||
{
|
|
||||||
return obj.GID.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
using MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data.Comparer;
|
|
||||||
|
|
||||||
|
|
||||||
public class GroupDtoComparer : IEqualityComparer<GroupDto>
|
|
||||||
{
|
|
||||||
public static GroupDtoComparer Instance => _instance;
|
|
||||||
private static GroupDtoComparer _instance = new GroupDtoComparer();
|
|
||||||
|
|
||||||
private GroupDtoComparer() { }
|
|
||||||
|
|
||||||
public bool Equals(GroupDto? x, GroupDto? y)
|
|
||||||
{
|
|
||||||
if (x == null || y == null) return false;
|
|
||||||
return x.GID.Equals(y.GID, StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetHashCode(GroupDto obj)
|
|
||||||
{
|
|
||||||
return obj.Group.GID.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data.Comparer;
|
|
||||||
|
|
||||||
public class GroupPairDtoComparer : IEqualityComparer<GroupPairDto>
|
|
||||||
{
|
|
||||||
public static GroupPairDtoComparer Instance => _instance;
|
|
||||||
private static GroupPairDtoComparer _instance = new();
|
|
||||||
private GroupPairDtoComparer() { }
|
|
||||||
public bool Equals(GroupPairDto? x, GroupPairDto? y)
|
|
||||||
{
|
|
||||||
if (x == null || y == null) return false;
|
|
||||||
return x.GID.Equals(y.GID, StringComparison.Ordinal) && x.UID.Equals(y.UID, StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetHashCode(GroupPairDto obj)
|
|
||||||
{
|
|
||||||
return HashCode.Combine(obj.Group.GID.GetHashCode(), obj.User.UID.GetHashCode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Data.Comparer;
|
|
||||||
|
|
||||||
public class UserDataComparer : IEqualityComparer<UserData>
|
|
||||||
{
|
|
||||||
public static UserDataComparer Instance => _instance;
|
|
||||||
private static UserDataComparer _instance = new();
|
|
||||||
|
|
||||||
private UserDataComparer() { }
|
|
||||||
|
|
||||||
public bool Equals(UserData? x, UserData? y)
|
|
||||||
{
|
|
||||||
if (x == null || y == null) return false;
|
|
||||||
return x.UID.Equals(y.UID, StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetHashCode(UserData obj)
|
|
||||||
{
|
|
||||||
return obj.UID.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using MareSynchronos.API.Dto.User;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data.Comparer;
|
|
||||||
|
|
||||||
public class UserDtoComparer : IEqualityComparer<UserDto>
|
|
||||||
{
|
|
||||||
public static UserDtoComparer Instance => _instance;
|
|
||||||
private static UserDtoComparer _instance = new();
|
|
||||||
private UserDtoComparer() { }
|
|
||||||
public bool Equals(UserDto? x, UserDto? y)
|
|
||||||
{
|
|
||||||
if (x == null || y == null) return false;
|
|
||||||
return x.User.UID.Equals(y.User.UID, StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetHashCode(UserDto obj)
|
|
||||||
{
|
|
||||||
return obj.User.UID.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Data.Enum;
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum GroupPermissions
|
|
||||||
{
|
|
||||||
NoneSet = 0x0,
|
|
||||||
DisableAnimations = 0x1,
|
|
||||||
DisableSounds = 0x2,
|
|
||||||
DisableInvites = 0x4,
|
|
||||||
DisableVFX = 0x8,
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Data.Enum;
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum GroupUserInfo
|
|
||||||
{
|
|
||||||
None = 0x0,
|
|
||||||
IsModerator = 0x2,
|
|
||||||
IsPinned = 0x4
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Data.Enum;
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum GroupUserPermissions
|
|
||||||
{
|
|
||||||
NoneSet = 0x0,
|
|
||||||
Paused = 0x1,
|
|
||||||
DisableAnimations = 0x2,
|
|
||||||
DisableSounds = 0x4,
|
|
||||||
DisableVFX = 0x8,
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Data.Enum;
|
|
||||||
|
|
||||||
public enum MessageSeverity
|
|
||||||
{
|
|
||||||
Information,
|
|
||||||
Warning,
|
|
||||||
Error
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Data.Enum;
|
|
||||||
|
|
||||||
public enum ObjectKind
|
|
||||||
{
|
|
||||||
Player = 0,
|
|
||||||
MinionOrMount = 1,
|
|
||||||
Companion = 2,
|
|
||||||
Pet = 3,
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Data.Enum;
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum UserPermissions
|
|
||||||
{
|
|
||||||
NoneSet = 0,
|
|
||||||
Paired = 1,
|
|
||||||
Paused = 2,
|
|
||||||
DisableAnimations = 4,
|
|
||||||
DisableSounds = 8,
|
|
||||||
DisableVFX = 16,
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data.Extensions;
|
|
||||||
|
|
||||||
public static class GroupPermissionsExtensions
|
|
||||||
{
|
|
||||||
public static bool IsDisableAnimations(this GroupPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(GroupPermissions.DisableAnimations);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsDisableSounds(this GroupPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(GroupPermissions.DisableSounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsDisableInvites(this GroupPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(GroupPermissions.DisableInvites);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsDisableVFX(this GroupPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(GroupPermissions.DisableVFX);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetDisableAnimations(this ref GroupPermissions perm, bool set)
|
|
||||||
{
|
|
||||||
if (set) perm |= GroupPermissions.DisableAnimations;
|
|
||||||
else perm &= ~GroupPermissions.DisableAnimations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetDisableSounds(this ref GroupPermissions perm, bool set)
|
|
||||||
{
|
|
||||||
if (set) perm |= GroupPermissions.DisableSounds;
|
|
||||||
else perm &= ~GroupPermissions.DisableSounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetDisableInvites(this ref GroupPermissions perm, bool set)
|
|
||||||
{
|
|
||||||
if (set) perm |= GroupPermissions.DisableInvites;
|
|
||||||
else perm &= ~GroupPermissions.DisableInvites;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetDisableVFX(this ref GroupPermissions perm, bool set)
|
|
||||||
{
|
|
||||||
if (set) perm |= GroupPermissions.DisableVFX;
|
|
||||||
else perm &= ~GroupPermissions.DisableVFX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data.Extensions;
|
|
||||||
|
|
||||||
public static class GroupUserInfoExtensions
|
|
||||||
{
|
|
||||||
public static bool IsModerator(this GroupUserInfo info)
|
|
||||||
{
|
|
||||||
return info.HasFlag(GroupUserInfo.IsModerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsPinned(this GroupUserInfo info)
|
|
||||||
{
|
|
||||||
return info.HasFlag(GroupUserInfo.IsPinned);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetModerator(this ref GroupUserInfo info, bool isModerator)
|
|
||||||
{
|
|
||||||
if (isModerator) info |= GroupUserInfo.IsModerator;
|
|
||||||
else info &= ~GroupUserInfo.IsModerator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetPinned(this ref GroupUserInfo info, bool isPinned)
|
|
||||||
{
|
|
||||||
if (isPinned) info |= GroupUserInfo.IsPinned;
|
|
||||||
else info &= ~GroupUserInfo.IsPinned;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data.Extensions;
|
|
||||||
|
|
||||||
public static class GroupUserPermissionsExtensions
|
|
||||||
{
|
|
||||||
public static bool IsDisableAnimations(this GroupUserPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(GroupUserPermissions.DisableAnimations);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsDisableSounds(this GroupUserPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(GroupUserPermissions.DisableSounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsPaused(this GroupUserPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(GroupUserPermissions.Paused);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsDisableVFX(this GroupUserPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(GroupUserPermissions.DisableVFX);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetDisableAnimations(this ref GroupUserPermissions perm, bool set)
|
|
||||||
{
|
|
||||||
if (set) perm |= GroupUserPermissions.DisableAnimations;
|
|
||||||
else perm &= ~GroupUserPermissions.DisableAnimations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetDisableSounds(this ref GroupUserPermissions perm, bool set)
|
|
||||||
{
|
|
||||||
if (set) perm |= GroupUserPermissions.DisableSounds;
|
|
||||||
else perm &= ~GroupUserPermissions.DisableSounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetPaused(this ref GroupUserPermissions perm, bool set)
|
|
||||||
{
|
|
||||||
if (set) perm |= GroupUserPermissions.Paused;
|
|
||||||
else perm &= ~GroupUserPermissions.Paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetDisableVFX(this ref GroupUserPermissions perm, bool set)
|
|
||||||
{
|
|
||||||
if (set) perm |= GroupUserPermissions.DisableVFX;
|
|
||||||
else perm &= ~GroupUserPermissions.DisableVFX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data.Extensions;
|
|
||||||
|
|
||||||
public static class UserPermissionsExtensions
|
|
||||||
{
|
|
||||||
public static bool IsPaired(this UserPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(UserPermissions.Paired);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsPaused(this UserPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(UserPermissions.Paused);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsDisableAnimations(this UserPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(UserPermissions.DisableAnimations);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsDisableSounds(this UserPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(UserPermissions.DisableSounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsDisableVFX(this UserPermissions perm)
|
|
||||||
{
|
|
||||||
return perm.HasFlag(UserPermissions.DisableVFX);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetPaired(this ref UserPermissions perm, bool paired)
|
|
||||||
{
|
|
||||||
if (paired) perm |= UserPermissions.Paired;
|
|
||||||
else perm &= ~UserPermissions.Paired;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetPaused(this ref UserPermissions perm, bool paused)
|
|
||||||
{
|
|
||||||
if (paused) perm |= UserPermissions.Paused;
|
|
||||||
else perm &= ~UserPermissions.Paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetDisableAnimations(this ref UserPermissions perm, bool set)
|
|
||||||
{
|
|
||||||
if (set) perm |= UserPermissions.DisableAnimations;
|
|
||||||
else perm &= ~UserPermissions.DisableAnimations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetDisableSounds(this ref UserPermissions perm, bool set)
|
|
||||||
{
|
|
||||||
if (set) perm |= UserPermissions.DisableSounds;
|
|
||||||
else perm &= ~UserPermissions.DisableSounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetDisableVFX(this ref UserPermissions perm, bool set)
|
|
||||||
{
|
|
||||||
if (set) perm |= UserPermissions.DisableVFX;
|
|
||||||
else perm &= ~UserPermissions.DisableVFX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using MessagePack;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public class FileReplacementData
|
|
||||||
{
|
|
||||||
public FileReplacementData()
|
|
||||||
{
|
|
||||||
DataHash = new(() =>
|
|
||||||
{
|
|
||||||
var json = JsonSerializer.Serialize(this);
|
|
||||||
#pragma warning disable SYSLIB0021 // Type or member is obsolete
|
|
||||||
using SHA256CryptoServiceProvider cryptoProvider = new();
|
|
||||||
#pragma warning restore SYSLIB0021 // Type or member is obsolete
|
|
||||||
return BitConverter.ToString(cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(json))).Replace("-", "", StringComparison.Ordinal);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public Lazy<string> DataHash { get; }
|
|
||||||
public string[] GamePaths { get; set; } = Array.Empty<string>();
|
|
||||||
public string Hash { get; set; } = string.Empty;
|
|
||||||
public string FileSwapPath { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GroupData(string GID, string? Alias = null)
|
|
||||||
{
|
|
||||||
[IgnoreMember]
|
|
||||||
public string AliasOrGID => string.IsNullOrWhiteSpace(Alias) ? GID : Alias;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record SignedChatMessage(ChatMessage Message, UserData Sender) : ChatMessage(Message)
|
|
||||||
{
|
|
||||||
// Sender and timestamp are set by the server
|
|
||||||
public UserData Sender { get; set; } = Sender;
|
|
||||||
public long Timestamp { get; set; } = 0;
|
|
||||||
// Signature is generated by the server as SHA256(Sender.UID | Timestamp | Destination | Message)
|
|
||||||
// Where Destination is either the receiver's UID, or the group GID
|
|
||||||
public string Signature { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Data;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record UserData(string UID, string? Alias = null)
|
|
||||||
{
|
|
||||||
[IgnoreMember]
|
|
||||||
public string AliasOrUID => string.IsNullOrWhiteSpace(Alias) ? UID : Alias;
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Account;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record RegisterReplyDto
|
|
||||||
{
|
|
||||||
public bool Success { get; set; } = false;
|
|
||||||
public string ErrorMessage { get; set; } = string.Empty;
|
|
||||||
public string UID { get; set; } = string.Empty;
|
|
||||||
public string SecretKey { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Account;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record RegisterReplyV2Dto
|
|
||||||
{
|
|
||||||
public bool Success { get; set; } = false;
|
|
||||||
public string ErrorMessage { get; set; } = string.Empty;
|
|
||||||
public string UID { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record AuthReplyDto
|
|
||||||
{
|
|
||||||
public string Token { get; set; } = string.Empty;
|
|
||||||
public string? WellKnown { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Dto.CharaData;
|
|
||||||
|
|
||||||
public enum AccessTypeDto
|
|
||||||
{
|
|
||||||
Individuals,
|
|
||||||
ClosePairs,
|
|
||||||
AllPairs,
|
|
||||||
Public
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.CharaData;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record CharaDataDownloadDto(string Id, UserData Uploader) : CharaDataDto(Id, Uploader)
|
|
||||||
{
|
|
||||||
public string GlamourerData { get; init; } = string.Empty;
|
|
||||||
public string CustomizeData { get; init; } = string.Empty;
|
|
||||||
public string ManipulationData { get; set; } = string.Empty;
|
|
||||||
public List<GamePathEntry> FileGamePaths { get; init; } = [];
|
|
||||||
public List<GamePathEntry> FileSwaps { get; init; } = [];
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.CharaData;
|
|
||||||
|
|
||||||
public record CharaDataDto(string Id, UserData Uploader)
|
|
||||||
{
|
|
||||||
public string Description { get; init; } = string.Empty;
|
|
||||||
public DateTime UpdatedDate { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.CharaData;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record CharaDataFullDto(string Id, UserData Uploader) : CharaDataDto(Id, Uploader)
|
|
||||||
{
|
|
||||||
public DateTime CreatedDate { get; init; }
|
|
||||||
public DateTime ExpiryDate { get; set; }
|
|
||||||
public string GlamourerData { get; set; } = string.Empty;
|
|
||||||
public string CustomizeData { get; set; } = string.Empty;
|
|
||||||
public string ManipulationData { get; set; } = string.Empty;
|
|
||||||
public int DownloadCount { get; set; } = 0;
|
|
||||||
public List<UserData> AllowedUsers { get; set; } = [];
|
|
||||||
public List<GroupData> AllowedGroups { get; set; } = [];
|
|
||||||
public List<GamePathEntry> FileGamePaths { get; set; } = [];
|
|
||||||
public List<GamePathEntry> FileSwaps { get; set; } = [];
|
|
||||||
public List<GamePathEntry> OriginalFiles { get; set; } = [];
|
|
||||||
public AccessTypeDto AccessType { get; set; }
|
|
||||||
public ShareTypeDto ShareType { get; set; }
|
|
||||||
public List<PoseEntry> PoseData { get; set; } = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GamePathEntry(string HashOrFileSwap, string GamePath);
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record PoseEntry(long? Id)
|
|
||||||
{
|
|
||||||
public string? Description { get; set; } = string.Empty;
|
|
||||||
public string? PoseData { get; set; } = string.Empty;
|
|
||||||
public WorldData? WorldData { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[MessagePackObject]
|
|
||||||
public record struct WorldData
|
|
||||||
{
|
|
||||||
[Key(0)] public LocationInfo LocationInfo { get; set; }
|
|
||||||
[Key(1)] public float PositionX { get; set; }
|
|
||||||
[Key(2)] public float PositionY { get; set; }
|
|
||||||
[Key(3)] public float PositionZ { get; set; }
|
|
||||||
[Key(4)] public float RotationX { get; set; }
|
|
||||||
[Key(5)] public float RotationY { get; set; }
|
|
||||||
[Key(6)] public float RotationZ { get; set; }
|
|
||||||
[Key(7)] public float RotationW { get; set; }
|
|
||||||
[Key(8)] public float ScaleX { get; set; }
|
|
||||||
[Key(9)] public float ScaleY { get; set; }
|
|
||||||
[Key(10)] public float ScaleZ { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[MessagePackObject]
|
|
||||||
public record struct LocationInfo
|
|
||||||
{
|
|
||||||
[Key(0)] public uint ServerId { get; set; }
|
|
||||||
[Key(1)] public uint MapId { get; set; }
|
|
||||||
[Key(2)] public uint TerritoryId { get; set; }
|
|
||||||
[Key(3)] public uint DivisionId { get; set; }
|
|
||||||
[Key(4)] public uint WardId { get; set; }
|
|
||||||
[Key(5)] public uint HouseId { get; set; }
|
|
||||||
[Key(6)] public uint RoomId { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[MessagePackObject]
|
|
||||||
public record struct PoseData
|
|
||||||
{
|
|
||||||
[Key(0)] public bool IsDelta { get; set; }
|
|
||||||
[Key(1)] public Dictionary<string, BoneData> Bones { get; set; }
|
|
||||||
[Key(2)] public Dictionary<string, BoneData> MainHand { get; set; }
|
|
||||||
[Key(3)] public Dictionary<string, BoneData> OffHand { get; set; }
|
|
||||||
[Key(4)] public BoneData ModelDifference { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[MessagePackObject]
|
|
||||||
public record struct BoneData
|
|
||||||
{
|
|
||||||
[Key(0)] public bool Exists { get; set; }
|
|
||||||
[Key(1)] public float PositionX { get; set; }
|
|
||||||
[Key(2)] public float PositionY { get; set; }
|
|
||||||
[Key(3)] public float PositionZ { get; set; }
|
|
||||||
[Key(4)] public float RotationX { get; set; }
|
|
||||||
[Key(5)] public float RotationY { get; set; }
|
|
||||||
[Key(6)] public float RotationZ { get; set; }
|
|
||||||
[Key(7)] public float RotationW { get; set; }
|
|
||||||
[Key(8)] public float ScaleX { get; set; }
|
|
||||||
[Key(9)] public float ScaleY { get; set; }
|
|
||||||
[Key(10)] public float ScaleZ { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.CharaData;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record CharaDataMetaInfoDto(string Id, UserData Uploader) : CharaDataDto(Id, Uploader)
|
|
||||||
{
|
|
||||||
public bool CanBeDownloaded { get; init; }
|
|
||||||
public List<PoseEntry> PoseData { get; set; } = [];
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.CharaData;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record CharaDataUpdateDto(string Id)
|
|
||||||
{
|
|
||||||
public string? Description { get; set; }
|
|
||||||
public DateTime? ExpiryDate { get; set; }
|
|
||||||
public string? GlamourerData { get; set; }
|
|
||||||
public string? CustomizeData { get; set; }
|
|
||||||
public string? ManipulationData { get; set; }
|
|
||||||
public List<string>? AllowedUsers { get; set; }
|
|
||||||
public List<string>? AllowedGroups { get; set; }
|
|
||||||
public List<GamePathEntry>? FileGamePaths { get; set; }
|
|
||||||
public List<GamePathEntry>? FileSwaps { get; set; }
|
|
||||||
public AccessTypeDto? AccessType { get; set; }
|
|
||||||
public ShareTypeDto? ShareType { get; set; }
|
|
||||||
public List<PoseEntry>? Poses { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Dto.CharaData;
|
|
||||||
|
|
||||||
public enum ShareTypeDto
|
|
||||||
{
|
|
||||||
Private,
|
|
||||||
Shared
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Dto.Group;
|
|
||||||
using MareSynchronos.API.Dto.User;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Chat;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GroupChatMsgDto(GroupDto Group, SignedChatMessage Message)
|
|
||||||
{
|
|
||||||
public GroupDto Group = Group;
|
|
||||||
public SignedChatMessage Message = Message;
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Dto.User;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Chat;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record UserChatMsgDto(SignedChatMessage Message)
|
|
||||||
{
|
|
||||||
public SignedChatMessage Message = Message;
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record ConnectionDto(UserData User)
|
|
||||||
{
|
|
||||||
public Version CurrentClientVersion { get; set; } = new(0, 0, 0);
|
|
||||||
public int ServerVersion { get; set; }
|
|
||||||
public bool IsAdmin { get; set; }
|
|
||||||
public bool IsModerator { get; set; }
|
|
||||||
public ServerInfo ServerInfo { get; set; } = new();
|
|
||||||
}
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record ServerInfo
|
|
||||||
{
|
|
||||||
public string ShardName { get; set; } = string.Empty;
|
|
||||||
public int MaxGroupUserCount { get; set; }
|
|
||||||
public int MaxGroupsCreatedByUser { get; set; }
|
|
||||||
public int MaxGroupsJoinedByUser { get; set; }
|
|
||||||
public Uri FileServerAddress { get; set; } = new Uri("http://nonemptyuri");
|
|
||||||
public int MaxCharaData { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Files;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record DownloadFileDto : ITransferFileDto
|
|
||||||
{
|
|
||||||
public bool FileExists { get; set; } = true;
|
|
||||||
public string Hash { get; set; } = string.Empty;
|
|
||||||
public string Url { get; set; } = string.Empty;
|
|
||||||
public long Size { get; set; } = 0;
|
|
||||||
public bool IsForbidden { get; set; } = false;
|
|
||||||
public string ForbiddenBy { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Files;
|
|
||||||
|
|
||||||
public class FilesSendDto
|
|
||||||
{
|
|
||||||
public List<string> FileHashes { get; set; } = new();
|
|
||||||
public List<string> UIDs { get; set; } = new();
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Dto.Files;
|
|
||||||
|
|
||||||
public interface ITransferFileDto
|
|
||||||
{
|
|
||||||
string Hash { get; set; }
|
|
||||||
bool IsForbidden { get; set; }
|
|
||||||
string ForbiddenBy { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Files;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record UploadFileDto : ITransferFileDto
|
|
||||||
{
|
|
||||||
public string Hash { get; set; } = string.Empty;
|
|
||||||
public bool IsForbidden { get; set; } = false;
|
|
||||||
public string ForbiddenBy { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record BannedGroupUserDto : GroupPairDto
|
|
||||||
{
|
|
||||||
public BannedGroupUserDto(GroupData group, UserData user, string reason, DateTime bannedOn, string bannedBy) : base(group, user)
|
|
||||||
{
|
|
||||||
Reason = reason;
|
|
||||||
BannedOn = bannedOn;
|
|
||||||
BannedBy = bannedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Reason { get; set; }
|
|
||||||
public DateTime BannedOn { get; set; }
|
|
||||||
public string BannedBy { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GroupDto(GroupData Group)
|
|
||||||
{
|
|
||||||
public GroupData Group { get; set; } = Group;
|
|
||||||
public string GID => Group.GID;
|
|
||||||
public string? GroupAlias => Group.Alias;
|
|
||||||
public string GroupAliasOrGID => Group.AliasOrGID;
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GroupFullInfoDto(GroupData Group, UserData Owner, GroupPermissions GroupPermissions, GroupUserPermissions GroupUserPermissions, GroupUserInfo GroupUserInfo) : GroupInfoDto(Group, Owner, GroupPermissions)
|
|
||||||
{
|
|
||||||
public GroupUserPermissions GroupUserPermissions { get; set; } = GroupUserPermissions;
|
|
||||||
public GroupUserInfo GroupUserInfo { get; set; } = GroupUserInfo;
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GroupInfoDto(GroupData Group, UserData Owner, GroupPermissions GroupPermissions) : GroupDto(Group)
|
|
||||||
{
|
|
||||||
public GroupPermissions GroupPermissions { get; set; } = GroupPermissions;
|
|
||||||
public UserData Owner { get; set; } = Owner;
|
|
||||||
|
|
||||||
public string OwnerUID => Owner.UID;
|
|
||||||
public string? OwnerAlias => Owner.Alias;
|
|
||||||
public string OwnerAliasOrUID => Owner.AliasOrUID;
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GroupPairDto(GroupData Group, UserData User) : GroupDto(Group)
|
|
||||||
{
|
|
||||||
public string UID => User.UID;
|
|
||||||
public string? UserAlias => User.Alias;
|
|
||||||
public string UserAliasOrUID => User.AliasOrUID;
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GroupPairFullInfoDto(GroupData Group, UserData User, GroupUserInfo GroupPairStatusInfo, GroupUserPermissions GroupUserPermissions) : GroupPairDto(Group, User)
|
|
||||||
{
|
|
||||||
public GroupUserInfo GroupPairStatusInfo { get; set; } = GroupPairStatusInfo;
|
|
||||||
public GroupUserPermissions GroupUserPermissions { get; set; } = GroupUserPermissions;
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GroupPairUserInfoDto(GroupData Group, UserData User, GroupUserInfo GroupUserInfo) : GroupPairDto(Group, User);
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GroupPairUserPermissionDto(GroupData Group, UserData User, GroupUserPermissions GroupPairPermissions) : GroupPairDto(Group, User);
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GroupPasswordDto(GroupData Group, string Password) : GroupDto(Group);
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.Group;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record GroupPermissionDto(GroupData Group, GroupPermissions Permissions) : GroupDto(Group);
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record SystemInfoDto
|
|
||||||
{
|
|
||||||
public int OnlineUsers { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.User;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record OnlineUserCharaDataDto(UserData User, CharacterData CharaData) : UserDto(User);
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.User;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record OnlineUserIdentDto(UserData User, string Ident) : UserDto(User);
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.User;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record UserCharaDataMessageDto(List<UserData> Recipients, CharacterData CharaData);
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.User;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record UserDto(UserData User);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.User;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record UserPairDto(UserData User, UserPermissions OwnPermissions, UserPermissions OtherPermissions) : UserDto(User)
|
|
||||||
{
|
|
||||||
public UserPermissions OwnPermissions { get; set; } = OwnPermissions;
|
|
||||||
public UserPermissions OtherPermissions { get; set; } = OtherPermissions;
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.User;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record UserPermissionsDto(UserData User, UserPermissions Permissions) : UserDto(User);
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.User;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record UserProfileDto(UserData User, bool Disabled, bool? IsNSFW, string? ProfilePictureBase64, string? Description) : UserDto(User);
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MessagePack;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.Dto.User;
|
|
||||||
|
|
||||||
[MessagePackObject(keyAsPropertyName: true)]
|
|
||||||
public record UserProfileReportDto(UserData User, string ProfileReport) : UserDto(User);
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="MessagePack.Annotations" Version="2.5.129" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Version 17
|
|
||||||
VisualStudioVersion = 17.2.32602.215
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MareSynchronos.API", "MareSynchronos.API.csproj", "{CD05EE19-802F-4490-AAD8-CAD4BF1D630D}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{CD05EE19-802F-4490-AAD8-CAD4BF1D630D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{CD05EE19-802F-4490-AAD8-CAD4BF1D630D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{CD05EE19-802F-4490-AAD8-CAD4BF1D630D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{CD05EE19-802F-4490-AAD8-CAD4BF1D630D}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {DFB70C71-AB27-468D-A08B-218CA79BF69D}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Routes;
|
|
||||||
|
|
||||||
public class MareAuth
|
|
||||||
{
|
|
||||||
public const string Auth = "/auth";
|
|
||||||
public const string Auth_CreateIdent = "createWithIdent";
|
|
||||||
public const string Auth_CreateIdentV2 = "createWithIdentV2";
|
|
||||||
public const string Auth_Register = "registerNewKey";
|
|
||||||
public const string Auth_RegisterV2 = "registerNewKeyV2";
|
|
||||||
public static Uri AuthFullPath(Uri baseUri) => new Uri(baseUri, Auth + "/" + Auth_CreateIdent);
|
|
||||||
public static Uri AuthV2FullPath(Uri baseUri) => new Uri(baseUri, Auth + "/" + Auth_CreateIdentV2);
|
|
||||||
public static Uri AuthRegisterFullPath(Uri baseUri) => new Uri(baseUri, Auth + "/" + Auth_Register);
|
|
||||||
public static Uri AuthRegisterV2FullPath(Uri baseUri) => new Uri(baseUri, Auth + "/" + Auth_RegisterV2);
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
namespace MareSynchronos.API.Routes;
|
|
||||||
|
|
||||||
public class MareFiles
|
|
||||||
{
|
|
||||||
public const string Cache = "/cache";
|
|
||||||
public const string Cache_Get = "get";
|
|
||||||
|
|
||||||
public const string Request = "/request";
|
|
||||||
public const string Request_Cancel = "cancel";
|
|
||||||
public const string Request_Check = "check";
|
|
||||||
public const string Request_Enqueue = "enqueue";
|
|
||||||
public const string Request_RequestFile = "file";
|
|
||||||
|
|
||||||
public const string ServerFiles = "/files";
|
|
||||||
public const string ServerFiles_DeleteAll = "deleteAll";
|
|
||||||
public const string ServerFiles_FilesSend = "filesSend";
|
|
||||||
public const string ServerFiles_GetSizes = "getFileSizes";
|
|
||||||
public const string ServerFiles_Upload = "upload";
|
|
||||||
public const string ServerFiles_UploadRaw = "uploadRaw";
|
|
||||||
public const string ServerFiles_UploadMunged = "uploadMunged";
|
|
||||||
|
|
||||||
public const string Distribution = "/dist";
|
|
||||||
public const string Distribution_Get = "get";
|
|
||||||
|
|
||||||
public const string Main = "/main";
|
|
||||||
public const string Main_SendReady = "sendReady";
|
|
||||||
|
|
||||||
public static Uri CacheGetFullPath(Uri baseUri, Guid requestId) => new(baseUri, Cache + "/" + Cache_Get + "?requestId=" + requestId.ToString());
|
|
||||||
|
|
||||||
public static Uri RequestCancelFullPath(Uri baseUri, Guid guid) => new Uri(baseUri, Request + "/" + Request_Cancel + "?requestId=" + guid.ToString());
|
|
||||||
public static Uri RequestCheckQueueFullPath(Uri baseUri, Guid guid) => new Uri(baseUri, Request + "/" + Request_Check + "?requestId=" + guid.ToString());
|
|
||||||
public static Uri RequestEnqueueFullPath(Uri baseUri) => new(baseUri, Request + "/" + Request_Enqueue);
|
|
||||||
public static Uri RequestRequestFileFullPath(Uri baseUri, string hash) => new(baseUri, Request + "/" + Request_RequestFile + "?file=" + hash);
|
|
||||||
|
|
||||||
public static Uri ServerFilesDeleteAllFullPath(Uri baseUri) => new(baseUri, ServerFiles + "/" + ServerFiles_DeleteAll);
|
|
||||||
public static Uri ServerFilesFilesSendFullPath(Uri baseUri) => new(baseUri, ServerFiles + "/" + ServerFiles_FilesSend);
|
|
||||||
public static Uri ServerFilesGetSizesFullPath(Uri baseUri) => new(baseUri, ServerFiles + "/" + ServerFiles_GetSizes);
|
|
||||||
public static Uri ServerFilesUploadFullPath(Uri baseUri, string hash) => new(baseUri, ServerFiles + "/" + ServerFiles_Upload + "/" + hash);
|
|
||||||
public static Uri ServerFilesUploadRawFullPath(Uri baseUri, string hash) => new(baseUri, ServerFiles + "/" + ServerFiles_UploadRaw + "/" + hash);
|
|
||||||
public static Uri ServerFilesUploadMunged(Uri baseUri, string hash) => new(baseUri, ServerFiles + "/" + ServerFiles_UploadMunged + "/" + hash);
|
|
||||||
|
|
||||||
public static Uri DistributionGetFullPath(Uri baseUri, string hash) => new(baseUri, Distribution + "/" + Distribution_Get + "?file=" + hash);
|
|
||||||
|
|
||||||
public static Uri MainSendReadyFullPath(Uri baseUri, string uid, Guid request) => new(baseUri, Main + "/" + Main_SendReady + "/" + "?uid=" + uid + "&requestId=" + request.ToString());
|
|
||||||
}
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
using MareSynchronos.API.Dto;
|
|
||||||
using MareSynchronos.API.Dto.CharaData;
|
|
||||||
using MareSynchronos.API.Dto.Chat;
|
|
||||||
using MareSynchronos.API.Dto.Group;
|
|
||||||
using MareSynchronos.API.Dto.User;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.SignalR;
|
|
||||||
|
|
||||||
public interface IMareHub
|
|
||||||
{
|
|
||||||
const int ApiVersion = 1026;
|
|
||||||
const string Path = "/mare";
|
|
||||||
|
|
||||||
Task<bool> CheckClientHealth();
|
|
||||||
|
|
||||||
Task Client_DownloadReady(Guid requestId);
|
|
||||||
|
|
||||||
Task Client_GroupChangePermissions(GroupPermissionDto groupPermission);
|
|
||||||
|
|
||||||
Task Client_GroupChatMsg(GroupChatMsgDto groupChatMsgDto);
|
|
||||||
|
|
||||||
Task Client_GroupDelete(GroupDto groupDto);
|
|
||||||
|
|
||||||
Task Client_GroupPairChangePermissions(GroupPairUserPermissionDto permissionDto);
|
|
||||||
|
|
||||||
Task Client_GroupPairChangeUserInfo(GroupPairUserInfoDto userInfo);
|
|
||||||
|
|
||||||
Task Client_GroupPairJoined(GroupPairFullInfoDto groupPairInfoDto);
|
|
||||||
|
|
||||||
Task Client_GroupPairLeft(GroupPairDto groupPairDto);
|
|
||||||
|
|
||||||
Task Client_GroupSendFullInfo(GroupFullInfoDto groupInfo);
|
|
||||||
|
|
||||||
Task Client_GroupSendInfo(GroupInfoDto groupInfo);
|
|
||||||
|
|
||||||
Task Client_ReceiveServerMessage(MessageSeverity messageSeverity, string message);
|
|
||||||
|
|
||||||
Task Client_UpdateSystemInfo(SystemInfoDto systemInfo);
|
|
||||||
|
|
||||||
Task Client_UserAddClientPair(UserPairDto dto);
|
|
||||||
|
|
||||||
Task Client_UserChatMsg(UserChatMsgDto chatMsgDto);
|
|
||||||
|
|
||||||
Task Client_UserReceiveCharacterData(OnlineUserCharaDataDto dataDto);
|
|
||||||
|
|
||||||
Task Client_UserReceiveUploadStatus(UserDto dto);
|
|
||||||
|
|
||||||
Task Client_UserRemoveClientPair(UserDto dto);
|
|
||||||
|
|
||||||
Task Client_UserSendOffline(UserDto dto);
|
|
||||||
|
|
||||||
Task Client_UserSendOnline(OnlineUserIdentDto dto);
|
|
||||||
|
|
||||||
Task Client_UserUpdateOtherPairPermissions(UserPermissionsDto dto);
|
|
||||||
|
|
||||||
Task Client_UserUpdateProfile(UserDto dto);
|
|
||||||
|
|
||||||
Task Client_UserUpdateSelfPairPermissions(UserPermissionsDto dto);
|
|
||||||
|
|
||||||
Task Client_GposeLobbyJoin(UserData userData);
|
|
||||||
Task Client_GposeLobbyLeave(UserData userData);
|
|
||||||
Task Client_GposeLobbyPushCharacterData(CharaDataDownloadDto charaDownloadDto);
|
|
||||||
Task Client_GposeLobbyPushPoseData(UserData userData, PoseData poseData);
|
|
||||||
Task Client_GposeLobbyPushWorldData(UserData userData, WorldData worldData);
|
|
||||||
|
|
||||||
Task<ConnectionDto> GetConnectionDto();
|
|
||||||
|
|
||||||
Task GroupBanUser(GroupPairDto dto, string reason);
|
|
||||||
|
|
||||||
Task GroupChangeGroupPermissionState(GroupPermissionDto dto);
|
|
||||||
|
|
||||||
Task GroupChangeIndividualPermissionState(GroupPairUserPermissionDto dto);
|
|
||||||
|
|
||||||
Task GroupChangeOwnership(GroupPairDto groupPair);
|
|
||||||
|
|
||||||
Task<bool> GroupChangePassword(GroupPasswordDto groupPassword);
|
|
||||||
|
|
||||||
Task GroupChatSendMsg(GroupDto group, ChatMessage message);
|
|
||||||
|
|
||||||
Task GroupClear(GroupDto group);
|
|
||||||
|
|
||||||
Task<GroupPasswordDto> GroupCreate();
|
|
||||||
|
|
||||||
Task<List<string>> GroupCreateTempInvite(GroupDto group, int amount);
|
|
||||||
|
|
||||||
Task GroupDelete(GroupDto group);
|
|
||||||
|
|
||||||
Task<List<BannedGroupUserDto>> GroupGetBannedUsers(GroupDto group);
|
|
||||||
|
|
||||||
Task<bool> GroupJoin(GroupPasswordDto passwordedGroup);
|
|
||||||
|
|
||||||
Task GroupLeave(GroupDto group);
|
|
||||||
|
|
||||||
Task GroupRemoveUser(GroupPairDto groupPair);
|
|
||||||
|
|
||||||
Task GroupSetUserInfo(GroupPairUserInfoDto groupPair);
|
|
||||||
|
|
||||||
Task<List<GroupFullInfoDto>> GroupsGetAll();
|
|
||||||
|
|
||||||
Task<List<GroupPairFullInfoDto>> GroupsGetUsersInGroup(GroupDto group);
|
|
||||||
|
|
||||||
Task GroupUnbanUser(GroupPairDto groupPair);
|
|
||||||
Task<int> GroupPrune(GroupDto group, int days, bool execute);
|
|
||||||
|
|
||||||
Task UserAddPair(UserDto user);
|
|
||||||
|
|
||||||
Task UserChatSendMsg(UserDto user, ChatMessage message);
|
|
||||||
|
|
||||||
Task UserDelete();
|
|
||||||
|
|
||||||
Task<List<OnlineUserIdentDto>> UserGetOnlinePairs();
|
|
||||||
|
|
||||||
Task<List<UserPairDto>> UserGetPairedClients();
|
|
||||||
|
|
||||||
Task<UserProfileDto> UserGetProfile(UserDto dto);
|
|
||||||
|
|
||||||
Task UserPushData(UserCharaDataMessageDto dto);
|
|
||||||
|
|
||||||
Task UserRemovePair(UserDto userDto);
|
|
||||||
|
|
||||||
Task UserReportProfile(UserProfileReportDto userDto);
|
|
||||||
|
|
||||||
Task UserSetPairPermissions(UserPermissionsDto userPermissions);
|
|
||||||
|
|
||||||
Task UserSetProfile(UserProfileDto userDescription);
|
|
||||||
|
|
||||||
Task<CharaDataFullDto?> CharaDataCreate();
|
|
||||||
Task<CharaDataFullDto?> CharaDataUpdate(CharaDataUpdateDto updateDto);
|
|
||||||
Task<bool> CharaDataDelete(string id);
|
|
||||||
Task<CharaDataMetaInfoDto?> CharaDataGetMetainfo(string id);
|
|
||||||
Task<CharaDataDownloadDto?> CharaDataDownload(string id);
|
|
||||||
Task<List<CharaDataFullDto>> CharaDataGetOwn();
|
|
||||||
Task<List<CharaDataMetaInfoDto>> CharaDataGetShared();
|
|
||||||
Task<CharaDataFullDto?> CharaDataAttemptRestore(string id);
|
|
||||||
|
|
||||||
Task<string> GposeLobbyCreate();
|
|
||||||
Task<List<UserData>> GposeLobbyJoin(string lobbyId);
|
|
||||||
Task<bool> GposeLobbyLeave();
|
|
||||||
Task GposeLobbyPushCharacterData(CharaDataDownloadDto charaDownloadDto);
|
|
||||||
Task GposeLobbyPushPoseData(PoseData poseData);
|
|
||||||
Task GposeLobbyPushWorldData(WorldData worldData);
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
using MareSynchronos.API.Data;
|
|
||||||
using MareSynchronos.API.Data.Enum;
|
|
||||||
using MareSynchronos.API.Dto;
|
|
||||||
using MareSynchronos.API.Dto.CharaData;
|
|
||||||
using MareSynchronos.API.Dto.Chat;
|
|
||||||
using MareSynchronos.API.Dto.Group;
|
|
||||||
using MareSynchronos.API.Dto.User;
|
|
||||||
|
|
||||||
namespace MareSynchronos.API.SignalR;
|
|
||||||
|
|
||||||
public interface IMareHubClient : IMareHub
|
|
||||||
{
|
|
||||||
void OnDownloadReady(Action<Guid> act);
|
|
||||||
|
|
||||||
void OnGroupChangePermissions(Action<GroupPermissionDto> act);
|
|
||||||
|
|
||||||
void OnGroupChatMsg(Action<GroupChatMsgDto> groupChatMsgDto);
|
|
||||||
|
|
||||||
void OnGroupDelete(Action<GroupDto> act);
|
|
||||||
|
|
||||||
void OnGroupPairChangePermissions(Action<GroupPairUserPermissionDto> act);
|
|
||||||
|
|
||||||
void OnGroupPairChangeUserInfo(Action<GroupPairUserInfoDto> act);
|
|
||||||
|
|
||||||
void OnGroupPairJoined(Action<GroupPairFullInfoDto> act);
|
|
||||||
|
|
||||||
void OnGroupPairLeft(Action<GroupPairDto> act);
|
|
||||||
|
|
||||||
void OnGroupSendFullInfo(Action<GroupFullInfoDto> act);
|
|
||||||
|
|
||||||
void OnGroupSendInfo(Action<GroupInfoDto> act);
|
|
||||||
|
|
||||||
void OnReceiveServerMessage(Action<MessageSeverity, string> act);
|
|
||||||
|
|
||||||
void OnUpdateSystemInfo(Action<SystemInfoDto> act);
|
|
||||||
|
|
||||||
void OnUserAddClientPair(Action<UserPairDto> act);
|
|
||||||
|
|
||||||
void OnUserChatMsg(Action<UserChatMsgDto> chatMsgDto);
|
|
||||||
|
|
||||||
void OnUserReceiveCharacterData(Action<OnlineUserCharaDataDto> act);
|
|
||||||
|
|
||||||
void OnUserReceiveUploadStatus(Action<UserDto> act);
|
|
||||||
|
|
||||||
void OnUserRemoveClientPair(Action<UserDto> act);
|
|
||||||
|
|
||||||
void OnUserSendOffline(Action<UserDto> act);
|
|
||||||
|
|
||||||
void OnUserSendOnline(Action<OnlineUserIdentDto> act);
|
|
||||||
|
|
||||||
void OnUserUpdateOtherPairPermissions(Action<UserPermissionsDto> act);
|
|
||||||
|
|
||||||
void OnUserUpdateProfile(Action<UserDto> act);
|
|
||||||
|
|
||||||
void OnUserUpdateSelfPairPermissions(Action<UserPermissionsDto> act);
|
|
||||||
|
|
||||||
void OnGposeLobbyJoin(Action<UserData> act);
|
|
||||||
void OnGposeLobbyLeave(Action<UserData> act);
|
|
||||||
void OnGposeLobbyPushCharacterData(Action<CharaDataDownloadDto> act);
|
|
||||||
void OnGposeLobbyPushPoseData(Action<UserData, PoseData> act);
|
|
||||||
void OnGposeLobbyPushWorldData(Action<UserData, WorldData> act);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user