finalize petnames & performance service
This commit is contained in:
@@ -8,13 +8,12 @@ public class CharacterData
|
|||||||
{
|
{
|
||||||
public Dictionary<ObjectKind, string> CustomizePlusScale { get; set; } = [];
|
public Dictionary<ObjectKind, string> CustomizePlusScale { get; set; } = [];
|
||||||
public Dictionary<ObjectKind, HashSet<FileReplacement>> FileReplacements { get; set; } = [];
|
public Dictionary<ObjectKind, HashSet<FileReplacement>> FileReplacements { get; set; } = [];
|
||||||
|
|
||||||
public Dictionary<ObjectKind, string> GlamourerString { get; set; } = [];
|
public Dictionary<ObjectKind, string> GlamourerString { get; set; } = [];
|
||||||
|
|
||||||
public string HeelsData { get; set; } = string.Empty;
|
public string HeelsData { get; set; } = string.Empty;
|
||||||
public string HonorificData { get; set; } = string.Empty;
|
public string HonorificData { get; set; } = string.Empty;
|
||||||
public string ManipulationString { get; set; } = string.Empty;
|
public string ManipulationString { get; set; } = string.Empty;
|
||||||
public string MoodlesData { get; set; } = string.Empty;
|
public string MoodlesData { get; set; } = string.Empty;
|
||||||
|
public string PetNamesData { get; set; } = string.Empty;
|
||||||
|
|
||||||
public API.Data.CharacterData ToAPI()
|
public API.Data.CharacterData ToAPI()
|
||||||
{
|
{
|
||||||
@@ -44,7 +43,8 @@ public class CharacterData
|
|||||||
HeelsData = HeelsData,
|
HeelsData = HeelsData,
|
||||||
CustomizePlusData = CustomizePlusScale.ToDictionary(d => d.Key, d => d.Value),
|
CustomizePlusData = CustomizePlusScale.ToDictionary(d => d.Key, d => d.Value),
|
||||||
HonorificData = HonorificData,
|
HonorificData = HonorificData,
|
||||||
MoodlesData = MoodlesData
|
MoodlesData = MoodlesData,
|
||||||
|
PetNamesData = PetNamesData
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,4 +10,5 @@ public enum PlayerChanges
|
|||||||
Honorific = 7,
|
Honorific = 7,
|
||||||
ForcedRedraw = 8,
|
ForcedRedraw = 8,
|
||||||
Moodles = 9,
|
Moodles = 9,
|
||||||
|
PetNames = 10,
|
||||||
}
|
}
|
||||||
@@ -218,8 +218,8 @@ public class PlayerDataFactory
|
|||||||
previousData.MoodlesData = await _ipcManager.Moodles.GetStatusAsync(playerRelatedObject.Address).ConfigureAwait(false) ?? string.Empty;
|
previousData.MoodlesData = await _ipcManager.Moodles.GetStatusAsync(playerRelatedObject.Address).ConfigureAwait(false) ?? string.Empty;
|
||||||
_logger.LogDebug("Moodles is now: {moodles}", previousData.MoodlesData);
|
_logger.LogDebug("Moodles is now: {moodles}", previousData.MoodlesData);
|
||||||
|
|
||||||
previousData.MoodlesData = _ipcManager.PetNames.GetLocalNames();
|
previousData.PetNamesData = _ipcManager.PetNames.GetLocalNames();
|
||||||
_logger.LogDebug("Pet Nicknames is now: {moodles}", previousData.MoodlesData);
|
_logger.LogDebug("Pet Nicknames is now: {petnames}", previousData.PetNamesData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previousData.FileReplacements.TryGetValue(objectKind, out HashSet<FileReplacement>? fileReplacements))
|
if (previousData.FileReplacements.TryGetValue(objectKind, out HashSet<FileReplacement>? fileReplacements))
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using MareSynchronos.API.Data;
|
using MareSynchronos.API.Data;
|
||||||
using MareSynchronos.API.Dto.User;
|
|
||||||
using MareSynchronos.FileCache;
|
using MareSynchronos.FileCache;
|
||||||
using MareSynchronos.Interop.Ipc;
|
using MareSynchronos.Interop.Ipc;
|
||||||
using MareSynchronos.PlayerData.Factories;
|
using MareSynchronos.PlayerData.Factories;
|
||||||
@@ -344,8 +343,10 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
case PlayerChanges.Moodles:
|
case PlayerChanges.Moodles:
|
||||||
await _ipcManager.Moodles.SetStatusAsync(handler.Address, charaData.MoodlesData).ConfigureAwait(false);
|
await _ipcManager.Moodles.SetStatusAsync(handler.Address, charaData.MoodlesData).ConfigureAwait(false);
|
||||||
|
break;
|
||||||
|
|
||||||
await _ipcManager.PetNames.SetPlayerData(handler.Address, charaData.MoodlesData).ConfigureAwait(false);
|
case PlayerChanges.PetNames:
|
||||||
|
await _ipcManager.PetNames.SetPlayerData(handler.Address, charaData.PetNamesData).ConfigureAwait(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlayerChanges.ForcedRedraw:
|
case PlayerChanges.ForcedRedraw:
|
||||||
@@ -378,135 +379,135 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
|
|||||||
_downloadCancellationTokenSource = _downloadCancellationTokenSource?.CancelRecreate() ?? new CancellationTokenSource();
|
_downloadCancellationTokenSource = _downloadCancellationTokenSource?.CancelRecreate() ?? new CancellationTokenSource();
|
||||||
var downloadToken = _downloadCancellationTokenSource.Token;
|
var downloadToken = _downloadCancellationTokenSource.Token;
|
||||||
|
|
||||||
_ = Task.Run(async () =>
|
_ = DownloadAndApplyCharacterAsync(applicationBase, charaData, updatedData, updateModdedPaths, updateManip, downloadToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DownloadAndApplyCharacterAsync(Guid applicationBase, CharacterData charaData, Dictionary<ObjectKind, HashSet<PlayerChanges>> updatedData,
|
||||||
|
bool updateModdedPaths, bool updateManip, CancellationToken downloadToken)
|
||||||
|
{
|
||||||
|
Dictionary<(string GamePath, string? Hash), string> moddedPaths = [];
|
||||||
|
|
||||||
|
if (updateModdedPaths)
|
||||||
{
|
{
|
||||||
Dictionary<(string GamePath, string? Hash), string> moddedPaths = [];
|
int attempts = 0;
|
||||||
|
List<FileReplacementData> toDownloadReplacements = TryCalculateModdedDictionary(applicationBase, charaData, out moddedPaths, downloadToken);
|
||||||
|
|
||||||
|
while (toDownloadReplacements.Count > 0 && attempts++ <= 10 && !downloadToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
_downloadManager.CancelDownload();
|
||||||
|
Logger.LogDebug("[BASE-{appBase}] Downloading missing files for player {name}, {kind}", applicationBase, PlayerName, updatedData);
|
||||||
|
|
||||||
|
Mediator.Publish(new EventMessage(new Event(PlayerName, Pair.UserData, nameof(PairHandler), EventSeverity.Informational,
|
||||||
|
$"Starting download for {toDownloadReplacements.Count} files")));
|
||||||
|
var toDownloadFiles = await _downloadManager.InitiateDownloadList(_charaHandler!, toDownloadReplacements, downloadToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (!_playerPerformanceService.ComputeAndAutoPauseOnVRAMUsageThresholds(this, charaData, toDownloadFiles))
|
||||||
|
{
|
||||||
|
_downloadManager.CancelDownload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _downloadManager.DownloadFiles(_charaHandler!, toDownloadReplacements, downloadToken).ConfigureAwait(false);
|
||||||
|
_downloadManager.CancelDownload();
|
||||||
|
|
||||||
|
if (downloadToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
Logger.LogTrace("[BASE-{appBase}] Detected cancellation", applicationBase);
|
||||||
|
_downloadManager.CancelDownload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toDownloadReplacements = TryCalculateModdedDictionary(applicationBase, charaData, out moddedPaths, downloadToken);
|
||||||
|
|
||||||
|
if (toDownloadReplacements.TrueForAll(c => _downloadManager.ForbiddenTransfers.Exists(f => string.Equals(f.Hash, c.Hash, StringComparison.Ordinal))))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await _playerPerformanceService.CheckBothThresholds(this, charaData).ConfigureAwait(false))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
var appToken = _applicationCancellationTokenSource?.Token;
|
||||||
|
while ((!_applicationTask?.IsCompleted ?? false)
|
||||||
|
&& !downloadToken.IsCancellationRequested
|
||||||
|
&& (!appToken?.IsCancellationRequested ?? false))
|
||||||
|
{
|
||||||
|
// block until current application is done
|
||||||
|
Logger.LogDebug("[BASE-{appBase}] Waiting for current data application (Id: {id}) for player ({handler}) to finish", applicationBase, _applicationId, PlayerName);
|
||||||
|
await Task.Delay(250).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloadToken.IsCancellationRequested || (appToken?.IsCancellationRequested ?? false)) return;
|
||||||
|
|
||||||
|
_applicationCancellationTokenSource = _applicationCancellationTokenSource.CancelRecreate() ?? new CancellationTokenSource();
|
||||||
|
var token = _applicationCancellationTokenSource.Token;
|
||||||
|
|
||||||
|
_applicationTask = ApplyCharacterDataAsync(applicationBase, charaData, updatedData, updateModdedPaths, updateManip, moddedPaths, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ApplyCharacterDataAsync(Guid applicationBase, CharacterData charaData, Dictionary<ObjectKind, HashSet<PlayerChanges>> updatedData, bool updateModdedPaths, bool updateManip,
|
||||||
|
Dictionary<(string GamePath, string? Hash), string> moddedPaths, CancellationToken token)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_applicationId = Guid.NewGuid();
|
||||||
|
Logger.LogDebug("[BASE-{applicationId}] Starting application task for {this}: {appId}", applicationBase, this, _applicationId);
|
||||||
|
|
||||||
|
Logger.LogDebug("[{applicationId}] Waiting for initial draw for for {handler}", _applicationId, _charaHandler);
|
||||||
|
await _dalamudUtil.WaitWhileCharacterIsDrawing(Logger, _charaHandler!, _applicationId, 30000, token).ConfigureAwait(false);
|
||||||
|
|
||||||
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
if (updateModdedPaths)
|
if (updateModdedPaths)
|
||||||
{
|
{
|
||||||
int attempts = 0;
|
await _ipcManager.Penumbra.SetTemporaryModsAsync(Logger, _applicationId, _penumbraCollection,
|
||||||
List<FileReplacementData> toDownloadReplacements = TryCalculateModdedDictionary(applicationBase, charaData, out moddedPaths, downloadToken);
|
moddedPaths.ToDictionary(k => k.Key.GamePath, k => k.Value, StringComparer.Ordinal)).ConfigureAwait(false);
|
||||||
|
LastAppliedDataBytes = -1;
|
||||||
while (toDownloadReplacements.Count > 0 && attempts++ <= 10 && !downloadToken.IsCancellationRequested)
|
foreach (var path in moddedPaths.Values.Distinct(StringComparer.OrdinalIgnoreCase).Select(v => new FileInfo(v)).Where(p => p.Exists))
|
||||||
{
|
{
|
||||||
_downloadManager.CancelDownload();
|
if (LastAppliedDataBytes == -1) LastAppliedDataBytes = 0;
|
||||||
Logger.LogDebug("[BASE-{appBase}] Downloading missing files for player {name}, {kind}", applicationBase, PlayerName, updatedData);
|
|
||||||
|
|
||||||
Mediator.Publish(new EventMessage(new Event(PlayerName, Pair.UserData, nameof(PairHandler), EventSeverity.Informational,
|
LastAppliedDataBytes += path.Length;
|
||||||
$"Starting download for {toDownloadReplacements.Count} files")));
|
|
||||||
var toDownloadFiles = await _downloadManager.InitiateDownloadList(_charaHandler!, toDownloadReplacements, downloadToken).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (!_playerPerformanceService.CheckVRAMUsageThresholds(this, charaData, toDownloadFiles))
|
|
||||||
{
|
|
||||||
_downloadManager.CancelDownload();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await _downloadManager.DownloadFiles(_charaHandler!, toDownloadReplacements, downloadToken).ConfigureAwait(false);
|
|
||||||
_downloadManager.CancelDownload();
|
|
||||||
|
|
||||||
if (downloadToken.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
Logger.LogTrace("[BASE-{appBase}] Detected cancellation", applicationBase);
|
|
||||||
_downloadManager.CancelDownload();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
toDownloadReplacements = TryCalculateModdedDictionary(applicationBase, charaData, out moddedPaths, downloadToken);
|
|
||||||
|
|
||||||
if (toDownloadReplacements.TrueForAll(c => _downloadManager.ForbiddenTransfers.Exists(f => string.Equals(f.Hash, c.Hash, StringComparison.Ordinal))))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attempts == 0 && !_playerPerformanceService.CheckVRAMUsageThresholds(this, charaData, []))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!await _playerPerformanceService.CheckTriangleUsageThresholds(this, charaData).ConfigureAwait(false))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadToken.ThrowIfCancellationRequested();
|
if (updateManip)
|
||||||
|
|
||||||
var appToken = _applicationCancellationTokenSource?.Token;
|
|
||||||
while ((!_applicationTask?.IsCompleted ?? false)
|
|
||||||
&& !downloadToken.IsCancellationRequested
|
|
||||||
&& (!appToken?.IsCancellationRequested ?? false))
|
|
||||||
{
|
{
|
||||||
// block until current application is done
|
await _ipcManager.Penumbra.SetManipulationDataAsync(Logger, _applicationId, _penumbraCollection, charaData.ManipulationData).ConfigureAwait(false);
|
||||||
Logger.LogDebug("[BASE-{appBase}] Waiting for current data application (Id: {id}) for player ({handler}) to finish", applicationBase, _applicationId, PlayerName);
|
|
||||||
await Task.Delay(250).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (downloadToken.IsCancellationRequested || (appToken?.IsCancellationRequested ?? false)) return;
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
_applicationCancellationTokenSource = _applicationCancellationTokenSource.CancelRecreate() ?? new CancellationTokenSource();
|
foreach (var kind in updatedData)
|
||||||
var token = _applicationCancellationTokenSource.Token;
|
|
||||||
_applicationTask = Task.Run(async () =>
|
|
||||||
{
|
{
|
||||||
try
|
await ApplyCustomizationDataAsync(_applicationId, kind, charaData, token).ConfigureAwait(false);
|
||||||
{
|
token.ThrowIfCancellationRequested();
|
||||||
_applicationId = Guid.NewGuid();
|
}
|
||||||
Logger.LogDebug("[BASE-{applicationId}] Starting application task for {this}: {appId}", applicationBase, this, _applicationId);
|
|
||||||
|
|
||||||
Logger.LogDebug("[{applicationId}] Waiting for initial draw for for {handler}", _applicationId, _charaHandler);
|
_cachedData = charaData;
|
||||||
await _dalamudUtil.WaitWhileCharacterIsDrawing(Logger, _charaHandler!, _applicationId, 30000, token).ConfigureAwait(false);
|
|
||||||
|
|
||||||
token.ThrowIfCancellationRequested();
|
Logger.LogDebug("[{applicationId}] Application finished", _applicationId);
|
||||||
|
}
|
||||||
if (updateModdedPaths)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await _ipcManager.Penumbra.SetTemporaryModsAsync(Logger, _applicationId, _penumbraCollection,
|
if (ex is AggregateException aggr && aggr.InnerExceptions.Any(e => e is ArgumentNullException))
|
||||||
moddedPaths.ToDictionary(k => k.Key.GamePath, k => k.Value, StringComparer.Ordinal)).ConfigureAwait(false);
|
{
|
||||||
LastAppliedDataBytes = -1;
|
IsVisible = false;
|
||||||
foreach (var path in moddedPaths.Values.Distinct(StringComparer.OrdinalIgnoreCase).Select(v => new FileInfo(v)).Where(p => p.Exists))
|
_forceApplyMods = true;
|
||||||
{
|
_cachedData = charaData;
|
||||||
if (LastAppliedDataBytes == -1) LastAppliedDataBytes = 0;
|
Logger.LogDebug("[{applicationId}] Cancelled, player turned null during application", _applicationId);
|
||||||
|
}
|
||||||
LastAppliedDataBytes += path.Length;
|
else
|
||||||
}
|
{
|
||||||
}
|
Logger.LogWarning(ex, "[{applicationId}] Cancelled", _applicationId);
|
||||||
|
}
|
||||||
if (updateManip)
|
}
|
||||||
{
|
|
||||||
await _ipcManager.Penumbra.SetManipulationDataAsync(Logger, _applicationId, _penumbraCollection, charaData.ManipulationData).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
token.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
foreach (var kind in updatedData)
|
|
||||||
{
|
|
||||||
await ApplyCustomizationDataAsync(_applicationId, kind, charaData, token).ConfigureAwait(false);
|
|
||||||
token.ThrowIfCancellationRequested();
|
|
||||||
}
|
|
||||||
|
|
||||||
_cachedData = charaData;
|
|
||||||
|
|
||||||
Logger.LogDebug("[{applicationId}] Application finished", _applicationId);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (ex is AggregateException aggr && aggr.InnerExceptions.Any(e => e is ArgumentNullException))
|
|
||||||
{
|
|
||||||
IsVisible = false;
|
|
||||||
_forceApplyMods = true;
|
|
||||||
_cachedData = charaData;
|
|
||||||
Logger.LogDebug("[{applicationId}] Cancelled, player turned null during application", _applicationId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.LogWarning(ex, "[{applicationId}] Cancelled", _applicationId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, token);
|
|
||||||
}, downloadToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FrameworkUpdate()
|
private void FrameworkUpdate()
|
||||||
@@ -595,7 +596,7 @@ public sealed class PairHandler : DisposableMediatorSubscriberBase
|
|||||||
await _ipcManager.Honorific.ClearTitleAsync(address).ConfigureAwait(false);
|
await _ipcManager.Honorific.ClearTitleAsync(address).ConfigureAwait(false);
|
||||||
Logger.LogDebug("[{applicationId}] Restoring Moodles for {alias}/{name}", applicationId, Pair.UserData.AliasOrUID, name);
|
Logger.LogDebug("[{applicationId}] Restoring Moodles for {alias}/{name}", applicationId, Pair.UserData.AliasOrUID, name);
|
||||||
await _ipcManager.Moodles.RevertStatusAsync(address).ConfigureAwait(false);
|
await _ipcManager.Moodles.RevertStatusAsync(address).ConfigureAwait(false);
|
||||||
Logger.LogDebug("[{applicationId}] Restoring Pet Nicknames for {alias}/{name}", applicationId, OnlineUser.User.AliasOrUID, name);
|
Logger.LogDebug("[{applicationId}] Restoring Pet Nicknames for {alias}/{name}", applicationId, Pair.UserData.AliasOrUID, name);
|
||||||
await _ipcManager.PetNames.ClearPlayerData(address).ConfigureAwait(false);
|
await _ipcManager.PetNames.ClearPlayerData(address).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else if (objectKind == ObjectKind.MinionOrMount)
|
else if (objectKind == ObjectKind.MinionOrMount)
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ public sealed class CacheCreationService : DisposableMediatorSubscriberBase
|
|||||||
Mediator.Subscribe<PetNamesMessage>(this, (msg) =>
|
Mediator.Subscribe<PetNamesMessage>(this, (msg) =>
|
||||||
{
|
{
|
||||||
if (_isZoning) return;
|
if (_isZoning) return;
|
||||||
if (!string.Equals(msg.PetNicknamesData, _playerData.MoodlesData, StringComparison.Ordinal))
|
if (!string.Equals(msg.PetNicknamesData, _playerData.PetNamesData, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
Logger.LogDebug("Received Pet Nicknames change, updating player");
|
Logger.LogDebug("Received Pet Nicknames change, updating player");
|
||||||
PetNicknamesChanged();
|
PetNicknamesChanged();
|
||||||
|
|||||||
@@ -29,6 +29,67 @@ public class PlayerPerformanceService
|
|||||||
_xivDataAnalyzer = xivDataAnalyzer;
|
_xivDataAnalyzer = xivDataAnalyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> CheckBothThresholds(PairHandler pairHandler, CharacterData charaData)
|
||||||
|
{
|
||||||
|
var config = _playerPerformanceConfigService.Current;
|
||||||
|
bool notPausedAfterVram = ComputeAndAutoPauseOnVRAMUsageThresholds(pairHandler, charaData, []);
|
||||||
|
if (!notPausedAfterVram) return false;
|
||||||
|
bool notPausedAfterTris = await CheckTriangleUsageThresholds(pairHandler, charaData).ConfigureAwait(false);
|
||||||
|
if (!notPausedAfterTris) return false;
|
||||||
|
|
||||||
|
if (config.UIDsToIgnore
|
||||||
|
.Exists(uid => string.Equals(uid, pairHandler.Pair.UserData.Alias, StringComparison.Ordinal) || string.Equals(uid, pairHandler.Pair.UserData.UID, StringComparison.Ordinal)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var vramUsage = pairHandler.Pair.LastAppliedApproximateVRAMBytes;
|
||||||
|
var triUsage = pairHandler.Pair.LastAppliedDataTris;
|
||||||
|
|
||||||
|
bool isPrefPerm = pairHandler.Pair.UserPair.OwnPermissions.HasFlag(API.Data.Enum.UserPermissions.Sticky);
|
||||||
|
|
||||||
|
bool exceedsTris = CheckForThreshold(config.WarnOnExceedingThresholds, config.TrisWarningThresholdThousands * 1000,
|
||||||
|
triUsage, config.WarnOnPreferredPermissionsExceedingThresholds, isPrefPerm);
|
||||||
|
bool exceedsVram = CheckForThreshold(config.WarnOnExceedingThresholds, config.VRAMSizeWarningThresholdMiB * 1024 * 1024,
|
||||||
|
vramUsage, config.WarnOnPreferredPermissionsExceedingThresholds, isPrefPerm);
|
||||||
|
|
||||||
|
if (exceedsVram)
|
||||||
|
{
|
||||||
|
_mediator.Publish(new EventMessage(new Event(pairHandler.Pair.PlayerName, pairHandler.Pair.UserData, nameof(PlayerPerformanceService), EventSeverity.Warning,
|
||||||
|
$"Exceeds VRAM threshold: ({UiSharedService.ByteToString(vramUsage, addSuffix: true)}/{config.VRAMSizeWarningThresholdMiB} MiB)")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exceedsTris)
|
||||||
|
{
|
||||||
|
_mediator.Publish(new EventMessage(new Event(pairHandler.Pair.PlayerName, pairHandler.Pair.UserData, nameof(PlayerPerformanceService), EventSeverity.Warning,
|
||||||
|
$"Exceeds triangle threshold: ({triUsage}/{config.TrisAutoPauseThresholdThousands * 1000} triangles)")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exceedsTris || exceedsVram)
|
||||||
|
{
|
||||||
|
string warningText = string.Empty;
|
||||||
|
if (exceedsTris && !exceedsVram)
|
||||||
|
{
|
||||||
|
warningText = $"Player {pairHandler.Pair.PlayerName} exceeds your configured triangle warning threshold (" +
|
||||||
|
$"{triUsage}/{config.TrisAutoPauseThresholdThousands * 1000} triangles).";
|
||||||
|
}
|
||||||
|
else if (!exceedsTris)
|
||||||
|
{
|
||||||
|
warningText = $"Player {pairHandler.Pair.PlayerName} exceeds your configured VRAM warning threshold (" +
|
||||||
|
$"{UiSharedService.ByteToString(vramUsage, true)}/{config.VRAMSizeWarningThresholdMiB} MiB).";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
warningText = $"Player {pairHandler.Pair.PlayerName} exceeds both VRAM warning threshold (" +
|
||||||
|
$"{UiSharedService.ByteToString(vramUsage, true)}/{config.VRAMSizeWarningThresholdMiB} MiB) and " +
|
||||||
|
$"triangle warning threshold ({triUsage}/{config.TrisAutoPauseThresholdThousands * 1000} triangles).";
|
||||||
|
}
|
||||||
|
|
||||||
|
_mediator.Publish(new NotificationMessage($"{pairHandler.Pair.PlayerName} ({pairHandler.Pair.UserData.AliasOrUID}) exceeds performance threshold(s)",
|
||||||
|
warningText, MareConfiguration.Models.NotificationType.Warning));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<bool> CheckTriangleUsageThresholds(PairHandler pairHandler, CharacterData charaData)
|
public async Task<bool> CheckTriangleUsageThresholds(PairHandler pairHandler, CharacterData charaData)
|
||||||
{
|
{
|
||||||
var config = _playerPerformanceConfigService.Current;
|
var config = _playerPerformanceConfigService.Current;
|
||||||
@@ -74,30 +135,17 @@ public class PlayerPerformanceService
|
|||||||
MareConfiguration.Models.NotificationType.Warning));
|
MareConfiguration.Models.NotificationType.Warning));
|
||||||
|
|
||||||
_mediator.Publish(new EventMessage(new Event(pair.PlayerName, pair.UserData, nameof(PlayerPerformanceService), EventSeverity.Warning,
|
_mediator.Publish(new EventMessage(new Event(pair.PlayerName, pair.UserData, nameof(PlayerPerformanceService), EventSeverity.Warning,
|
||||||
$"Exceeds triangle threshold: automatically paused ({triUsage}/{triUsage * 1000} triangles)")));
|
$"Exceeds triangle threshold: automatically paused ({triUsage}/{config.TrisAutoPauseThresholdThousands * 1000} triangles)")));
|
||||||
|
|
||||||
_mediator.Publish(new PauseMessage(pair.UserData));
|
_mediator.Publish(new PauseMessage(pair.UserData));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and fucking warnings
|
|
||||||
if (CheckForThreshold(config.WarnOnExceedingThresholds, config.TrisWarningThresholdThousands * 1000,
|
|
||||||
triUsage, config.WarnOnPreferredPermissionsExceedingThresholds, isPrefPerm))
|
|
||||||
{
|
|
||||||
_mediator.Publish(new NotificationMessage($"{pair.PlayerName} ({pair.UserData.AliasOrUID}) exceeds performance threshold",
|
|
||||||
$"Player {pair.PlayerName} exceeds your configured triangle warning threshold (" +
|
|
||||||
$"{triUsage}/{triUsage * 1000} triangles).",
|
|
||||||
MareConfiguration.Models.NotificationType.Warning));
|
|
||||||
|
|
||||||
_mediator.Publish(new EventMessage(new Event(pair.PlayerName, pair.UserData, nameof(PlayerPerformanceService), EventSeverity.Warning,
|
|
||||||
$"Exceeds triangle threshold: ({triUsage}/{triUsage * 1000} triangles)")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CheckVRAMUsageThresholds(PairHandler pairHandler, CharacterData charaData, List<DownloadFileTransfer> toDownloadFiles)
|
public bool ComputeAndAutoPauseOnVRAMUsageThresholds(PairHandler pairHandler, CharacterData charaData, List<DownloadFileTransfer> toDownloadFiles)
|
||||||
{
|
{
|
||||||
var config = _playerPerformanceConfigService.Current;
|
var config = _playerPerformanceConfigService.Current;
|
||||||
var pair = pairHandler.Pair;
|
var pair = pairHandler.Pair;
|
||||||
@@ -165,24 +213,11 @@ public class PlayerPerformanceService
|
|||||||
_mediator.Publish(new PauseMessage(pair.UserData));
|
_mediator.Publish(new PauseMessage(pair.UserData));
|
||||||
|
|
||||||
_mediator.Publish(new EventMessage(new Event(pair.PlayerName, pair.UserData, nameof(PlayerPerformanceService), EventSeverity.Warning,
|
_mediator.Publish(new EventMessage(new Event(pair.PlayerName, pair.UserData, nameof(PlayerPerformanceService), EventSeverity.Warning,
|
||||||
$"Exceeds VRAM threshold: automatically paused ({UiSharedService.ByteToString(vramUsage, addSuffix: true)}/{config.VRAMSizeAutoPauseThresholdMiB}MiB)")));
|
$"Exceeds VRAM threshold: automatically paused ({UiSharedService.ByteToString(vramUsage, addSuffix: true)}/{config.VRAMSizeAutoPauseThresholdMiB} MiB)")));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and fucking warnings
|
|
||||||
if (CheckForThreshold(config.WarnOnExceedingThresholds, config.VRAMSizeWarningThresholdMiB * 1024 * 1024,
|
|
||||||
vramUsage, config.WarnOnPreferredPermissionsExceedingThresholds, isPrefPerm))
|
|
||||||
{
|
|
||||||
_mediator.Publish(new NotificationMessage($"{pair.PlayerName} ({pair.UserData.AliasOrUID}) exceeds performance threshold",
|
|
||||||
$"Player {pair.PlayerName} exceeds your configured VRAM warning threshold (" +
|
|
||||||
$"{UiSharedService.ByteToString(vramUsage, true)}/{config.VRAMSizeWarningThresholdMiB}MiB).",
|
|
||||||
MareConfiguration.Models.NotificationType.Warning));
|
|
||||||
|
|
||||||
_mediator.Publish(new EventMessage(new Event(pair.PlayerName, pair.UserData, nameof(PlayerPerformanceService), EventSeverity.Warning,
|
|
||||||
$"Exceeds triangle threshold: ({UiSharedService.ByteToString(vramUsage, addSuffix: true)}/{config.VRAMSizeAutoPauseThresholdMiB}MiB)")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class PluginWarningNotificationService
|
|||||||
warning.ShownMoodlesWarning = true;
|
warning.ShownMoodlesWarning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changes.Contains(PlayerChanges.Moodles) && !warning.ShowPetNicknamesWarning && !_ipcManager.PetNames.APIAvailable)
|
if (changes.Contains(PlayerChanges.PetNames) && !warning.ShowPetNicknamesWarning && !_ipcManager.PetNames.APIAvailable)
|
||||||
{
|
{
|
||||||
missingPluginsForData.Add("PetNicknames");
|
missingPluginsForData.Add("PetNicknames");
|
||||||
warning.ShowPetNicknamesWarning = true;
|
warning.ShowPetNicknamesWarning = true;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using ImGuiNET;
|
|||||||
using MareSynchronos.API.Data.Extensions;
|
using MareSynchronos.API.Data.Extensions;
|
||||||
using MareSynchronos.API.Dto.Group;
|
using MareSynchronos.API.Dto.Group;
|
||||||
using MareSynchronos.API.Dto.User;
|
using MareSynchronos.API.Dto.User;
|
||||||
|
using MareSynchronos.MareConfiguration;
|
||||||
using MareSynchronos.PlayerData.Pairs;
|
using MareSynchronos.PlayerData.Pairs;
|
||||||
using MareSynchronos.Services.Mediator;
|
using MareSynchronos.Services.Mediator;
|
||||||
using MareSynchronos.Services.ServerConfiguration;
|
using MareSynchronos.Services.ServerConfiguration;
|
||||||
@@ -26,6 +27,7 @@ public class DrawUserPair
|
|||||||
private readonly SelectTagForPairUi _selectTagForPairUi;
|
private readonly SelectTagForPairUi _selectTagForPairUi;
|
||||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||||
private readonly UiSharedService _uiSharedService;
|
private readonly UiSharedService _uiSharedService;
|
||||||
|
private readonly PlayerPerformanceConfigService _performanceConfigService;
|
||||||
private float _menuWidth = -1;
|
private float _menuWidth = -1;
|
||||||
private bool _wasHovered = false;
|
private bool _wasHovered = false;
|
||||||
|
|
||||||
@@ -34,7 +36,7 @@ public class DrawUserPair
|
|||||||
ApiController apiController, IdDisplayHandler uIDDisplayHandler,
|
ApiController apiController, IdDisplayHandler uIDDisplayHandler,
|
||||||
MareMediator mareMediator, SelectTagForPairUi selectTagForPairUi,
|
MareMediator mareMediator, SelectTagForPairUi selectTagForPairUi,
|
||||||
ServerConfigurationManager serverConfigurationManager,
|
ServerConfigurationManager serverConfigurationManager,
|
||||||
UiSharedService uiSharedService)
|
UiSharedService uiSharedService, PlayerPerformanceConfigService performanceConfigService)
|
||||||
{
|
{
|
||||||
_id = id;
|
_id = id;
|
||||||
_pair = entry;
|
_pair = entry;
|
||||||
@@ -46,6 +48,7 @@ public class DrawUserPair
|
|||||||
_selectTagForPairUi = selectTagForPairUi;
|
_selectTagForPairUi = selectTagForPairUi;
|
||||||
_serverConfigurationManager = serverConfigurationManager;
|
_serverConfigurationManager = serverConfigurationManager;
|
||||||
_uiSharedService = uiSharedService;
|
_uiSharedService = uiSharedService;
|
||||||
|
_performanceConfigService = performanceConfigService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair Pair => _pair;
|
public Pair Pair => _pair;
|
||||||
@@ -235,11 +238,11 @@ public class DrawUserPair
|
|||||||
userPairText += "Files Size: " + UiSharedService.ByteToString(_pair.LastAppliedDataBytes, true);
|
userPairText += "Files Size: " + UiSharedService.ByteToString(_pair.LastAppliedDataBytes, true);
|
||||||
if (_pair.LastAppliedApproximateVRAMBytes >= 0)
|
if (_pair.LastAppliedApproximateVRAMBytes >= 0)
|
||||||
{
|
{
|
||||||
userPairText += Environment.NewLine + "Approximate max. VRAM Usage: " + UiSharedService.ByteToString(_pair.LastAppliedApproximateVRAMBytes, true);
|
userPairText += Environment.NewLine + "Approx. VRAM Usage: " + UiSharedService.ByteToString(_pair.LastAppliedApproximateVRAMBytes, true);
|
||||||
}
|
}
|
||||||
if (_pair.LastAppliedDataTris >= 0)
|
if (_pair.LastAppliedDataTris >= 0)
|
||||||
{
|
{
|
||||||
userPairText += Environment.NewLine + "Triangle Count (excl. Vanilla): "
|
userPairText += Environment.NewLine + "Approx. Triangle Count (excl. Vanilla): "
|
||||||
+ (_pair.LastAppliedDataTris > 1000 ? (_pair.LastAppliedDataTris / 1000d).ToString("0.0'k'") : _pair.LastAppliedDataTris);
|
+ (_pair.LastAppliedDataTris > 1000 ? (_pair.LastAppliedDataTris / 1000d).ToString("0.0'k'") : _pair.LastAppliedDataTris);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,6 +260,34 @@ public class DrawUserPair
|
|||||||
|
|
||||||
UiSharedService.AttachToolTip(userPairText);
|
UiSharedService.AttachToolTip(userPairText);
|
||||||
|
|
||||||
|
if (_performanceConfigService.Current.ShowPerformanceIndicator
|
||||||
|
&& !_performanceConfigService.Current.UIDsToIgnore
|
||||||
|
.Exists(uid => string.Equals(uid, UserPair.User.Alias, StringComparison.Ordinal) || string.Equals(uid, UserPair.User.UID, StringComparison.Ordinal))
|
||||||
|
&& (_performanceConfigService.Current.VRAMSizeWarningThresholdMiB * 1024 * 1024 < _pair.LastAppliedApproximateVRAMBytes
|
||||||
|
|| _performanceConfigService.Current.TrisWarningThresholdThousands * 1000 < _pair.LastAppliedDataTris)
|
||||||
|
&& (!_pair.UserPair.OwnPermissions.IsSticky()
|
||||||
|
|| _performanceConfigService.Current.WarnOnPreferredPermissionsExceedingThresholds))
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
_uiSharedService.IconText(FontAwesomeIcon.ExclamationTriangle, ImGuiColors.DalamudYellow);
|
||||||
|
|
||||||
|
string userWarningText = "WARNING: This user exceeds one or more of your defined thresholds:" + UiSharedService.TooltipSeparator;
|
||||||
|
bool shownVram = false;
|
||||||
|
if (_performanceConfigService.Current.VRAMSizeWarningThresholdMiB * 1024 * 1024 < _pair.LastAppliedApproximateVRAMBytes)
|
||||||
|
{
|
||||||
|
shownVram = true;
|
||||||
|
userWarningText += $"Approx. VRAM Usage: Used: {UiSharedService.ByteToString(_pair.LastAppliedApproximateVRAMBytes)}, Threshold: {_performanceConfigService.Current.VRAMSizeWarningThresholdMiB} MiB";
|
||||||
|
}
|
||||||
|
if (_performanceConfigService.Current.TrisWarningThresholdThousands * 1024 < _pair.LastAppliedDataTris)
|
||||||
|
{
|
||||||
|
if (shownVram) userWarningText += Environment.NewLine;
|
||||||
|
userWarningText += $"Approx. Triangle count: Used: {_pair.LastAppliedDataTris}, Threshold: {_performanceConfigService.Current.TrisWarningThresholdThousands * 1000}";
|
||||||
|
}
|
||||||
|
|
||||||
|
UiSharedService.AttachToolTip(userWarningText);
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using MareSynchronos.API.Dto.Group;
|
using MareSynchronos.API.Dto.Group;
|
||||||
|
using MareSynchronos.MareConfiguration;
|
||||||
using MareSynchronos.PlayerData.Pairs;
|
using MareSynchronos.PlayerData.Pairs;
|
||||||
using MareSynchronos.Services.Mediator;
|
using MareSynchronos.Services.Mediator;
|
||||||
using MareSynchronos.Services.ServerConfiguration;
|
using MareSynchronos.Services.ServerConfiguration;
|
||||||
@@ -18,6 +19,7 @@ public class DrawEntityFactory
|
|||||||
private readonly SelectPairForTagUi _selectPairForTagUi;
|
private readonly SelectPairForTagUi _selectPairForTagUi;
|
||||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||||
private readonly UiSharedService _uiSharedService;
|
private readonly UiSharedService _uiSharedService;
|
||||||
|
private readonly PlayerPerformanceConfigService _playerPerformanceConfigService;
|
||||||
private readonly SelectTagForPairUi _selectTagForPairUi;
|
private readonly SelectTagForPairUi _selectTagForPairUi;
|
||||||
private readonly TagHandler _tagHandler;
|
private readonly TagHandler _tagHandler;
|
||||||
private readonly IdDisplayHandler _uidDisplayHandler;
|
private readonly IdDisplayHandler _uidDisplayHandler;
|
||||||
@@ -25,7 +27,8 @@ public class DrawEntityFactory
|
|||||||
public DrawEntityFactory(ILogger<DrawEntityFactory> logger, ApiController apiController, IdDisplayHandler uidDisplayHandler,
|
public DrawEntityFactory(ILogger<DrawEntityFactory> logger, ApiController apiController, IdDisplayHandler uidDisplayHandler,
|
||||||
SelectTagForPairUi selectTagForPairUi, MareMediator mediator,
|
SelectTagForPairUi selectTagForPairUi, MareMediator mediator,
|
||||||
TagHandler tagHandler, SelectPairForTagUi selectPairForTagUi,
|
TagHandler tagHandler, SelectPairForTagUi selectPairForTagUi,
|
||||||
ServerConfigurationManager serverConfigurationManager, UiSharedService uiSharedService)
|
ServerConfigurationManager serverConfigurationManager, UiSharedService uiSharedService,
|
||||||
|
PlayerPerformanceConfigService playerPerformanceConfigService)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_apiController = apiController;
|
_apiController = apiController;
|
||||||
@@ -36,6 +39,7 @@ public class DrawEntityFactory
|
|||||||
_selectPairForTagUi = selectPairForTagUi;
|
_selectPairForTagUi = selectPairForTagUi;
|
||||||
_serverConfigurationManager = serverConfigurationManager;
|
_serverConfigurationManager = serverConfigurationManager;
|
||||||
_uiSharedService = uiSharedService;
|
_uiSharedService = uiSharedService;
|
||||||
|
_playerPerformanceConfigService = playerPerformanceConfigService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DrawFolderGroup CreateDrawGroupFolder(GroupFullInfoDto groupFullInfoDto,
|
public DrawFolderGroup CreateDrawGroupFolder(GroupFullInfoDto groupFullInfoDto,
|
||||||
@@ -58,6 +62,6 @@ public class DrawEntityFactory
|
|||||||
public DrawUserPair CreateDrawPair(string id, Pair user, List<GroupFullInfoDto> groups, GroupFullInfoDto? currentGroup)
|
public DrawUserPair CreateDrawPair(string id, Pair user, List<GroupFullInfoDto> groups, GroupFullInfoDto? currentGroup)
|
||||||
{
|
{
|
||||||
return new DrawUserPair(id + user.UserData.UID, user, groups, currentGroup, _apiController, _uidDisplayHandler,
|
return new DrawUserPair(id + user.UserData.UID, user, groups, currentGroup, _apiController, _uidDisplayHandler,
|
||||||
_mediator, _selectTagForPairUi, _serverConfigurationManager, _uiSharedService);
|
_mediator, _selectTagForPairUi, _serverConfigurationManager, _uiSharedService, _playerPerformanceConfigService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1400,7 +1400,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
_playerPerformanceConfigService.Save();
|
_playerPerformanceConfigService.Save();
|
||||||
}
|
}
|
||||||
_uiShared.DrawHelpText("Mare will print a warning in chat once per session of meeting those people. Will not warn on players with preferred permissions.");
|
_uiShared.DrawHelpText("Mare will print a warning in chat once per session of meeting those people. Will not warn on players with preferred permissions.");
|
||||||
using (ImRaii.Disabled(!warnOnExceedingThresholds))
|
using (ImRaii.Disabled(!warnOnExceedingThresholds && !showPerformanceIndicator))
|
||||||
{
|
{
|
||||||
using var indent = ImRaii.PushIndent();
|
using var indent = ImRaii.PushIndent();
|
||||||
var warnOnPref = _playerPerformanceConfigService.Current.WarnOnPreferredPermissionsExceedingThresholds;
|
var warnOnPref = _playerPerformanceConfigService.Current.WarnOnPreferredPermissionsExceedingThresholds;
|
||||||
@@ -1409,7 +1409,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
_playerPerformanceConfigService.Current.WarnOnPreferredPermissionsExceedingThresholds = warnOnPref;
|
_playerPerformanceConfigService.Current.WarnOnPreferredPermissionsExceedingThresholds = warnOnPref;
|
||||||
_playerPerformanceConfigService.Save();
|
_playerPerformanceConfigService.Save();
|
||||||
}
|
}
|
||||||
_uiShared.DrawHelpText("Mare will also print warnings for players where you enabled preferred permissions.");
|
_uiShared.DrawHelpText("Mare will also print warnings and show performance indicator for players where you enabled preferred permissions.");
|
||||||
}
|
}
|
||||||
using (ImRaii.Disabled(!showPerformanceIndicator && !warnOnExceedingThresholds))
|
using (ImRaii.Disabled(!showPerformanceIndicator && !warnOnExceedingThresholds))
|
||||||
{
|
{
|
||||||
@@ -1456,8 +1456,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
_playerPerformanceConfigService.Save();
|
_playerPerformanceConfigService.Save();
|
||||||
}
|
}
|
||||||
_uiShared.DrawHelpText("When enabled, will automatically pause all players regardless of preferred permissions that exceed thresholds defined below." + UiSharedService.TooltipSeparator +
|
_uiShared.DrawHelpText("When enabled, will automatically pause all players regardless of preferred permissions that exceed thresholds defined below." + UiSharedService.TooltipSeparator +
|
||||||
"Warning: this will not automatically unpause those people again, you will have to do this manually." + UiSharedService.TooltipSeparator
|
"Warning: this will not automatically unpause those people again, you will have to do this manually.");
|
||||||
+ "Default: 550 MiB");
|
|
||||||
var vramAuto = _playerPerformanceConfigService.Current.VRAMSizeAutoPauseThresholdMiB;
|
var vramAuto = _playerPerformanceConfigService.Current.VRAMSizeAutoPauseThresholdMiB;
|
||||||
var trisAuto = _playerPerformanceConfigService.Current.TrisAutoPauseThresholdThousands;
|
var trisAuto = _playerPerformanceConfigService.Current.TrisAutoPauseThresholdThousands;
|
||||||
ImGui.SetNextItemWidth(100);
|
ImGui.SetNextItemWidth(100);
|
||||||
@@ -1468,7 +1467,8 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.Text("(MiB)");
|
ImGui.Text("(MiB)");
|
||||||
_uiShared.DrawHelpText("When a loading in player and their VRAM usage exceeds this amount, automatically pauses the synced player.");
|
_uiShared.DrawHelpText("When a loading in player and their VRAM usage exceeds this amount, automatically pauses the synced player." + UiSharedService.TooltipSeparator
|
||||||
|
+ "Default: 550 MiB");
|
||||||
ImGui.SetNextItemWidth(100);
|
ImGui.SetNextItemWidth(100);
|
||||||
if (ImGui.InputInt("Auto Pause Triangle threshold", ref trisAuto))
|
if (ImGui.InputInt("Auto Pause Triangle threshold", ref trisAuto))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -190,6 +190,13 @@ public static class VariousExtensions
|
|||||||
logger.LogDebug("[BASE-{appBase}] Updating {object}/{kind} (Diff moodles data) => {change}", applicationBase, cachedPlayer, objectKind, PlayerChanges.Moodles);
|
logger.LogDebug("[BASE-{appBase}] Updating {object}/{kind} (Diff moodles data) => {change}", applicationBase, cachedPlayer, objectKind, PlayerChanges.Moodles);
|
||||||
charaDataToUpdate[objectKind].Add(PlayerChanges.Moodles);
|
charaDataToUpdate[objectKind].Add(PlayerChanges.Moodles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool petNamesDataDifferent = !string.Equals(oldData.PetNamesData, newData.PetNamesData, StringComparison.Ordinal);
|
||||||
|
if (petNamesDataDifferent || (forceApplyCustomization && !string.IsNullOrEmpty(newData.PetNamesData)))
|
||||||
|
{
|
||||||
|
logger.LogDebug("[BASE-{appBase}] Updating {object}/{kind} (Diff petnames data) => {change}", applicationBase, cachedPlayer, objectKind, PlayerChanges.PetNames);
|
||||||
|
charaDataToUpdate[objectKind].Add(PlayerChanges.PetNames);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (KeyValuePair<ObjectKind, HashSet<PlayerChanges>> data in charaDataToUpdate.ToList())
|
foreach (KeyValuePair<ObjectKind, HashSet<PlayerChanges>> data in charaDataToUpdate.ToList())
|
||||||
|
|||||||
Reference in New Issue
Block a user