mirror of
https://gitlab.com/2009scape/Saradomin-Launcher.git
synced 2026-08-01 14:19:14 -06:00
Make singleplayer actually use the launcher's client and configuration.
This commit is contained in:
parent
3d51cbf87e
commit
90b8027be1
7 changed files with 112 additions and 94 deletions
|
|
@ -2,7 +2,4 @@
|
||||||
|
|
||||||
<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/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/Hierarchy/Build/SolBuilderDuo/UseMsbuildSolutionBuilder/@EntryValue">No</s:String>
|
||||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=7a951a1e_002Dc4b2_002D4516_002Db0cc_002D72fd4df57b19/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from FindMostRecentBackupDirectory.cs" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
|
||||||
<Project Location="\home\xacket\Projects\Saradomin-Launcher\UnitTests" Presentation="&lt;UnitTests&gt;" />
|
|
||||||
</SessionState></s:String>
|
|
||||||
</wpf:ResourceDictionary>
|
</wpf:ResourceDictionary>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
using Glitonea.Mvvm.Messaging;
|
||||||
|
|
||||||
|
namespace Saradomin.Infrastructure.Messaging;
|
||||||
|
|
||||||
|
public class ClientClosedMessage : Message
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
using Glitonea.Mvvm.Messaging;
|
||||||
|
|
||||||
|
namespace Saradomin.Infrastructure.Messaging;
|
||||||
|
|
||||||
|
public class ClientLaunchRequestedMessage : Message
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -355,5 +355,41 @@ namespace Saradomin.Utilities
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Process StartJavaProcess(string javaExecutable, string jarPath, string memoryAllocation, Action<string> outputHandler, Action onExit)
|
||||||
|
{
|
||||||
|
Process process = new Process();
|
||||||
|
process.StartInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = javaExecutable,
|
||||||
|
Arguments = $"-Xmx{memoryAllocation} -Xms{memoryAllocation} -jar \"{jarPath}\"",
|
||||||
|
UseShellExecute = false,
|
||||||
|
CreateNoWindow = true,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
WorkingDirectory = Path.Combine(CrossPlatform.GetSingleplayerHome(), "game")
|
||||||
|
};
|
||||||
|
|
||||||
|
process.OutputDataReceived += (_, args) =>
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(args.Data)) return;
|
||||||
|
outputHandler?.Invoke(args.Data);
|
||||||
|
};
|
||||||
|
|
||||||
|
process.ErrorDataReceived += (_, args) =>
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(args.Data)) return;
|
||||||
|
outputHandler?.Invoke(args.Data);
|
||||||
|
};
|
||||||
|
|
||||||
|
process.EnableRaisingEvents = true;
|
||||||
|
process.Exited += (_, _) => onExit?.Invoke();
|
||||||
|
|
||||||
|
process.Start();
|
||||||
|
|
||||||
|
process.BeginOutputReadLine();
|
||||||
|
process.BeginErrorReadLine();
|
||||||
|
return process;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.NetworkInformation;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Saradomin.Utilities.Singleplayer;
|
|
||||||
|
|
||||||
public static class Windows
|
|
||||||
{
|
|
||||||
private static bool IsPortInUse(int port)
|
|
||||||
{
|
|
||||||
var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
|
|
||||||
var tcpConnInfoArray = ipGlobalProperties.GetActiveTcpListeners();
|
|
||||||
|
|
||||||
return tcpConnInfoArray.Any(endpoint => endpoint.Port == port);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Process StartJavaProcess(string javaExecutable, string jarPath, string memoryAllocation, Action<string> outputHandler, Action onExit)
|
|
||||||
{
|
|
||||||
Process process = new Process();
|
|
||||||
process.StartInfo = new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = javaExecutable,
|
|
||||||
Arguments = $"-Xmx{memoryAllocation} -Xms{memoryAllocation} -jar \"{jarPath}\"",
|
|
||||||
UseShellExecute = false,
|
|
||||||
CreateNoWindow = true,
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
WorkingDirectory = Path.Combine(CrossPlatform.GetSingleplayerHome(), "game")
|
|
||||||
};
|
|
||||||
|
|
||||||
process.OutputDataReceived += (_, args) =>
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(args.Data)) return;
|
|
||||||
outputHandler?.Invoke(args.Data);
|
|
||||||
};
|
|
||||||
|
|
||||||
process.ErrorDataReceived += (_, args) =>
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(args.Data)) return;
|
|
||||||
outputHandler?.Invoke(args.Data);
|
|
||||||
};
|
|
||||||
|
|
||||||
process.EnableRaisingEvents = true;
|
|
||||||
process.Exited += (_, _) => onExit?.Invoke();
|
|
||||||
|
|
||||||
process.Start();
|
|
||||||
|
|
||||||
process.BeginOutputReadLine();
|
|
||||||
process.BeginErrorReadLine();
|
|
||||||
return process;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void WindowsLaunchServerAndClient(string javaExecutableLocation, Action<string> log)
|
|
||||||
{
|
|
||||||
string serverJar = CrossPlatform.GetSingleplayerHome() + @"\game\server.jar";
|
|
||||||
string clientJar = CrossPlatform.GetSingleplayerHome() + @"\game\client.jar";
|
|
||||||
|
|
||||||
if (IsPortInUse(43595))
|
|
||||||
{
|
|
||||||
log("Port 43595 is in use. Cannot start the server again.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Process serverProcess = StartJavaProcess(javaExecutableLocation, serverJar, "2G", log, null);
|
|
||||||
|
|
||||||
while (!IsPortInUse(43595)) Thread.Sleep(1000);
|
|
||||||
|
|
||||||
StartJavaProcess(javaExecutableLocation, clientJar, "1G", null, () =>
|
|
||||||
{
|
|
||||||
serverProcess.Kill();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -14,6 +14,8 @@ using Avalonia.Controls;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using Glitonea.Mvvm;
|
using Glitonea.Mvvm;
|
||||||
|
using Glitonea.Mvvm.Messaging;
|
||||||
|
using Saradomin.Infrastructure.Messaging;
|
||||||
using Saradomin.Infrastructure.Services;
|
using Saradomin.Infrastructure.Services;
|
||||||
using Saradomin.Model.Settings.Launcher;
|
using Saradomin.Model.Settings.Launcher;
|
||||||
using Saradomin.Utilities;
|
using Saradomin.Utilities;
|
||||||
|
|
@ -35,6 +37,9 @@ public class SingleplayerViewModel : ViewModelBase
|
||||||
public bool ShowLogPanel { get; private set; }
|
public bool ShowLogPanel { get; private set; }
|
||||||
public LauncherSettings Launcher => _settingsService.Launcher;
|
public LauncherSettings Launcher => _settingsService.Launcher;
|
||||||
|
|
||||||
|
private string _oldServerAddress, _oldManagementAddress;
|
||||||
|
private Process _serverProcess;
|
||||||
|
|
||||||
public SingleplayerViewModel(ISettingsService settingsService,
|
public SingleplayerViewModel(ISettingsService settingsService,
|
||||||
IJavaUpdateService javaUpdateService,
|
IJavaUpdateService javaUpdateService,
|
||||||
ISingleplayerUpdateService iSingleplayerUpdateService)
|
ISingleplayerUpdateService iSingleplayerUpdateService)
|
||||||
|
|
@ -55,6 +60,18 @@ public class SingleplayerViewModel : ViewModelBase
|
||||||
AcceptsReturn = true,
|
AcceptsReturn = true,
|
||||||
TextWrapping = TextWrapping.Wrap,
|
TextWrapping = TextWrapping.Wrap,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Message.Subscribe<ClientClosedMessage>(this, OnClientClosed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnClientClosed(ClientClosedMessage _)
|
||||||
|
{
|
||||||
|
if (_serverProcess == null) return;
|
||||||
|
_serverProcess.Kill();
|
||||||
|
_serverProcess = null;
|
||||||
|
CanLaunch = true;
|
||||||
|
_settingsService.Client.GameServerAddress = _oldServerAddress;
|
||||||
|
_settingsService.Client.ManagementServerAddress = _oldManagementAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSingleplayerDownloadProgressChanged(object sender, Tuple<float, bool> e)
|
private void OnSingleplayerDownloadProgressChanged(object sender, Tuple<float, bool> e)
|
||||||
|
|
@ -133,21 +150,36 @@ public class SingleplayerViewModel : ViewModelBase
|
||||||
}
|
}
|
||||||
CanLaunch = false;
|
CanLaunch = false;
|
||||||
PrintLog("Starting Singleplayer.. The Singleplayer client will launch when 2009scape is ready. Sit tight!");
|
PrintLog("Starting Singleplayer.. The Singleplayer client will launch when 2009scape is ready. Sit tight!");
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
||||||
{
|
_oldServerAddress = _settingsService.Client.GameServerAddress;
|
||||||
new Task(() => Utilities.Singleplayer.Windows.WindowsLaunchServerAndClient(Launcher.JavaExecutableLocation, PrintLog)).Start();
|
_oldManagementAddress = _settingsService.Client.ManagementServerAddress;
|
||||||
}
|
_settingsService.Client.GameServerAddress = _settingsService.Client.ManagementServerAddress = "localhost";
|
||||||
else
|
new Task(() => LaunchServerAndClient(Launcher.JavaExecutableLocation, PrintLog)).Start();
|
||||||
{
|
|
||||||
new Task(() =>
|
|
||||||
CrossPlatform.RunCommandAndGetOutput(
|
|
||||||
$"{CrossPlatform.LocateSingleplayerExecutable()} \"{Launcher.JavaExecutableLocation}\"",
|
|
||||||
PrintLog,
|
|
||||||
PrintLog)
|
|
||||||
).Start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LaunchServerAndClient (string javaExecutableLocation, Action<string> log)
|
||||||
|
{
|
||||||
|
var serverJar = CrossPlatform.GetSingleplayerHome() + @"/game/server.jar";
|
||||||
|
|
||||||
|
if (IsPortInUse(43595))
|
||||||
|
{
|
||||||
|
log("Port 43595 is in use. Cannot start the server again.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_serverProcess = CrossPlatform.StartJavaProcess(javaExecutableLocation, serverJar, "2G", log, null);
|
||||||
|
while (!IsPortInUse(43595)) Thread.Sleep(1000);
|
||||||
|
Message.Broadcast<ClientLaunchRequestedMessage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsPortInUse(int port)
|
||||||
|
{
|
||||||
|
var ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
|
||||||
|
var tcpConnInfoArray = ipGlobalProperties.GetActiveTcpListeners();
|
||||||
|
|
||||||
|
return tcpConnInfoArray.Any(endpoint => endpoint.Port == port);
|
||||||
|
}
|
||||||
|
|
||||||
private void LaunchFaq()
|
private void LaunchFaq()
|
||||||
{
|
{
|
||||||
CrossPlatform.LaunchURL("https://2009scape.org/site/game_guide/singleplayer.html");
|
CrossPlatform.LaunchURL("https://2009scape.org/site/game_guide/singleplayer.html");
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ namespace Saradomin.ViewModel.Windows
|
||||||
|
|
||||||
Message.Subscribe<MainViewLoadedMessage>(this, MainViewLoaded);
|
Message.Subscribe<MainViewLoadedMessage>(this, MainViewLoaded);
|
||||||
Message.Subscribe<NotificationBoxStateChangedMessage>(this, NotificatationBoxStateChanged);
|
Message.Subscribe<NotificationBoxStateChangedMessage>(this, NotificatationBoxStateChanged);
|
||||||
|
Message.Subscribe<ClientLaunchRequestedMessage>(this, ClientLaunchRequested);
|
||||||
|
|
||||||
_settingsService.Launcher.JavaExecutableLocation ??= CrossPlatform.LocateJavaExecutable();
|
_settingsService.Launcher.JavaExecutableLocation ??= CrossPlatform.LocateJavaExecutable();
|
||||||
}
|
}
|
||||||
|
|
@ -67,6 +68,12 @@ namespace Saradomin.ViewModel.Windows
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async void ClientLaunchRequested(ClientLaunchRequestedMessage _)
|
||||||
|
{
|
||||||
|
if (CanLaunch)
|
||||||
|
await ExecuteLaunchSequence();
|
||||||
|
}
|
||||||
|
|
||||||
public async void MainViewLoaded(MainViewLoadedMessage _)
|
public async void MainViewLoaded(MainViewLoadedMessage _)
|
||||||
{
|
{
|
||||||
using (var httpClient = new HttpClient())
|
using (var httpClient = new HttpClient())
|
||||||
|
|
@ -117,7 +124,13 @@ namespace Saradomin.ViewModel.Windows
|
||||||
public bool CanExecuteLaunchSequence(object param)
|
public bool CanExecuteLaunchSequence(object param)
|
||||||
=> CanLaunch;
|
=> CanLaunch;
|
||||||
|
|
||||||
|
//Stub to maintain compatibility with AXAML
|
||||||
public async Task ExecuteLaunchSequence()
|
public async Task ExecuteLaunchSequence()
|
||||||
|
{
|
||||||
|
await ExecuteLaunchSequence(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ExecuteLaunchSequence(bool forceWait)
|
||||||
{
|
{
|
||||||
CanLaunch = false;
|
CanLaunch = false;
|
||||||
|
|
||||||
|
|
@ -159,7 +172,7 @@ namespace Saradomin.ViewModel.Windows
|
||||||
// Will block this task until client process exits.
|
// Will block this task until client process exits.
|
||||||
var t = _launchService.LaunchClient();
|
var t = _launchService.LaunchClient();
|
||||||
|
|
||||||
if (!_settingsService.Launcher.AllowMultiboxing)
|
if (!_settingsService.Launcher.AllowMultiboxing || forceWait)
|
||||||
await t;
|
await t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -174,6 +187,7 @@ namespace Saradomin.ViewModel.Windows
|
||||||
{
|
{
|
||||||
CanLaunch = true;
|
CanLaunch = true;
|
||||||
LaunchText = "Play!";
|
LaunchText = "Play!";
|
||||||
|
Message.Broadcast<ClientClosedMessage>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue