Merge pull request #391 from 4sval/dev

Dev
This commit is contained in:
Valentin 2023-06-04 18:12:16 +02:00 committed by GitHub
commit 3f9b1197d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 121 additions and 121 deletions

@ -1 +1 @@
Subproject commit 2d5e2bdd35db42759d8320076778737fcf9d53a2
Subproject commit 2cdf9d61e66253f746f6a6e5b23b57979fbaab69

View File

@ -124,8 +124,7 @@ public class BaseBundle : UCreator
}
var shaper = new CustomSKShaper(_headerPaint.Typeface);
var shapedText = shaper.Shape(DisplayName, _headerPaint);
c.DrawShapedText(shaper, DisplayName, (Width - shapedText.Points[^1].X) / 2, _headerHeight / 2 + _headerPaint.TextSize / 2 - 10, _headerPaint);
c.DrawShapedText(shaper, DisplayName, Width / 2f, _headerHeight / 2f + _headerPaint.TextSize / 2 - 10, _headerPaint);
}
private void DrawQuests(SKCanvas c)
@ -137,4 +136,4 @@ public class BaseBundle : UCreator
y += quest.Height;
}
}
}
}

View File

@ -155,10 +155,9 @@ public class BaseCommunity : BaseIcon
}
var shaper = new CustomSKShaper(DisplayNamePaint.Typeface);
var shapedText = shaper.Shape(DisplayName, DisplayNamePaint);
var x = font.Alignment switch
{
SKTextAlign.Center => (Width - shapedText.Points[^1].X) / 2f,
SKTextAlign.Center => Width / 2f,
_ => font.X
};
@ -192,10 +191,9 @@ public class BaseCommunity : BaseIcon
}
var shaper = new CustomSKShaper(DescriptionPaint.Typeface);
var shapedText = shaper.Shape(Description, DescriptionPaint);
var x = font.Alignment switch
{
SKTextAlign.Center => (Width - shapedText.Points[^1].X) / 2f,
SKTextAlign.Center => Width / 2f,
_ => font.X
};
@ -236,11 +234,9 @@ public class BaseCommunity : BaseIcon
DisplayNamePaint.Typeface = Utils.Typefaces.OnTheFly(path);
var shaper = new CustomSKShaper(DisplayNamePaint.Typeface);
var shapedText = shaper.Shape(text, DisplayNamePaint);
var x = font.Alignment switch
{
SKTextAlign.Center => (Width - shapedText.Points[^1].X) / 2f,
SKTextAlign.Right => font.X - DisplayNamePaint.MeasureText(text),
SKTextAlign.Center => Width / 2f,
_ => font.X
};

View File

@ -217,8 +217,7 @@ public class BaseIconStats : BaseIcon
}
var shaper = new CustomSKShaper(_informationPaint.Typeface);
shaper.Shape(DisplayName, _informationPaint);
c.DrawShapedText(shaper, DisplayName, _headerHeight + _headerHeight / 3 + 10, _headerHeight / 2 + _informationPaint.TextSize / 3, _informationPaint);
c.DrawShapedText(shaper, DisplayName, _headerHeight + _headerHeight / 3 + 10, _headerHeight / 2f + _informationPaint.TextSize / 3, _informationPaint);
}
private void DrawStatistics(SKCanvas c)
@ -270,7 +269,6 @@ public class IconStat
}
var shaper = new CustomSKShaper(_statPaint.Typeface);
shaper.Shape(_statName, _statPaint);
c.DrawShapedText(shaper, _statName, 50, y + 10, _statPaint);
_statPaint.TextAlign = SKTextAlign.Right;

View File

@ -76,7 +76,7 @@ public class BaseItemAccessToken : UCreator
var shaper = new CustomSKShaper(DisplayNamePaint.Typeface);
var shapedText = shaper.Shape(DisplayName, DisplayNamePaint);
c.DrawShapedText(shaper, DisplayName, left - shapedText.Points[^1].X / 2, _icon.Margin * 8 + size, DisplayNamePaint);
c.DrawShapedText(shaper, DisplayName, left - shapedText.Width / 2, _icon.Margin * 8 + size, DisplayNamePaint);
float topBase = _icon.Margin + size * 2;
if (!string.IsNullOrEmpty(_unlockedDescription))
@ -96,4 +96,4 @@ public class BaseItemAccessToken : UCreator
var h = Width - _icon.Margin - topBase;
c.DrawBitmap(_icon.Preview ?? _icon.DefaultPreview, new SKRect(left - h / 2, topBase, left + h / 2, Width - _icon.Margin), ImagePaint);
}
}
}

View File

@ -233,7 +233,6 @@ public class BaseQuest : BaseIcon
}
var shaper = new CustomSKShaper(_informationPaint.Typeface);
shaper.Shape(DisplayName, _informationPaint);
c.DrawShapedText(shaper, DisplayName, Height, y + 50, _informationPaint);
}
@ -263,4 +262,4 @@ public class BaseQuest : BaseIcon
_reward.DrawQuest(c, new SKRect(Height, outY + 25, Width - 20, y + Height - 25));
}
}
}

View File

@ -136,8 +136,7 @@ public class BaseSeason : UCreator
}
var shaper = new CustomSKShaper(_headerPaint.Typeface);
var shapedText = shaper.Shape(DisplayName, _headerPaint);
c.DrawShapedText(shaper, DisplayName, (Width - shapedText.Points[^1].X) / 2, _headerHeight / 2 + _headerPaint.TextSize / 2 - 10, _headerPaint);
c.DrawShapedText(shaper, DisplayName, Width / 2f, _headerHeight / 2f + _headerPaint.TextSize / 2 - 10, _headerPaint);
}
private void DrawBookSchedule(SKCanvas c)
@ -156,4 +155,4 @@ public class BaseSeason : UCreator
x = 20;
}
}
}
}

View File

@ -146,7 +146,6 @@ public class BaseUserControl : UCreator
}
var shaper = new CustomSKShaper(_displayNamePaint.Typeface);
shaper.Shape(DisplayName, _displayNamePaint);
c.DrawShapedText(shaper, DisplayName, Margin, Margin + _displayNamePaint.TextSize, _displayNamePaint);
#if DEBUG
c.DrawRect(new SKRect(Margin, Margin, Width - Margin, Margin + _displayNamePaint.TextSize), new SKPaint { Color = SKColors.Blue, IsStroke = true });

View File

@ -75,7 +75,6 @@ public class Reward
}
var shaper = new CustomSKShaper(_rewardPaint.Typeface);
shaper.Shape(_rewardQuantity, _rewardPaint);
c.DrawShapedText(shaper, _rewardQuantity, rect.Left + rect.Height + 25, rect.MidY + 20, _rewardPaint);
}
else
@ -149,4 +148,4 @@ public class Reward
}
}
}
}
}

View File

@ -166,7 +166,7 @@ public abstract class UCreator
var shaper = new CustomSKShaper(DisplayNamePaint.Typeface);
var shapedText = shaper.Shape(DisplayName, DisplayNamePaint);
var x = (Width - shapedText.Points[^1].X) / 2;
var x = Width / 2f;
var y = _STARTER_TEXT_POSITION + _NAME_TEXT_SIZE;
switch (Style)
@ -174,14 +174,15 @@ public abstract class UCreator
case EIconStyle.Flat:
{
DisplayNamePaint.TextAlign = SKTextAlign.Right;
x = Width - Margin * 2 - shapedText.Points[^1].X;
x = Width - Margin * 2;
break;
}
}
#if DEBUG
c.DrawLine(x, 0, x, Width, new SKPaint { Color = SKColors.Blue, IsStroke = true });
c.DrawLine(x + shapedText.Points[^1].X, 0, x + shapedText.Points[^1].X, Width, new SKPaint { Color = SKColors.Blue, IsStroke = true });
var halfWidth = shapedText.Width / 2f;
c.DrawLine(x - halfWidth, 0, x - halfWidth, Width, new SKPaint { Color = SKColors.Blue, IsStroke = true });
c.DrawLine(x + halfWidth, 0, x + halfWidth, Width, new SKPaint { Color = SKColors.Blue, IsStroke = true });
c.DrawRect(new SKRect(Margin, _STARTER_TEXT_POSITION, Width - Margin, y), new SKPaint { Color = SKColors.Blue, IsStroke = true });
#endif
@ -216,8 +217,6 @@ public abstract class UCreator
case SKTextAlign.Left:
_shortDescriptionPaint.Typeface = Utils.Typefaces.Bottom ?? Utils.Typefaces.DisplayName;
var shaper = new CustomSKShaper(_shortDescriptionPaint.Typeface);
shaper.Shape(text, _shortDescriptionPaint);
c.DrawShapedText(shaper, text, Margin * 2.5f, Width - Margin * 2.5f, _shortDescriptionPaint);
break;
case SKTextAlign.Right:

View File

@ -204,9 +204,6 @@ public static class Utils
return string.Empty;
}
public static string FixPath(string weirdPath) =>
_applicationView.CUE4Parse.Provider.FixPath(weirdPath, StringComparison.Ordinal);
public static void DrawCenteredMultilineText(SKCanvas c, string text, int maxCount, int size, int margin, SKTextAlign side, SKRect area, SKPaint paint)
{
var lineHeight = paint.TextSize * 1.2f;
@ -233,8 +230,8 @@ public static class Utils
y += lineHeight;
var x = side switch
{
SKTextAlign.Center => area.MidX - shapedText.Points[^1].X / 2,
SKTextAlign.Right => size - margin - shapedText.Points[^1].X,
SKTextAlign.Center => area.MidX - shapedText.Width / 2,
SKTextAlign.Right => size - margin - shapedText.Width,
SKTextAlign.Left => margin,
_ => throw new NotImplementedException()
};
@ -266,8 +263,8 @@ public static class Utils
var x = side switch
{
SKTextAlign.Center => area.MidX - shapedText.Points[^1].X / 2,
SKTextAlign.Right => size - margin - shapedText.Points[^1].X,
SKTextAlign.Center => area.MidX - shapedText.Width / 2,
SKTextAlign.Right => size - margin - shapedText.Width,
SKTextAlign.Left => area.Left,
_ => throw new NotImplementedException()
};

View File

@ -5,9 +5,9 @@
<TargetFramework>net6.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<ApplicationIcon>FModel.ico</ApplicationIcon>
<Version>4.4.3.0</Version>
<AssemblyVersion>4.4.3.0</AssemblyVersion>
<FileVersion>4.4.3.0</FileVersion>
<Version>4.4.3.1</Version>
<AssemblyVersion>4.4.3.1</AssemblyVersion>
<FileVersion>4.4.3.1</FileVersion>
<IsPackable>false</IsPackable>
<IsPublishable>true</IsPublishable>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
@ -135,22 +135,22 @@
<ItemGroup>
<PackageReference Include="AdonisUI" Version="1.17.1" />
<PackageReference Include="AdonisUI.ClassicTheme" Version="1.17.1" />
<PackageReference Include="Autoupdater.NET.Official" Version="1.7.6" />
<PackageReference Include="AvalonEdit" Version="6.2.0.78" />
<PackageReference Include="Autoupdater.NET.Official" Version="1.8.2" />
<PackageReference Include="AvalonEdit" Version="6.3.0.90" />
<PackageReference Include="CSCore" Version="1.2.1.2" />
<PackageReference Include="DiscordRichPresence" Version="1.1.3.18" />
<PackageReference Include="ImGui.NET" Version="1.89.4" />
<PackageReference Include="ImGui.NET" Version="1.89.5" />
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.3.5" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NVorbis" Version="0.10.5" />
<PackageReference Include="Oodle.NET" Version="1.0.1" />
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
<PackageReference Include="OpenTK" Version="4.7.7" />
<PackageReference Include="RestSharp" Version="108.0.3" />
<PackageReference Include="RestSharp" Version="110.2.0" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
<PackageReference Include="SkiaSharp.HarfBuzz" Version="2.88.0" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" />
<PackageReference Include="SkiaSharp.HarfBuzz" Version="2.88.3" />
<PackageReference Include="SkiaSharp.Svg" Version="1.60.0" />
</ItemGroup>

View File

@ -58,7 +58,7 @@ public class CustomSKShaper : SKShaper
points[i] = new SKPoint(xOffset + pos[i].XOffset * textSizeX, yOffset - pos[i].YOffset * textSizeY);
}
return new Result(codepoints, clusters, points);
return new Result(codepoints, clusters, points, points[^1].X);
}
public new Result Shape(string text, SKPaint paint) => Shape(text, 0, 0, paint);
@ -87,4 +87,4 @@ public class CustomSKShaper : SKShaper
buffer.GuessSegmentProperties();
return Shape(buffer, xOffset, yOffset, paint);
}
}
}

View File

@ -22,9 +22,9 @@ public class JsonNetSerializer : IRestSerializer, ISerializer, IDeserializer
public ISerializer Serializer => this;
public IDeserializer Deserializer => this;
public string ContentType { get; set; } = "application/json";
public string[] AcceptedContentTypes => RestSharp.Serializers.ContentType.JsonAccept;
public SupportsContentType SupportsContentType => contentType => contentType.EndsWith("json", StringComparison.InvariantCultureIgnoreCase);
public ContentType ContentType { get; set; } = ContentType.Json;
public string[] AcceptedContentTypes => ContentType.JsonAccept;
public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase);
public DataFormat DataFormat => DataFormat.Json;
}

View File

@ -9,14 +9,11 @@ namespace FModel.ViewModels;
public class ApiEndpointViewModel
{
private readonly RestClient _client = new RestClient
private readonly RestClient _client = new (new RestClientOptions
{
Options =
{
UserAgent = $"FModel/{Constants.APP_VERSION}",
MaxTimeout = 3 * 1000
}
}.UseSerializer<JsonNetSerializer>();
UserAgent = $"FModel/{Constants.APP_VERSION}",
MaxTimeout = 3 * 1000
}, configureSerialization: s => s.UseSerializer<JsonNetSerializer>());
public FortniteApiEndpoint FortniteApi { get; }
public ValorantApiEndpoint ValorantApi { get; }

View File

@ -32,6 +32,7 @@ using CUE4Parse.UE4.Wwise;
using CUE4Parse_Conversion;
using CUE4Parse_Conversion.Sounds;
using CUE4Parse.FileProvider.Objects;
using CUE4Parse.UE4.Objects.Core.Serialization;
using EpicManifestParser.Objects;
using FModel.Creator;
using FModel.Extensions;
@ -132,7 +133,7 @@ public class CUE4ParseViewModel : ViewModel
Provider = new StreamedFileProvider("FortniteLive", true,
new VersionContainer(
UserSettings.Default.OverridedGame[Game], UserSettings.Default.OverridedPlatform,
customVersions: UserSettings.Default.OverridedCustomVersions[Game],
customVersions: new FCustomVersionContainer(UserSettings.Default.OverridedCustomVersions[Game]),
optionOverrides: UserSettings.Default.OverridedOptions[Game]));
break;
}
@ -142,7 +143,7 @@ public class CUE4ParseViewModel : ViewModel
Provider = new StreamedFileProvider("ValorantLive", true,
new VersionContainer(
UserSettings.Default.OverridedGame[Game], UserSettings.Default.OverridedPlatform,
customVersions: UserSettings.Default.OverridedCustomVersions[Game],
customVersions: new FCustomVersionContainer(UserSettings.Default.OverridedCustomVersions[Game]),
optionOverrides: UserSettings.Default.OverridedOptions[Game]));
break;
}
@ -152,7 +153,7 @@ public class CUE4ParseViewModel : ViewModel
if (gameDirectory.Contains("eFootball")) parent = gameDirectory.SubstringBeforeLast("\\pak").SubstringAfterLast("\\");
Game = parent.ToEnum(FGame.Unknown);
var versions = new VersionContainer(UserSettings.Default.OverridedGame[Game], UserSettings.Default.OverridedPlatform,
customVersions: UserSettings.Default.OverridedCustomVersions[Game],
customVersions: new FCustomVersionContainer(UserSettings.Default.OverridedCustomVersions[Game]),
optionOverrides: UserSettings.Default.OverridedOptions[Game],
mapStructTypesOverrides: UserSettings.Default.OverridedMapStructTypes[Game]);
@ -185,7 +186,7 @@ public class CUE4ParseViewModel : ViewModel
case FGame.Unknown when UserSettings.Default.ManualGames.TryGetValue(gameDirectory, out var settings):
{
versions = new VersionContainer(settings.OverridedGame, UserSettings.Default.OverridedPlatform,
customVersions: settings.OverridedCustomVersions,
customVersions: new FCustomVersionContainer(settings.OverridedCustomVersions),
optionOverrides: settings.OverridedOptions,
mapStructTypesOverrides: settings.OverridedMapStructTypes);
goto default;
@ -549,6 +550,7 @@ public class CUE4ParseViewModel : ViewModel
{
FLogger.Append(ELog.Information, () =>
FLogger.Text($"{LocalizedResourcesCount} localized resources loaded for '{UserSettings.Default.AssetLanguage.GetDescription()}'", Constants.WHITE, true));
Utils.Typefaces = new Typefaces(this);
}
}
private Task LoadGameLocalizedResources()
@ -607,7 +609,7 @@ public class CUE4ParseViewModel : ViewModel
{
foreach (var asset in assetItems)
{
Thread.Yield();
Thread.Sleep(10);
cancellationToken.ThrowIfCancellationRequested();
Extract(cancellationToken, asset.FullPath, TabControl.HasNoTabs);
}
@ -617,7 +619,7 @@ public class CUE4ParseViewModel : ViewModel
{
foreach (var asset in folder.AssetsList.Assets)
{
Thread.Yield();
Thread.Sleep(10);
cancellationToken.ThrowIfCancellationRequested();
try
{

View File

@ -56,7 +56,6 @@ public class LoadCommand : ViewModelCommand<LoadingModesViewModel>
await Task.WhenAll(
_applicationView.CUE4Parse.LoadLocalizedResources(), // load locres if not already loaded,
_applicationView.CUE4Parse.LoadVirtualPaths(), // load virtual paths if not already loaded
Task.Run(() => Utils.Typefaces = new Typefaces(_applicationView.CUE4Parse)),
_threadWorkerView.Begin(cancellationToken =>
{
// filter what to show

View File

@ -111,7 +111,7 @@ public class MenuCommand : ViewModelCommand<ApplicationViewModel>
if (!expand && folder.IsExpanded)
{
folder.IsExpanded = false;
Thread.Yield();
Thread.Sleep(10);
cancellationToken.ThrowIfCancellationRequested();
}
@ -129,7 +129,7 @@ public class MenuCommand : ViewModelCommand<ApplicationViewModel>
for (var node = nodes.Last; node != null; node = node.Previous)
{
node.Value.IsExpanded = true;
Thread.Yield();
Thread.Sleep(10);
cancellationToken.ThrowIfCancellationRequested();
}
}

View File

@ -29,7 +29,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Extract_New_Tab":
foreach (var asset in assetItems)
{
Thread.Yield();
Thread.Sleep(10);
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, true);
}
@ -37,7 +37,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Export_Data":
foreach (var asset in assetItems)
{
Thread.Yield();
Thread.Sleep(10);
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.ExportData(asset.FullPath);
}
@ -45,7 +45,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Save_Properties":
foreach (var asset in assetItems)
{
Thread.Yield();
Thread.Sleep(10);
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Properties);
}
@ -53,7 +53,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Save_Textures":
foreach (var asset in assetItems)
{
Thread.Yield();
Thread.Sleep(10);
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Textures);
}
@ -61,7 +61,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Save_Models":
foreach (var asset in assetItems)
{
Thread.Yield();
Thread.Sleep(10);
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Meshes | EBulkType.Auto);
}
@ -69,7 +69,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Save_Animations":
foreach (var asset in assetItems)
{
Thread.Yield();
Thread.Sleep(10);
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Animations | EBulkType.Auto);
}

View File

@ -99,20 +99,20 @@ public class GameSelectorViewModel : ViewModel
private IEnumerable<DetectedGame> EnumerateDetectedGames()
{
yield return GetUnrealEngineGame("Fortnite");
yield return GetUnrealEngineGame("Fortnite", "\\FortniteGame\\Content\\Paks");
yield return new DetectedGame { GameName = "Fortnite [LIVE]", GameDirectory = Constants._FN_LIVE_TRIGGER };
yield return GetUnrealEngineGame("Pewee");
yield return GetUnrealEngineGame("Rosemallow");
yield return GetUnrealEngineGame("Catnip");
yield return GetUnrealEngineGame("AzaleaAlpha");
yield return GetUnrealEngineGame("WorldExplorersLive");
yield return GetUnrealEngineGame("Newt");
yield return GetUnrealEngineGame("shoebill");
yield return GetUnrealEngineGame("Snoek");
yield return GetUnrealEngineGame("a99769d95d8f400baad1f67ab5dfe508");
yield return GetUnrealEngineGame("Nebula");
yield return GetUnrealEngineGame("711c5e95dc094ca58e5f16bd48e751d6");
yield return GetUnrealEngineGame("9361c8c6d2f34b42b5f2f61093eedf48");
yield return GetUnrealEngineGame("Pewee", "\\RogueCompany\\Content\\Paks");
yield return GetUnrealEngineGame("Rosemallow", "\\Indiana\\Content\\Paks");
yield return GetUnrealEngineGame("Catnip", "\\OakGame\\Content\\Paks");
yield return GetUnrealEngineGame("AzaleaAlpha", "\\Prospect\\Content\\Paks");
yield return GetUnrealEngineGame("WorldExplorersLive", "\\WorldExplorers\\Content\\Paks");
yield return GetUnrealEngineGame("Newt", "\\g3\\Content\\Paks");
yield return GetUnrealEngineGame("shoebill", "\\SwGame\\Content\\Paks");
yield return GetUnrealEngineGame("Snoek", "\\StateOfDecay2\\Content\\Paks");
yield return GetUnrealEngineGame("a99769d95d8f400baad1f67ab5dfe508", "\\Core\\Platform\\Content\\Paks");
yield return GetUnrealEngineGame("Nebula", "\\BendGame\\Content");
yield return GetUnrealEngineGame("711c5e95dc094ca58e5f16bd48e751d6", "\\MultiVersus\\Content\\Paks");
yield return GetUnrealEngineGame("9361c8c6d2f34b42b5f2f61093eedf48", "\\TslGame\\Content\\Paks");
yield return GetRiotGame("VALORANT", "ShooterGame\\Content\\Paks");
yield return new DetectedGame { GameName = "Valorant [LIVE]", GameDirectory = Constants._VAL_LIVE_TRIGGER };
yield return GetMojangGame("MinecraftDungeons", "\\dungeons\\dungeons\\Dungeons\\Content\\Paks");
@ -129,22 +129,22 @@ public class GameSelectorViewModel : ViewModel
}
private LauncherInstalled _launcherInstalled;
private DetectedGame GetUnrealEngineGame(string gameName)
private DetectedGame GetUnrealEngineGame(string gameName, string pakDirectory)
{
_launcherInstalled ??= GetDriveLauncherInstalls<LauncherInstalled>("ProgramData\\Epic\\UnrealEngineLauncher\\LauncherInstalled.dat");
if (_launcherInstalled?.InstallationList != null)
{
foreach (var installationList in _launcherInstalled.InstallationList)
{
if (installationList.AppName.Equals(gameName, StringComparison.OrdinalIgnoreCase))
var gameDir = $"{installationList.InstallLocation}{pakDirectory}";
if (installationList.AppName.Equals(gameName, StringComparison.OrdinalIgnoreCase) && Directory.Exists(gameDir))
{
var pak = Directory.GetDirectories(installationList.InstallLocation, "Paks*", SearchOption.AllDirectories);
if (pak.Length > 0) return new DetectedGame { GameName = installationList.AppName, GameDirectory = pak[0] };
Log.Debug("Found {GameName} in LauncherInstalled.dat", gameName);
return new DetectedGame { GameName = installationList.AppName, GameDirectory = gameDir };
}
}
}
Log.Warning("Could not find {GameName} in LauncherInstalled.dat", gameName);
return null;
}
@ -156,12 +156,15 @@ public class GameSelectorViewModel : ViewModel
{
foreach (var (key, _) in _riotClientInstalls.AssociatedClient)
{
if (key.Contains(gameName, StringComparison.OrdinalIgnoreCase))
return new DetectedGame { GameName = gameName, GameDirectory = $"{key.Replace('/', '\\')}{pakDirectory}" };
var gameDir = $"{key.Replace('/', '\\')}{pakDirectory}";
if (key.Contains(gameName, StringComparison.OrdinalIgnoreCase) && Directory.Exists(gameDir))
{
Log.Debug("Found {GameName} in RiotClientInstalls.json", gameName);
return new DetectedGame { GameName = gameName, GameDirectory = gameDir };
}
}
}
Log.Warning("Could not find {GameName} in RiotClientInstalls.json", gameName);
return null;
}
@ -170,9 +173,15 @@ public class GameSelectorViewModel : ViewModel
{
_launcherSettings ??= GetDataLauncherInstalls<LauncherSettings>("\\.minecraft\\launcher_settings.json");
if (_launcherSettings is { ProductLibraryDir: { } })
return new DetectedGame { GameName = gameName, GameDirectory = $"{_launcherSettings.ProductLibraryDir}{pakDirectory}" };
{
var gameDir = $"{_launcherSettings.ProductLibraryDir}{pakDirectory}";
if (Directory.Exists(gameDir))
{
Log.Debug("Found {GameName} in launcher_settings.json", gameName);
return new DetectedGame { GameName = gameName, GameDirectory = gameDir };
}
}
Log.Warning("Could not find {GameName} in launcher_settings.json", gameName);
return null;
}
@ -180,9 +189,11 @@ public class GameSelectorViewModel : ViewModel
{
var steamInfo = SteamDetection.GetSteamGameById(id);
if (steamInfo is not null)
{
Log.Debug("Found {GameName} in steam manifests", steamInfo.Name);
return new DetectedGame { GameName = steamInfo.Name, GameDirectory = $"{steamInfo.GameRoot}{pakDirectory}" };
}
Log.Warning("Could not find {GameId} in steam manifests", id);
return null;
}
@ -198,10 +209,13 @@ public class GameSelectorViewModel : ViewModel
// ignored
}
if (!string.IsNullOrEmpty(installLocation))
return new DetectedGame { GameName = key, GameDirectory = $"{installLocation}{pakDirectory}" };
var gameDir = $"{installLocation}{pakDirectory}";
if (Directory.Exists(gameDir))
{
Log.Debug("Found {GameName} in the registry", key);
return new DetectedGame { GameName = key, GameDirectory = gameDir };
}
Log.Warning("Could not find {GameName} in the registry", key);
return null;
}
@ -220,10 +234,13 @@ public class GameSelectorViewModel : ViewModel
// ignored
}
if (!string.IsNullOrEmpty(installLocation))
return new DetectedGame { GameName = displayName, GameDirectory = $"{installLocation}{pakDirectory}" };
var gameDir = $"{installLocation}{pakDirectory}";
if (Directory.Exists(gameDir))
{
Log.Debug("Found {GameName} in the registry", key);
return new DetectedGame { GameName = displayName, GameDirectory = gameDir };
}
Log.Warning("Could not find {GameName} in the registry", key);
return null;
}
@ -234,11 +251,10 @@ public class GameSelectorViewModel : ViewModel
var launcher = $"{drive.Name}{jsonFile}";
if (!File.Exists(launcher)) continue;
Log.Information("\"{Launcher}\" found in drive \"{DriveName}\"", launcher, drive.Name);
Log.Debug("\"{Launcher}\" found in drive \"{DriveName}\"", launcher, drive.Name);
return JsonConvert.DeserializeObject<T>(File.ReadAllText(launcher));
}
Log.Warning("\"{JsonFile}\" not found in any drives", jsonFile);
return default;
}
@ -248,11 +264,10 @@ public class GameSelectorViewModel : ViewModel
var launcher = $"{appData}{jsonFile}";
if (File.Exists(launcher))
{
Log.Information("\"{Launcher}\" found in \"{AppData}\"", launcher, appData);
Log.Debug("\"{Launcher}\" found in \"{AppData}\"", launcher, appData);
return JsonConvert.DeserializeObject<T>(File.ReadAllText(launcher));
}
Log.Warning("\"{Json}\" not found anywhere", jsonFile);
return default;
}
@ -321,7 +336,10 @@ public class GameSelectorViewModel : ViewModel
private static List<AppInfo> GetSteamApps(IEnumerable<string> steamLibs)
{
var apps = new List<AppInfo>();
foreach (var files in steamLibs.Select(lib => Path.Combine(lib, "SteamApps")).Select(appMetaDataPath => Directory.GetFiles(appMetaDataPath, "*.acf")))
foreach (var files in steamLibs
.Select(lib => Path.Combine(lib, "SteamApps"))
.Select(appMetaDataPath => Directory.Exists(appMetaDataPath) ? Directory.GetFiles(appMetaDataPath, "*.acf") : null)
.Where(files => files != null))
{
apps.AddRange(files.Select(GetAppInfo).Where(appInfo => appInfo != null));
}
@ -346,16 +364,16 @@ public class GameSelectorViewModel : ViewModel
!dic.TryGetValue("name", out var name) ||
!dic.TryGetValue("installDir", out var installDir)) return null;
var path = Path.GetDirectoryName(appMetaFile);
var path = Path.GetDirectoryName(appMetaFile) ?? "";
var libGameRoot = Path.Combine(path, "common", installDir);
return !Directory.Exists(libGameRoot) ? null : new AppInfo { Id = appId, Name = name, GameRoot = libGameRoot };
return Directory.Exists(libGameRoot) ? new AppInfo { Id = appId, Name = name, GameRoot = libGameRoot } : null;
}
private static List<string> GetSteamLibs()
{
var steamPath = GetSteamPath();
if (steamPath == null) return new List<string>();
if (steamPath == null || !Directory.Exists(steamPath)) return new List<string>();
var libraries = new List<string> { steamPath };
var listFile = Path.Combine(steamPath, @"steamapps\libraryfolders.vdf");
@ -366,7 +384,7 @@ public class GameSelectorViewModel : ViewModel
var match = Regex.Match(line, @"""(?<path>\w:\\\\.*)""");
if (!match.Success) continue;
var path = match.Groups["path"].Value.Replace(@"\\", @"\");
if (Directory.Exists(path))
if (Directory.Exists(path) && !libraries.Contains(path))
{
libraries.Add(path);
}

View File

@ -430,30 +430,28 @@ public class MapViewerViewModel : ViewModel
!poiData.TryGetValue(out FName discoverBackend, "DiscoverObjectiveBackendName")) continue;
var shaper = new CustomSKShaper(_textPaint.Typeface);
var shapedText = shaper.Shape(text.Text, _textPaint);
if (discoverBackend.Text.Contains("papaya", StringComparison.OrdinalIgnoreCase))
{
_fillPaint.StrokeWidth = 5;
var vector = GetMapPosition(worldLocation, _prRadius);
prLandmarks.DrawPoint(vector.X, vector.Y, _pathPaint);
prLandmarks.DrawShapedText(shaper, text.Text, vector.X - shapedText.Points[^1].X / 2, vector.Y - 12.5F, _fillPaint);
prLandmarks.DrawShapedText(shaper, text.Text, vector.X - shapedText.Points[^1].X / 2, vector.Y - 12.5F, _textPaint);
prLandmarks.DrawShapedText(shaper, text.Text, vector.X, vector.Y - 12.5F, _fillPaint);
prLandmarks.DrawShapedText(shaper, text.Text, vector.X, vector.Y - 12.5F, _textPaint);
}
else if (discoveryQuest.AssetPathName.Text.Contains("landmarks", StringComparison.OrdinalIgnoreCase))
{
_fillPaint.StrokeWidth = 5;
var vector = GetMapPosition(worldLocation, _brRadius);
brLandmarks.DrawPoint(vector.X, vector.Y, _pathPaint);
brLandmarks.DrawShapedText(shaper, text.Text, vector.X - shapedText.Points[^1].X / 2, vector.Y - 12.5F, _fillPaint);
brLandmarks.DrawShapedText(shaper, text.Text, vector.X - shapedText.Points[^1].X / 2, vector.Y - 12.5F, _textPaint);
brLandmarks.DrawShapedText(shaper, text.Text, vector.X, vector.Y - 12.5F, _fillPaint);
brLandmarks.DrawShapedText(shaper, text.Text, vector.X, vector.Y - 12.5F, _textPaint);
}
else
{
_fillPaint.StrokeWidth = 10;
var vector = GetMapPosition(worldLocation, _brRadius);
pois.DrawShapedText(shaper, text.Text.ToUpperInvariant(), vector.X - shapedText.Points[^1].X / 2, vector.Y, _fillPaint);
pois.DrawShapedText(shaper, text.Text.ToUpperInvariant(), vector.X - shapedText.Points[^1].X / 2, vector.Y, _textPaint);
pois.DrawShapedText(shaper, text.Text.ToUpperInvariant(), vector.X, vector.Y, _fillPaint);
pois.DrawShapedText(shaper, text.Text.ToUpperInvariant(), vector.X, vector.Y, _textPaint);
}
}
}

View File

@ -50,6 +50,7 @@ public static class TextureHelper
// G: Metallic
// B: Whatever (AO / S / E / ...)
case "CCFF7R":
case "PJ033":
{
texture.SwizzleMask = new []
{