Implemented fabric version setting

This commit is contained in:
Marcel Baumgartner
2023-04-28 18:07:51 +02:00
parent 4fc3d70df0
commit 3e2828f3d8
6 changed files with 332 additions and 2 deletions

View File

@@ -37,4 +37,61 @@ public static class ParseHelper
return res; return res;
} }
public static string GetHighestVersion(string[] versions)
{
// Initialize the highest version to the first version in the array
string highestVersion = versions[0];
// Loop through the remaining versions in the array
for (int i = 1; i < versions.Length; i++)
{
// Compare the current version to the highest version
if (CompareVersions(versions[i], highestVersion) > 0)
{
// If the current version is higher, update the highest version
highestVersion = versions[i];
}
}
return highestVersion;
}
public static int CompareVersions(string version1, string version2)
{
// Split the versions into their component parts
string[] version1Parts = version1.Split('.');
string[] version2Parts = version2.Split('.');
// Compare each component part in turn
for (int i = 0; i < version1Parts.Length && i < version2Parts.Length; i++)
{
int part1 = int.Parse(version1Parts[i]);
int part2 = int.Parse(version2Parts[i]);
if (part1 < part2)
{
return -1;
}
else if (part1 > part2)
{
return 1;
}
}
// If we get here, the versions are equal up to the length of the shorter one.
// If one version has more parts than the other, the longer one is considered higher.
if (version1Parts.Length < version2Parts.Length)
{
return -1;
}
else if (version1Parts.Length > version2Parts.Length)
{
return 1;
}
else
{
return 0;
}
}
} }

View File

@@ -0,0 +1,96 @@
using System.Text;
using Moonlight.App.Helpers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Moonlight.App.Services;
public class FabricService
{
private readonly HttpClient Client;
public FabricService()
{
Client = new();
}
public async Task<string> GetLatestInstallerVersion()
{
var data = await Client
.GetStringAsync("https://meta.fabricmc.net/v2/versions/installer");
var x = JsonConvert.DeserializeObject<JObject[]>(data) ?? Array.Empty<JObject>();
var stableVersions = new List<string>();
foreach (var y in x)
{
var section = new ConfigurationBuilder().AddJsonStream(
new MemoryStream(Encoding.ASCII.GetBytes(
y.Root.ToString()
)
)
).Build();
if (section.GetValue<bool>("stable"))
{
stableVersions.Add(section.GetValue<string>("version"));
}
}
return ParseHelper.GetHighestVersion(stableVersions.ToArray());
}
public async Task<string> GetLatestLoaderVersion()
{
var data = await Client
.GetStringAsync("https://meta.fabricmc.net/v2/versions/loader");
var x = JsonConvert.DeserializeObject<JObject[]>(data) ?? Array.Empty<JObject>();
var stableVersions = new List<string>();
foreach (var y in x)
{
var section = new ConfigurationBuilder().AddJsonStream(
new MemoryStream(Encoding.ASCII.GetBytes(
y.Root.ToString()
)
)
).Build();
if (section.GetValue<bool>("stable"))
{
stableVersions.Add(section.GetValue<string>("version"));
}
}
return ParseHelper.GetHighestVersion(stableVersions.ToArray());
}
public async Task<string[]> GetGameVersions()
{
var data = await Client
.GetStringAsync("https://meta.fabricmc.net/v2/versions/game");
var x = JsonConvert.DeserializeObject<JObject[]>(data) ?? Array.Empty<JObject>();
var stableVersions = new List<string>();
foreach (var y in x)
{
var section = new ConfigurationBuilder().AddJsonStream(
new MemoryStream(Encoding.ASCII.GetBytes(
y.Root.ToString()
)
)
).Build();
if (section.GetValue<bool>("stable"))
{
stableVersions.Add(section.GetValue<string>("version"));
}
}
return stableVersions.ToArray();
}
}

View File

@@ -15,12 +15,12 @@ public class ForgeService
// Key: 1.9.4-recommended Value: 12.17.0.2317 // Key: 1.9.4-recommended Value: 12.17.0.2317
public async Task<Dictionary<string, string>> GetVersions() public async Task<Dictionary<string, string>> GetVersions()
{ {
var data = await Client.GetAsync( var data = await Client.GetStringAsync(
"https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json"); "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json");
var json = new ConfigurationBuilder().AddJsonStream( var json = new ConfigurationBuilder().AddJsonStream(
new MemoryStream(Encoding.ASCII.GetBytes( new MemoryStream(Encoding.ASCII.GetBytes(
await data.Content.ReadAsStringAsync() data
) )
) )
).Build(); ).Build();

View File

@@ -107,6 +107,7 @@ namespace Moonlight
builder.Services.AddSingleton<EventSystem>(); builder.Services.AddSingleton<EventSystem>();
builder.Services.AddScoped<FileDownloadService>(); builder.Services.AddScoped<FileDownloadService>();
builder.Services.AddScoped<ForgeService>(); builder.Services.AddScoped<ForgeService>();
builder.Services.AddScoped<FabricService>();
builder.Services.AddScoped<GoogleOAuth2Service>(); builder.Services.AddScoped<GoogleOAuth2Service>();
builder.Services.AddScoped<DiscordOAuth2Service>(); builder.Services.AddScoped<DiscordOAuth2Service>();

View File

@@ -40,6 +40,9 @@
if(Tags.Contains("forgeversion")) if(Tags.Contains("forgeversion"))
Settings.Add("Forge version", typeof(ForgeVersionSetting)); Settings.Add("Forge version", typeof(ForgeVersionSetting));
if(Tags.Contains("fabricversion"))
Settings.Add("Fabric version", typeof(FabricVersionSetting));
if(Tags.Contains("join2start")) if(Tags.Contains("join2start"))
Settings.Add("Join2Start", typeof(Join2StartSetting)); Settings.Add("Join2Start", typeof(Join2StartSetting));

View File

@@ -0,0 +1,173 @@
@using Moonlight.App.Services
@using Microsoft.EntityFrameworkCore
@using Moonlight.App.Database.Entities
@using Moonlight.App.Repositories
@using Moonlight.App.Repositories.Servers
@using Moonlight.App.Helpers
@inject ServerService ServerService
@inject ServerRepository ServerRepository
@inject ImageRepository ImageRepository
@inject FabricService FabricService
@inject SmartTranslateService TranslationService
<div class="col">
<div class="card card-body">
<LazyLoader Load="Load">
<label class="mb-2 form-label">
<TL>Fabric version</TL>
</label>
<input class="mb-2 form-control" disabled="" value="@(FabricVersion)"/>
<label class="mb-2 form-label">
<TL>Fabric loader version</TL>
</label>
<input class="mb-2 form-control" disabled="" value="@(LoaderVersion)"/>
<label class="mb-2 form-label">
<TL>Minecraft version</TL>
</label>
<select class="mb-2 form-select" @bind="CurrentVersion">
@foreach (var version in Versions)
{
if (version == CurrentVersion)
{
<option value="@(version)" selected="">@(version)</option>
}
else
{
<option value="@(version)">@(version)</option>
}
}
</select>
<WButton
OnClick="Save"
Text="@(TranslationService.Translate("Change"))"
WorkingText="@(TranslationService.Translate("Changing"))"
CssClasses="btn-primary">
</WButton>
</LazyLoader>
</div>
</div>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private string[] Versions = Array.Empty<string>();
private string CurrentVersion = "";
private string FabricVersion = "";
private string LoaderVersion = "";
private async Task Load(LazyLoader lazyLoader)
{
// Fabric version
var fabricVersion = LiveMigrateVar(
"FABRIC_VERSION",
await FabricService.GetLatestInstallerVersion(),
true
);
FabricVersion = fabricVersion.Value;
// Fabric loader version
var loaderVersion = LiveMigrateVar(
"LOADER_VERSION",
await FabricService.GetLatestLoaderVersion(),
true
);
LoaderVersion = loaderVersion.Value;
// Minecraft versions
Versions = await FabricService.GetGameVersions();
var mcVersion = LiveMigrateVar(
"MC_VERSION",
Versions.First()
);
CurrentVersion = mcVersion.Value;
await InvokeAsync(StateHasChanged);
}
private ServerVariable LiveMigrateVar(string key, string value, bool overwrite = false)
{
var v = CurrentServer.Variables.FirstOrDefault(x => x.Key == key);
if (v == null)
{
CurrentServer.Variables.Add(new()
{
Key = key,
Value = value
});
ServerRepository.Update(CurrentServer);
return CurrentServer.Variables.First(x => x.Key == key);
}
else
{
if (string.IsNullOrEmpty(v.Value) || overwrite)
{
v.Value = value;
ServerRepository.Update(CurrentServer);
}
return v;
}
}
private async Task Save()
{
var vars = CurrentServer.Variables;
var versionVar = vars.First(x => x.Key == "MC_VERSION");
versionVar.Value = CurrentVersion;
// This searches for the display name of a version using the constructed full version
var version = ParseHelper.MinecraftToInt(CurrentVersion);
var serverImage = ImageRepository
.Get()
.Include(x => x.DockerImages)
.First(x => x.Id == CurrentServer.Image.Id);
var dockerImages = serverImage.DockerImages;
var dockerImageToUpdate = dockerImages.Last();
if (version < 1130)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("8"));
}
if (version >= 1130)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("11"));
}
if (version >= 1170)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("16"));
}
if (version >= 1190)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("17"));
}
CurrentServer.DockerImageIndex = dockerImages.IndexOf(dockerImageToUpdate);
ServerRepository.Update(CurrentServer);
await ServerService.Reinstall(CurrentServer);
}
}