-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Now possible to disable all other mods while activating the new…
… mod when installing a new mod (#116) refactor: Redid notifications and updated namespaces fix: Potential fix for deleting mods freezing the app tweaks: Bring main window to front after mod install
- Loading branch information
Showing
30 changed files
with
610 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,48 @@ | ||
namespace GIMI_ModManager.WinUI.Models; | ||
using CommunityToolkit.Mvvm.ComponentModel; | ||
using GIMI_ModManager.WinUI.Services.Notifications; | ||
using Microsoft.UI.Xaml; | ||
using Microsoft.UI.Xaml.Controls; | ||
|
||
public record Notification | ||
namespace GIMI_ModManager.WinUI.Models; | ||
|
||
public class Notification : ObservableObject | ||
{ | ||
public Notification(string title, string message) | ||
public Notification(string title, TimeSpan duration, string? subtitle = null, UIElement? content = null, | ||
FontIcon? icon = null, bool showNow = false, | ||
string? logMessage = null, NotificationType type = NotificationType.Information) | ||
{ | ||
Title = title; | ||
Message = message; | ||
Timestamp = DateTime.Now; | ||
Subtitle = subtitle; | ||
Content = content; | ||
Duration = duration; | ||
Icon = icon; | ||
ShowNow = showNow; | ||
LogMessage = logMessage; | ||
Type = type; | ||
} | ||
|
||
public Guid Id { get; } = Guid.NewGuid(); | ||
|
||
public DateTime QueueTime { get; } = DateTime.Now; | ||
|
||
public DateTime? ShowTime { get; set; } | ||
|
||
public string Title { get; } | ||
public string Message { get; } | ||
public DateTime Timestamp { get; } | ||
public string? Subtitle { get; } | ||
public UIElement? Content { get; } | ||
public TimeSpan Duration { get; } | ||
public FontIcon? Icon { get; } | ||
public bool ShowNow { get; } | ||
public string? LogMessage { get; set; } | ||
|
||
public NotificationType Type { get; } | ||
|
||
public bool IsLogged { get; set; } | ||
|
||
|
||
public override string ToString() | ||
{ | ||
return LogMessage ?? $"Title: {Title} | Subtitle: {Subtitle} | Duration: {Duration} | " + | ||
$"Icon: {Icon} | ShowNow: {ShowNow} | ShowTime: {ShowTime}"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
161 changes: 161 additions & 0 deletions
161
src/GIMI-ModManager.WinUI/Services/ModHandling/CharacterSkinService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
using System.Diagnostics; | ||
using GIMI_ModManager.Core.Contracts.Entities; | ||
using GIMI_ModManager.Core.Contracts.Services; | ||
using GIMI_ModManager.Core.GamesService; | ||
using GIMI_ModManager.Core.GamesService.Interfaces; | ||
using GIMI_ModManager.Core.Helpers; | ||
using GIMI_ModManager.Core.Services; | ||
using Serilog; | ||
|
||
namespace GIMI_ModManager.WinUI.Services.ModHandling; | ||
|
||
public class CharacterSkinService | ||
{ | ||
private readonly ILogger _logger; | ||
private readonly ModCrawlerService _modCrawlerService; | ||
private readonly ISkinManagerService _skinManagerService; | ||
private readonly IGameService _gameService; | ||
|
||
public CharacterSkinService(ModCrawlerService modCrawlerService, ISkinManagerService skinManagerService, | ||
ILogger logger, IGameService gameService) | ||
{ | ||
_modCrawlerService = modCrawlerService; | ||
_skinManagerService = skinManagerService; | ||
_gameService = gameService; | ||
_logger = logger.ForContext<CharacterSkinService>(); | ||
} | ||
|
||
private async IAsyncEnumerable<ISkinMod> FilterModsToSkin(ICharacterSkin skin, | ||
IEnumerable<ISkinMod> mods, bool ignoreUndetectableMods = false) | ||
{ | ||
foreach (var mod in mods) | ||
{ | ||
var modSettings = await mod.Settings.TryReadSettingsAsync(); | ||
|
||
if (modSettings is null) | ||
{ | ||
_logger.Warning("Could not read settings for mod {mod}", mod.Name); | ||
Debugger.Break(); | ||
|
||
if (ignoreUndetectableMods) | ||
continue; | ||
} | ||
|
||
|
||
var modSkin = modSettings?.CharacterSkinOverride; | ||
|
||
// Has skin override and is a match for the shown skin | ||
if (modSkin is not null && skin.InternalNameEquals(modSkin)) | ||
{ | ||
yield return mod; | ||
continue; | ||
} | ||
|
||
// Has override skin, but does not match any of the characters skins | ||
if (modSkin is not null && !skin.Character.Skins.Any(skinVm => | ||
skinVm.InternalNameEquals(modSkin))) | ||
{ | ||
// In this case, the override skin is not a valid skin for this character, so we just add it. | ||
yield return mod; | ||
continue; | ||
} | ||
|
||
|
||
var detectedSkin = | ||
_modCrawlerService.GetFirstSubSkinRecursive(mod.FullPath, skin.Character.InternalName); | ||
|
||
// If we can detect the skin, and the mod has no override skin, check if the detected skin matches the shown skin. | ||
if (modSkin is null && detectedSkin is not null && detectedSkin.InternalNameEquals(skin.InternalName)) | ||
{ | ||
yield return mod; | ||
continue; | ||
} | ||
|
||
// If we can't detect the skin, and the mod has no override skin. | ||
// We add it if the caller wants to see undetectable mods. | ||
if (detectedSkin is null && modSkin is null && !ignoreUndetectableMods) | ||
yield return mod; | ||
} | ||
} | ||
|
||
|
||
public async IAsyncEnumerable<ISkinMod> GetModsForSkinAsync(ICharacterSkin skin, | ||
bool ignoreUndetectableMods = false) | ||
{ | ||
var modList = _skinManagerService.GetCharacterModList(skin.Character); | ||
|
||
var mods = modList.Mods.Select(entry => entry.Mod).ToArray(); | ||
await foreach (var skinMod in FilterModsToSkin(skin, mods, ignoreUndetectableMods)) | ||
yield return skinMod; | ||
} | ||
|
||
|
||
public async Task<GetAllModsBySkinResult?> GetAllModsBySkin(ICharacter character) | ||
{ | ||
var modList = _skinManagerService.GetCharacterModListOrDefault(character.InternalName); | ||
if (modList is null) return null; | ||
|
||
var mods = modList.Mods.Select(entry => entry.Mod).ToArray(); | ||
|
||
var result = new Dictionary<ICharacterSkin, ISkinMod[]>(); | ||
foreach (var skin in character.Skins) | ||
{ | ||
var modsForSkin = new List<ISkinMod>(); | ||
await foreach (var skinMod in FilterModsToSkin(skin, mods)) | ||
{ | ||
modsForSkin.Add(skinMod); | ||
} | ||
|
||
result.Add(skin, modsForSkin.ToArray()); | ||
} | ||
|
||
var unknownMods = mods | ||
.Where(mod => !result.Values.SelectMany(detectedMods => detectedMods) | ||
.Contains(mod)) | ||
.ToArray(); | ||
|
||
return new GetAllModsBySkinResult(result, unknownMods); | ||
} | ||
|
||
|
||
public async Task<ICharacterSkin?> GetFirstSkinForMod(ISkinMod mod, ICharacter? character = null) | ||
{ | ||
var modSettings = await mod.Settings.TryReadSettingsAsync(); | ||
|
||
if (modSettings is null) | ||
{ | ||
_logger.Warning("Could not read settings for mod {mod}", mod.Name); | ||
Debugger.Break(); | ||
} | ||
|
||
var modSkin = modSettings?.CharacterSkinOverride; | ||
|
||
|
||
if (!modSkin.IsNullOrEmpty()) | ||
{ | ||
var foundSkin = character?.Skins.FirstOrDefault(skinVm => | ||
skinVm.InternalNameEquals(modSkin)); | ||
|
||
if (foundSkin != null) | ||
return foundSkin; | ||
|
||
|
||
var allSkins = _gameService.GetCharacters().SelectMany(characterVm => characterVm.Skins).ToArray(); | ||
|
||
var skin = allSkins.FirstOrDefault(skinVm => | ||
skinVm.InternalNameEquals(modSkin)); | ||
|
||
if (skin is not null) | ||
return skin; | ||
} | ||
|
||
var detectedSkin = | ||
_modCrawlerService.GetFirstSubSkinRecursive(mod.FullPath, character?.InternalName.Id); | ||
|
||
return detectedSkin; | ||
} | ||
|
||
public record GetAllModsBySkinResult( | ||
Dictionary<ICharacterSkin, ISkinMod[]> ModsBySkin, | ||
ISkinMod[] UndetectableMods); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.