now it works
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
namespace Mlaumcherb.Client.Avalonia.классы;
|
||||
|
||||
public class ArgumentsWithPlaceholders
|
||||
{
|
||||
protected List<string> _raw_args = new();
|
||||
|
||||
public IEnumerable<string> FillPlaceholders(Dictionary<string, string> values)
|
||||
{
|
||||
foreach (var _s in _raw_args)
|
||||
{
|
||||
string arg = _s;
|
||||
int begin = arg.IndexOf("${", StringComparison.Ordinal);
|
||||
while(begin != -1)
|
||||
{
|
||||
int keyBegin = begin + 2;
|
||||
int end = arg.IndexOf('}', keyBegin);
|
||||
if (end != -1)
|
||||
{
|
||||
var key = arg.Substring(keyBegin, end - keyBegin);
|
||||
if (!values.TryGetValue(key, out var value))
|
||||
throw new Exception($"can't find value for placeholder '{key}'");
|
||||
arg = arg.Replace("${"+ key + "}", value);
|
||||
}
|
||||
if(end + 1 < arg.Length)
|
||||
begin = arg.IndexOf("${", end + 1, StringComparison.Ordinal);
|
||||
else break;
|
||||
}
|
||||
yield return arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using DTLib.Extensions;
|
||||
|
||||
namespace Mlaumcherb.Client.Avalonia.классы;
|
||||
|
||||
public class GameArguments : ArgumentsWithPlaceholders
|
||||
{
|
||||
private static readonly string[] _initial_arguments =
|
||||
[
|
||||
"--width", "${resolution_width}",
|
||||
"--height", "${resolution_height}",
|
||||
];
|
||||
|
||||
private static readonly string[] _enabled_features =
|
||||
[
|
||||
];
|
||||
|
||||
public GameArguments(GameVersionDescriptor d)
|
||||
{
|
||||
_raw_args.AddRange(_initial_arguments);
|
||||
|
||||
if (d.minecraftArguments is not null)
|
||||
{
|
||||
_raw_args.AddRange(d.minecraftArguments.SplitToList(' ', quot: '"'));
|
||||
}
|
||||
else if (d.arguments is not null)
|
||||
{
|
||||
foreach (var av in d.arguments.game)
|
||||
{
|
||||
if(Rules.Check(av.rules, _enabled_features))
|
||||
{
|
||||
foreach (var arg in av.value)
|
||||
{
|
||||
if(!_raw_args.Contains(arg))
|
||||
_raw_args.Add(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else throw new Exception("no game arguments specified in descriptor");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Mlaumcherb.Client.Avalonia.холопы;
|
||||
|
||||
namespace Mlaumcherb.Client.Avalonia.классы;
|
||||
|
||||
public class GameVersionProps : IComparable<GameVersionProps>, IEquatable<GameVersionProps>
|
||||
{
|
||||
public string Name { get; }
|
||||
public IOPath LocalDescriptorPath { get; }
|
||||
public string? RemoteDescriptorUrl { get; }
|
||||
private bool _isDownloaded;
|
||||
public bool IsDownloaded
|
||||
{
|
||||
get => _isDownloaded;
|
||||
set
|
||||
{
|
||||
bool downloadCompleted = value && !_isDownloaded;
|
||||
_isDownloaded = value;
|
||||
if(downloadCompleted)
|
||||
OnDownloadCompleted?.Invoke();
|
||||
}
|
||||
}
|
||||
public event Action? OnDownloadCompleted;
|
||||
|
||||
public GameVersionProps(string name, string? url)
|
||||
{
|
||||
Name = name;
|
||||
LocalDescriptorPath = PathHelper.GetVersionDescriptorPath(name);
|
||||
RemoteDescriptorUrl = url;
|
||||
IsDownloaded = File.Exists(PathHelper.GetVersionJarFilePath(name));
|
||||
}
|
||||
|
||||
public override string ToString() => Name;
|
||||
|
||||
public override int GetHashCode() => Name.GetHashCode();
|
||||
|
||||
public int CompareTo(GameVersionProps? other)
|
||||
{
|
||||
if (ReferenceEquals(this, other)) return 0;
|
||||
if (other is null) return 1;
|
||||
|
||||
if (Version.TryParse(Name, out var version1) && Version.TryParse(other.Name, out var version2))
|
||||
{
|
||||
return version1.CompareTo(version2);
|
||||
}
|
||||
|
||||
return String.Compare(Name, other.Name, StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
public bool Equals(GameVersionProps? other)
|
||||
{
|
||||
if (other is null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return Name == other.Name;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is GameVersionProps other) return Equals(other);
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
namespace Mlaumcherb.Client.Avalonia.классы;
|
||||
|
||||
public class JavaArguments : ArgumentsWithPlaceholders
|
||||
{
|
||||
private static readonly string[] _initial_arguments =
|
||||
[
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseG1GC",
|
||||
"-XX:G1NewSizePercent=20",
|
||||
"-XX:G1ReservePercent=20",
|
||||
"-XX:MaxGCPauseMillis=50",
|
||||
"-XX:G1HeapRegionSize=32M",
|
||||
"-XX:+DisableExplicitGC",
|
||||
"-XX:+AlwaysPreTouch",
|
||||
"-XX:+ParallelRefProcEnabled",
|
||||
"-Xms${xms}M",
|
||||
"-Xmx${xmx}M",
|
||||
"-Dfile.encoding=UTF-8",
|
||||
"-Dlog4j.configurationFile=${path}",
|
||||
"-Djava.library.path=${natives_directory}",
|
||||
"-Dminecraft.client.jar=${client_jar}",
|
||||
"-Dminecraft.launcher.brand=${launcher_name}",
|
||||
"-Dminecraft.launcher.version=${launcher_version}",
|
||||
"-cp", "${classpath}"
|
||||
];
|
||||
|
||||
private static readonly string[] _enabled_features =
|
||||
[
|
||||
];
|
||||
|
||||
public JavaArguments(GameVersionDescriptor d)
|
||||
{
|
||||
_raw_args.AddRange(_initial_arguments);
|
||||
if (d.arguments is not null)
|
||||
{
|
||||
foreach (var av in d.arguments.jvm)
|
||||
{
|
||||
if (Rules.Check(av.rules, _enabled_features))
|
||||
{
|
||||
foreach (var arg in av.value)
|
||||
{
|
||||
if(!_raw_args.Contains(arg))
|
||||
_raw_args.Add(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
80
Mlaumcherb.Client.Avalonia/классы/Пролетариат/Libraries.cs
Normal file
80
Mlaumcherb.Client.Avalonia/классы/Пролетариат/Libraries.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using DTLib.Extensions;
|
||||
using Mlaumcherb.Client.Avalonia.холопы;
|
||||
|
||||
namespace Mlaumcherb.Client.Avalonia.классы;
|
||||
|
||||
public class Libraries
|
||||
{
|
||||
private static readonly string[] enabled_features = [];
|
||||
|
||||
public record JarLib(string name, IOPath jarFilePath, Artifact artifact);
|
||||
public record NativeLib(string name, IOPath jarFilePath, Artifact artifact, Extract? extractionOptions)
|
||||
: JarLib(name, jarFilePath, artifact);
|
||||
|
||||
public IReadOnlyCollection<JarLib> Libs { get; }
|
||||
|
||||
public Libraries(GameVersionDescriptor descriptor)
|
||||
{
|
||||
List<JarLib> libs = new();
|
||||
HashSet<string> libHashes = new();
|
||||
|
||||
foreach (var l in descriptor.libraries)
|
||||
{
|
||||
if (l.rules != null && !Rules.Check(l.rules, enabled_features))
|
||||
continue;
|
||||
|
||||
if (l.natives != null)
|
||||
{
|
||||
string? nativesKey;
|
||||
if (OperatingSystem.IsWindows())
|
||||
nativesKey = l.natives.windows;
|
||||
else if (OperatingSystem.IsLinux())
|
||||
nativesKey = l.natives.linux;
|
||||
else if (OperatingSystem.IsMacOS())
|
||||
nativesKey = l.natives.osx;
|
||||
else throw new PlatformNotSupportedException();
|
||||
if(nativesKey is null)
|
||||
throw new Exception($"nativesKey for '{l.name}' is null");
|
||||
|
||||
// example: "natives-windows-${arch}"
|
||||
if (nativesKey.Contains('$'))
|
||||
{
|
||||
var span = nativesKey.AsSpan();
|
||||
nativesKey = span.After("${").Before('}') switch
|
||||
{
|
||||
"arch" => span.Before("${").ToString() + PlatformHelper.GetArchOld(),
|
||||
_ => throw new Exception($"unknown placeholder in {nativesKey}")
|
||||
};
|
||||
}
|
||||
|
||||
Artifact artifact = null!;
|
||||
if(l.downloads.classifiers != null && !l.downloads.classifiers.TryGetValue(nativesKey, out artifact!))
|
||||
throw new Exception($"can't find artifact for '{l.name}' with nativesKey '{nativesKey}'");
|
||||
|
||||
// skipping duplicates (WHO THE HELL CREATES THIS DISCRIPTORS AAAAAAAAA)
|
||||
if(!libHashes.Add(artifact.sha1))
|
||||
continue;
|
||||
|
||||
string urlTail = artifact.url.AsSpan().After("://").After('/').ToString();
|
||||
IOPath jarFilePath = Path.Concat(PathHelper.GetLibrariesDir(), urlTail);
|
||||
libs.Add(new NativeLib(l.name, jarFilePath, artifact, l.extract));
|
||||
}
|
||||
else
|
||||
{
|
||||
Artifact? artifact = l.downloads.artifact;
|
||||
if (artifact == null)
|
||||
throw new NullReferenceException($"artifact for '{l.name}' is null");
|
||||
|
||||
// skipping duplicates
|
||||
if(!libHashes.Add(artifact.sha1))
|
||||
continue;
|
||||
|
||||
string urlTail = artifact.url.AsSpan().After("://").After('/').ToString();
|
||||
IOPath jarFilePath = Path.Concat(PathHelper.GetLibrariesDir(), urlTail);
|
||||
libs.Add(new JarLib(l.name, jarFilePath, artifact));
|
||||
}
|
||||
}
|
||||
|
||||
Libs = libs;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user