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/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>
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
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.Threading;
|
||||
using Glitonea.Mvvm;
|
||||
using Glitonea.Mvvm.Messaging;
|
||||
using Saradomin.Infrastructure.Messaging;
|
||||
using Saradomin.Infrastructure.Services;
|
||||
using Saradomin.Model.Settings.Launcher;
|
||||
using Saradomin.Utilities;
|
||||
|
|
@ -35,6 +37,9 @@ public class SingleplayerViewModel : ViewModelBase
|
|||
public bool ShowLogPanel { get; private set; }
|
||||
public LauncherSettings Launcher => _settingsService.Launcher;
|
||||
|
||||
private string _oldServerAddress, _oldManagementAddress;
|
||||
private Process _serverProcess;
|
||||
|
||||
public SingleplayerViewModel(ISettingsService settingsService,
|
||||
IJavaUpdateService javaUpdateService,
|
||||
ISingleplayerUpdateService iSingleplayerUpdateService)
|
||||
|
|
@ -55,6 +60,18 @@ public class SingleplayerViewModel : ViewModelBase
|
|||
AcceptsReturn = true,
|
||||
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)
|
||||
|
|
@ -133,21 +150,36 @@ public class SingleplayerViewModel : ViewModelBase
|
|||
}
|
||||
CanLaunch = false;
|
||||
PrintLog("Starting Singleplayer.. The Singleplayer client will launch when 2009scape is ready. Sit tight!");
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
new Task(() => Utilities.Singleplayer.Windows.WindowsLaunchServerAndClient(Launcher.JavaExecutableLocation, PrintLog)).Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
new Task(() =>
|
||||
CrossPlatform.RunCommandAndGetOutput(
|
||||
$"{CrossPlatform.LocateSingleplayerExecutable()} \"{Launcher.JavaExecutableLocation}\"",
|
||||
PrintLog,
|
||||
PrintLog)
|
||||
).Start();
|
||||
}
|
||||
|
||||
_oldServerAddress = _settingsService.Client.GameServerAddress;
|
||||
_oldManagementAddress = _settingsService.Client.ManagementServerAddress;
|
||||
_settingsService.Client.GameServerAddress = _settingsService.Client.ManagementServerAddress = "localhost";
|
||||
new Task(() => LaunchServerAndClient(Launcher.JavaExecutableLocation, 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()
|
||||
{
|
||||
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<NotificationBoxStateChangedMessage>(this, NotificatationBoxStateChanged);
|
||||
Message.Subscribe<ClientLaunchRequestedMessage>(this, ClientLaunchRequested);
|
||||
|
||||
_settingsService.Launcher.JavaExecutableLocation ??= CrossPlatform.LocateJavaExecutable();
|
||||
}
|
||||
|
|
@ -67,6 +68,12 @@ namespace Saradomin.ViewModel.Windows
|
|||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
public async void ClientLaunchRequested(ClientLaunchRequestedMessage _)
|
||||
{
|
||||
if (CanLaunch)
|
||||
await ExecuteLaunchSequence();
|
||||
}
|
||||
|
||||
public async void MainViewLoaded(MainViewLoadedMessage _)
|
||||
{
|
||||
using (var httpClient = new HttpClient())
|
||||
|
|
@ -117,7 +124,13 @@ namespace Saradomin.ViewModel.Windows
|
|||
public bool CanExecuteLaunchSequence(object param)
|
||||
=> CanLaunch;
|
||||
|
||||
//Stub to maintain compatibility with AXAML
|
||||
public async Task ExecuteLaunchSequence()
|
||||
{
|
||||
await ExecuteLaunchSequence(false);
|
||||
}
|
||||
|
||||
private async Task ExecuteLaunchSequence(bool forceWait)
|
||||
{
|
||||
CanLaunch = false;
|
||||
|
||||
|
|
@ -159,7 +172,7 @@ namespace Saradomin.ViewModel.Windows
|
|||
// Will block this task until client process exits.
|
||||
var t = _launchService.LaunchClient();
|
||||
|
||||
if (!_settingsService.Launcher.AllowMultiboxing)
|
||||
if (!_settingsService.Launcher.AllowMultiboxing || forceWait)
|
||||
await t;
|
||||
}
|
||||
}
|
||||
|
|
@ -174,6 +187,7 @@ namespace Saradomin.ViewModel.Windows
|
|||
{
|
||||
CanLaunch = true;
|
||||
LaunchText = "Play!";
|
||||
Message.Broadcast<ClientClosedMessage>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue