Add reset config button

This commit is contained in:
dginovker 2023-11-06 00:06:58 +09:00
parent 749c0a08dd
commit 3795e951f1
5 changed files with 78 additions and 19 deletions

View file

@ -3,6 +3,6 @@
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">/usr/share/dotnet/sdk/7.0.100/MSBuild.dll</s:String>
<s:String x:Key="/Default/Environment/Hierarchy/Build/SolBuilderDuo/UseMsbuildSolutionBuilder/@EntryValue">No</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=7a951a1e_002Dc4b2_002D4516_002Db0cc_002D72fd4df57b19/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from FindMostRecentBackupDirectory.cs" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;ProjectFile&gt;6A66E5A7-9297-410F-B061-EB386679E430/d:Saradomin/d:Utilities/d:SingleplayerManagement/f:FindMostRecentBackupDirectory.cs&lt;/ProjectFile&gt;
&lt;Project Location="/home/xacket/Projects/Saradomin-Launcher/UnitTests" Presentation="&amp;lt;UnitTests&amp;gt;" /&gt;
&lt;/SessionState&gt;</s:String>
</wpf:ResourceDictionary>

View file

@ -135,22 +135,32 @@ public static class SingleplayerManagement
}
private static Dictionary<string, string> _confCache;
public static Dictionary<string, string> GrabConfCache()
{
var configPath = CrossPlatform.GetSingleplayerHome() + "/game/worldprops/default.conf";
return File.ReadLines(configPath)
.Where(line => line.Contains('=') && !line.TrimStart().StartsWith("#"))
.Select(l => l.Split(new[] { '#', '=' }, 3))
.ToDictionary(parts => parts[0].Trim(), parts => parts[1].Trim());
}
public static T ParseConf<T>(string key, T defaultValue = default)
{
if (!File.Exists(CrossPlatform.GetSingleplayerHome() + "/game/worldprops/default.conf")) return defaultValue;
_confCache ??= File.ReadLines(CrossPlatform.GetSingleplayerHome() + "/game/worldprops/default.conf")
.Where(line => line.Contains('='))
.Select(line => line.Split('='))
.ToDictionary(parts => parts[0].Trim(), parts => parts[1].Trim());
return (T)Convert.ChangeType(_confCache[key], typeof(T));
_confCache ??= GrabConfCache();
if (!_confCache.TryGetValue(key, out var value)) return defaultValue;
return (T)Convert.ChangeType(value, typeof(T));
}
public static void WriteConf(string key, object value)
{
Console.WriteLine($"Writing {key}");
_confCache[key] = value.ToString().ToLowerInvariant(); // Update cache
var filePath = CrossPlatform.GetSingleplayerHome() + "/game/worldprops/default.conf";
var lines = File.ReadAllLines(filePath);
File.WriteAllLines(filePath, lines.Select(l => l.StartsWith(key + " =") ? $"{key} = {value}" : l));
_confCache[key] = value.ToString();
var lines = File.ReadAllLines(filePath).Select(l =>
l.StartsWith(key + " =")
? $"{key} = {_confCache[key]}" + (l.Contains("#") ? " " + l.Substring(l.IndexOf('#')) : "")
: l);
File.WriteAllLines(filePath, lines);
}
}

View file

@ -188,7 +188,7 @@
<HeaderedContentControl Margin="2,2,0,0"
Classes="GroupBox"
DockPanel.Dock="Top"
Header="singleplayer config (edit config manually for now)">
Header="singleplayer config">
<HeaderedContentControl.HeaderTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Center"

View file

@ -1,5 +1,8 @@
using System;
using System.Diagnostics.Contracts;
using System.IO;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
@ -20,8 +23,6 @@ public class SingleplayerViewModel : ViewModelBase
public string SingleplayerDownloadText { get; private set; } =
Directory.Exists(CrossPlatform.GetSingleplayerHome()) ? "Update Singleplayer" : "Download Singleplayer";
public bool CanDownload { get; private set; } = true;
public bool CanLaunch { get; private set; } = File.Exists(CrossPlatform.LocateSingleplayerExecutable());
public TextBox SingleplayerLogsTextBox { get; }
public bool ShowLogPanel { get; private set; }
@ -55,8 +56,8 @@ public class SingleplayerViewModel : ViewModelBase
{
SingleplayerDownloadText = "Update Singleplayer";
ApplyLatestBackup(PrintLog);
PrintLog($"");
PrintLog($"Singleplayer Download complete");
PrintLog($"");
CanLaunch = true;
return;
}
@ -72,6 +73,7 @@ public class SingleplayerViewModel : ViewModelBase
public void DownloadSingleplayer()
{
if (!CanLaunch) return; // While the button could be disabled, this looks nicer visually (since we update the download progress in the button text)
CanLaunch = false;
MakeBackup();
PrintLog($"Starting singleplayer download...");
@ -93,11 +95,19 @@ public class SingleplayerViewModel : ViewModelBase
CrossPlatform.OpenFolder(CrossPlatform.GetSingleplayerBackupsHome());
}
[Pure]
public static bool IsServerTerminationLog(string log)
{
return Regex.IsMatch(log, @"^\[\d{2}:\d{2}:\d{2}\]: \[SystemTermination\] Server successfully terminated!\s*$");
}
private void PrintLog(string message)
{
ShowLogPanel = true;
Dispatcher.UIThread.Post(() => { SingleplayerLogsTextBox.Text += message + Environment.NewLine; },
DispatcherPriority.Background);
if (IsServerTerminationLog(message)) CanLaunch = true;
}
public void LaunchSingleplayer()
@ -121,8 +131,8 @@ public class SingleplayerViewModel : ViewModelBase
CrossPlatform.LaunchURL("https://forum.2009scape.org/viewforum.php?f=8-support");
}
public bool Cheats
{
public bool Cheats
{
get => ParseConf<bool>("noauth_default_admin");
set => WriteConf("noauth_default_admin", value);
}
@ -145,8 +155,27 @@ public class SingleplayerViewModel : ViewModelBase
set => WriteConf("debug", value);
}
public void ResetToDefaults()
public async void ResetToDefaults()
{
using var httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromSeconds(5);
MakeBackup();
PrintLog("Grabbing the default config from the latest singleplayer codebase..");
try
{
string defaultConf = await httpClient.GetStringAsync("https://gitlab.com/2009scape/singleplayer/windows/-/raw/master/game/worldprops/default.conf");
await File.WriteAllTextAsync(CrossPlatform.GetSingleplayerHome() + "/game/worldprops/default.conf",
defaultConf);
}
catch (Exception ex)
{
PrintLog($"Couldn't reset game properties");
PrintLog(ex.Message);
return;
}
Cheats = GEAutoBuySell = Debug = false; // Force update UI
FakePlayers = true;
PrintLog("Saved new config.");
PrintLog("");
}
}

View file

@ -0,0 +1,20 @@
namespace UnitTests.Saradomin.ViewModel.Controls.SingleplayerViewModel;
[TestFixture]
public class IsServerTerminationLogTests
{
[Test]
[TestCase("[23:43:26]: [SystemTermination] Server successfully terminated!", true)]
[TestCase("[23:00:26]: [SystemTermination] Server successfully terminated!", true)]
[TestCase("[23:43:26]: lol said [SystemTermination] Server successfully terminated!", false)]
[TestCase("[23:00:26]: [SystemTermination] Server successfully terminated! weee exploit", false)]
[TestCase("Gotcha [23:00:26]: [SystemTermination] Server successfully terminated!", false)]
public void ServerTerminationLogTests(string log, bool expectedOutcome)
{
// Act
var result = global::Saradomin.ViewModel.Controls.SingleplayerViewModel.IsServerTerminationLog(log);
// Assert
Assert.That(result, Is.EqualTo(expectedOutcome), $"Failed for log: {log}");
}
}