Added supports other game mode LAN (Daily, Custom)
Now game cannot start before all players are present
This commit is contained in:
@@ -0,0 +1,102 @@
|
|||||||
|
using Godot;
|
||||||
|
using HarmonyLib;
|
||||||
|
using MegaCrit.Sts2.Core.Assets;
|
||||||
|
using MegaCrit.Sts2.Core.Helpers;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.GodotExtensions;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.MainMenu;
|
||||||
|
using MegaCrit.Sts2.Core.Runs;
|
||||||
|
using MegaCrit.Sts2.Core.TestSupport;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
|
namespace SlayTheSpire2.LAN.Multiplayer.Components
|
||||||
|
{
|
||||||
|
internal class LanMultiplayerHostSubmenu : NMultiplayerHostSubmenu
|
||||||
|
{
|
||||||
|
private static readonly string ScenePath = SceneHelper.GetScenePath("screens/multiplayer_host_submenu");
|
||||||
|
|
||||||
|
public static LanMultiplayerHostSubmenu? Instance { get; private set; }
|
||||||
|
|
||||||
|
private Control? _loadingOverlay;
|
||||||
|
|
||||||
|
public new static NMultiplayerHostSubmenu? Create()
|
||||||
|
{
|
||||||
|
if (Instance != null)
|
||||||
|
return Instance;
|
||||||
|
|
||||||
|
if (TestMode.IsOn)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var multiplayerHostSubmenu =
|
||||||
|
PreloadManager.Cache.GetScene(ScenePath).Instantiate<NMultiplayerHostSubmenu>();
|
||||||
|
|
||||||
|
var lanMultiplayerHostSubmenu = new LanMultiplayerHostSubmenu();
|
||||||
|
|
||||||
|
lanMultiplayerHostSubmenu.SetAnchorsAndOffsetsPreset(LayoutPreset.FullRect);
|
||||||
|
|
||||||
|
foreach (var child in multiplayerHostSubmenu.GetChildren())
|
||||||
|
{
|
||||||
|
child.Reparent(lanMultiplayerHostSubmenu, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
multiplayerHostSubmenu.QueueFree();
|
||||||
|
|
||||||
|
Instance = lanMultiplayerHostSubmenu;
|
||||||
|
|
||||||
|
return lanMultiplayerHostSubmenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
ConnectSignals();
|
||||||
|
|
||||||
|
var loadingOverlay = GetNode<Control>("LoadingOverlay");
|
||||||
|
Traverse.Create(this).Field("_loadingOverlay").SetValue(loadingOverlay);
|
||||||
|
_loadingOverlay = loadingOverlay;
|
||||||
|
|
||||||
|
var standardButton = GetNode<NSubmenuButton>("StandardButton");
|
||||||
|
Traverse.Create(this).Field("_standardButton").SetValue(standardButton);
|
||||||
|
|
||||||
|
standardButton.Connect(NClickableControl.SignalName.Released, Callable.From<NButton>(OnStandardPressed));
|
||||||
|
standardButton.SetIconAndLocalization("STANDARD_MP");
|
||||||
|
|
||||||
|
var dailyButton = GetNode<NSubmenuButton>("DailyButton");
|
||||||
|
Traverse.Create(this).Field("_dailyButton").SetValue(dailyButton);
|
||||||
|
|
||||||
|
dailyButton.Connect(NClickableControl.SignalName.Released, Callable.From<NButton>(OnDailyPressed));
|
||||||
|
dailyButton.SetIconAndLocalization("DAILY_MP");
|
||||||
|
|
||||||
|
var customButton = GetNode<NSubmenuButton>("CustomRunButton");
|
||||||
|
Traverse.Create(this).Field("_customButton").SetValue(customButton);
|
||||||
|
|
||||||
|
customButton.Connect(NClickableControl.SignalName.Released, Callable.From<NButton>(OnCustomPressed));
|
||||||
|
customButton.SetIconAndLocalization("CUSTOM_MP");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStandardPressed(NButton _)
|
||||||
|
{
|
||||||
|
StartHost(GameMode.Standard);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDailyPressed(NButton _)
|
||||||
|
{
|
||||||
|
StartHost(GameMode.Daily);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCustomPressed(NButton _)
|
||||||
|
{
|
||||||
|
StartHost(GameMode.Custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
private new void StartHost(GameMode gameMode)
|
||||||
|
{
|
||||||
|
if (_loadingOverlay != null)
|
||||||
|
{
|
||||||
|
var settingsModel = SettingsService.Instance.SettingsModel;
|
||||||
|
|
||||||
|
LanHostHelper.StartHost(gameMode, _loadingOverlay, _stack, settingsModel.HostPort,
|
||||||
|
settingsModel.HostMaxPlayers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ using MegaCrit.Sts2.Core.Nodes.Screens.MainMenu;
|
|||||||
using MegaCrit.Sts2.Core.Platform;
|
using MegaCrit.Sts2.Core.Platform;
|
||||||
using MegaCrit.Sts2.Core.Runs;
|
using MegaCrit.Sts2.Core.Runs;
|
||||||
using MegaCrit.Sts2.Core.Saves;
|
using MegaCrit.Sts2.Core.Saves;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
// ReSharper disable MemberCanBePrivate.Global
|
// ReSharper disable MemberCanBePrivate.Global
|
||||||
// ReSharper disable UnusedType.Global
|
// ReSharper disable UnusedType.Global
|
||||||
@@ -138,7 +139,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Helpers
|
|||||||
ushort port, int maxPlayers)
|
ushort port, int maxPlayers)
|
||||||
{
|
{
|
||||||
var readSaveResult =
|
var readSaveResult =
|
||||||
LanRunSaveManagerHelper.LoadAndCanonicalizeMultiplayerRunSave(
|
LanRunSaveManagerService.Instance.LoadAndCanonicalizeMultiplayerRunSave(
|
||||||
PlatformUtil.GetLocalPlayerId(PlatformType.None));
|
PlatformUtil.GetLocalPlayerId(PlatformType.None));
|
||||||
if (!readSaveResult.Success || readSaveResult.SaveData == null)
|
if (!readSaveResult.Success || readSaveResult.SaveData == null)
|
||||||
{
|
{
|
||||||
@@ -177,7 +178,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Helpers
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var readSaveResult =
|
var readSaveResult =
|
||||||
LanRunSaveManagerHelper.LoadAndCanonicalizeMultiplayerRunSave(
|
LanRunSaveManagerService.Instance.LoadAndCanonicalizeMultiplayerRunSave(
|
||||||
PlatformUtil.GetLocalPlayerId(PlatformType.None));
|
PlatformUtil.GetLocalPlayerId(PlatformType.None));
|
||||||
if (readSaveResult is { Success: true, SaveData: not null })
|
if (readSaveResult is { Success: true, SaveData: not null })
|
||||||
{
|
{
|
||||||
@@ -206,7 +207,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Helpers
|
|||||||
$"ERROR: Failed to load multiplayer run save: status={readSaveResult.Status}. Deleting current run...");
|
$"ERROR: Failed to load multiplayer run save: status={readSaveResult.Status}. Deleting current run...");
|
||||||
}
|
}
|
||||||
|
|
||||||
LanRunSaveManagerHelper.DeleteCurrentMultiplayerRun();
|
LanRunSaveManagerService.Instance.DeleteCurrentMultiplayerRun();
|
||||||
updateButtons();
|
updateButtons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
// ReSharper disable ClassNeverInstantiated.Global
|
|
||||||
|
|
||||||
namespace SlayTheSpire2.LAN.Multiplayer.Helpers
|
|
||||||
{
|
|
||||||
internal class LanMapDrawingsHelper
|
|
||||||
{
|
|
||||||
public static readonly HashSet<ulong> DisableDrawingHashSet = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
using HarmonyLib;
|
|
||||||
using MegaCrit.Sts2.addons.mega_text;
|
|
||||||
using MegaCrit.Sts2.Core.Multiplayer;
|
|
||||||
using MegaCrit.Sts2.Core.Multiplayer.Game;
|
|
||||||
using MegaCrit.Sts2.Core.Nodes.Multiplayer;
|
|
||||||
using MegaCrit.Sts2.Core.Nodes.Screens.CharacterSelect;
|
|
||||||
using MegaCrit.Sts2.Core.Platform;
|
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Components;
|
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Models;
|
|
||||||
|
|
||||||
// ReSharper disable ClassNeverInstantiated.Global
|
|
||||||
|
|
||||||
namespace SlayTheSpire2.LAN.Multiplayer.Helpers
|
|
||||||
{
|
|
||||||
internal class LanPlayerNameHelper
|
|
||||||
{
|
|
||||||
public static LanPlayerNames PlayerNameDictionary = DefaultPlayerNameDictionary;
|
|
||||||
|
|
||||||
public static INetGameService? NetService;
|
|
||||||
|
|
||||||
public static NCharacterSelectScreen? CharacterSelectScreen;
|
|
||||||
|
|
||||||
public static NMultiplayerLoadGameScreen? MultiplayerLoadGameScreen;
|
|
||||||
|
|
||||||
public static TaskCompletionSource<LanPlayerNameResponseMessage>? LanPlayerNameCompletion;
|
|
||||||
|
|
||||||
private static LanPlayerNames DefaultPlayerNameDictionary =>
|
|
||||||
!PlayerNameLineEdit.GetPlayerNameIsInvalid(SettingsHelper.Instance.SettingsModel.PlayerName)
|
|
||||||
? new LanPlayerNames
|
|
||||||
{
|
|
||||||
{ 1u, SettingsHelper.Instance.SettingsModel.PlayerName }
|
|
||||||
}
|
|
||||||
: new LanPlayerNames();
|
|
||||||
|
|
||||||
public static void SetHostPlayerName()
|
|
||||||
{
|
|
||||||
if (!PlayerNameLineEdit.GetPlayerNameIsInvalid(SettingsHelper.Instance.SettingsModel.PlayerName))
|
|
||||||
{
|
|
||||||
PlayerNameDictionary[1u] = SettingsHelper.Instance.SettingsModel.PlayerName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PlayerNameDictionary.Remove(1u);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetDefaultPlayerNameDictionary()
|
|
||||||
{
|
|
||||||
PlayerNameDictionary = DefaultPlayerNameDictionary;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void HandleLanPlayerNameResponseMessage(LanPlayerNameResponseMessage lanPlayerNameResponseMessage,
|
|
||||||
ulong senderId)
|
|
||||||
{
|
|
||||||
PlayerNameDictionary = lanPlayerNameResponseMessage.playerNameDictionary;
|
|
||||||
|
|
||||||
UpdatePlayerName();
|
|
||||||
|
|
||||||
LanPlayerNameCompletion?.SetResult(lanPlayerNameResponseMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void HandleLanPlayerNameRequestMessage(LanPlayerNameRequestMessage lanPlayerNameRequestMessage,
|
|
||||||
ulong senderId)
|
|
||||||
{
|
|
||||||
if (PlayerNameLineEdit.GetPlayerNameIsInvalid(lanPlayerNameRequestMessage.playerName))
|
|
||||||
{
|
|
||||||
NetService?.SendMessage(
|
|
||||||
new LanPlayerNameResponseMessage { playerNameDictionary = PlayerNameDictionary }, senderId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerNameDictionary[senderId] = lanPlayerNameRequestMessage.playerName;
|
|
||||||
|
|
||||||
UpdatePlayerName();
|
|
||||||
|
|
||||||
NetService?.SendMessage(new LanPlayerNameResponseMessage { playerNameDictionary = PlayerNameDictionary });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task AttemptPlayerName(NetClientGameService gameService)
|
|
||||||
{
|
|
||||||
LanPlayerNameCompletion = new TaskCompletionSource<LanPlayerNameResponseMessage>();
|
|
||||||
var message = new LanPlayerNameRequestMessage
|
|
||||||
{ playerName = SettingsHelper.Instance.SettingsModel.PlayerName };
|
|
||||||
gameService.SendMessage(message);
|
|
||||||
await LanPlayerNameCompletion.Task;
|
|
||||||
LanPlayerNameCompletion = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UpdatePlayerName()
|
|
||||||
{
|
|
||||||
if (CharacterSelectScreen != null)
|
|
||||||
{
|
|
||||||
UpdateNameplateLabel(CharacterSelectScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MultiplayerLoadGameScreen != null)
|
|
||||||
{
|
|
||||||
UpdateNameplateLabel(MultiplayerLoadGameScreen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UpdateNameplateLabel(Control container)
|
|
||||||
{
|
|
||||||
var nodes = Traverse.Create(container).Field("_remotePlayerContainer")
|
|
||||||
.Field("_nodes").GetValue<List<NRemoteLobbyPlayer>>();
|
|
||||||
|
|
||||||
foreach (var node in nodes)
|
|
||||||
{
|
|
||||||
var megaLabel = Traverse.Create(node).Field("_nameplateLabel").GetValue<MegaLabel>();
|
|
||||||
|
|
||||||
if (!GodotObject.IsInstanceValid(megaLabel))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
megaLabel.SetTextAutoSize(PlatformUtil.GetPlayerName(PlatformType.None, node.PlayerId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
using MegaCrit.Sts2.Core.Nodes.Screens.MainMenu;
|
|
||||||
|
|
||||||
// ReSharper disable ClassNeverInstantiated.Global
|
|
||||||
|
|
||||||
namespace SlayTheSpire2.LAN.Multiplayer.Helpers
|
|
||||||
{
|
|
||||||
internal class NMultiplayerSubmenuButtonHelpers
|
|
||||||
{
|
|
||||||
public static NSubmenuButton? LanHostButton;
|
|
||||||
public static NSubmenuButton? LanLoadButton;
|
|
||||||
public static NSubmenuButton? LanAbandonButton;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Models
|
|||||||
{
|
{
|
||||||
public struct LanPlayerNameResponseMessage : INetMessage
|
public struct LanPlayerNameResponseMessage : INetMessage
|
||||||
{
|
{
|
||||||
public LanPlayerNames playerNameDictionary;
|
public PlayerNames playerNames;
|
||||||
|
|
||||||
public bool ShouldBroadcast => false;
|
public bool ShouldBroadcast => false;
|
||||||
public NetTransferMode Mode => NetTransferMode.Reliable;
|
public NetTransferMode Mode => NetTransferMode.Reliable;
|
||||||
@@ -14,8 +14,8 @@ namespace SlayTheSpire2.LAN.Multiplayer.Models
|
|||||||
|
|
||||||
public void Serialize(PacketWriter writer)
|
public void Serialize(PacketWriter writer)
|
||||||
{
|
{
|
||||||
writer.WriteInt(playerNameDictionary.Count);
|
writer.WriteInt(playerNames.Count);
|
||||||
foreach (var keyValue in playerNameDictionary)
|
foreach (var keyValue in playerNames)
|
||||||
{
|
{
|
||||||
writer.WriteULong(keyValue.Key);
|
writer.WriteULong(keyValue.Key);
|
||||||
writer.WriteString(keyValue.Value);
|
writer.WriteString(keyValue.Value);
|
||||||
@@ -25,10 +25,10 @@ namespace SlayTheSpire2.LAN.Multiplayer.Models
|
|||||||
public void Deserialize(PacketReader reader)
|
public void Deserialize(PacketReader reader)
|
||||||
{
|
{
|
||||||
var count = reader.ReadInt();
|
var count = reader.ReadInt();
|
||||||
playerNameDictionary = new LanPlayerNames();
|
playerNames = new PlayerNames();
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
playerNameDictionary.Add(reader.ReadULong(), reader.ReadString());
|
playerNames.Add(reader.ReadULong(), reader.ReadString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace SlayTheSpire2.LAN.Multiplayer.Models
|
|
||||||
{
|
|
||||||
[JsonSerializable(typeof(LanPlayerNames))]
|
|
||||||
public partial class LanPlayerNamesContext : JsonSerializerContext;
|
|
||||||
|
|
||||||
public class LanPlayerNames : Dictionary<ulong, string>;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace SlayTheSpire2.LAN.Multiplayer.Models
|
||||||
|
{
|
||||||
|
[JsonSerializable(typeof(PlayerNames))]
|
||||||
|
public partial class PlayerNamesContext : JsonSerializerContext;
|
||||||
|
|
||||||
|
public class PlayerNames : Dictionary<ulong, string>;
|
||||||
|
}
|
||||||
@@ -3,8 +3,8 @@ using MegaCrit.Sts2.Core.Entities.Multiplayer;
|
|||||||
using MegaCrit.Sts2.Core.Multiplayer.Connection;
|
using MegaCrit.Sts2.Core.Multiplayer.Connection;
|
||||||
using MegaCrit.Sts2.Core.Multiplayer.Game;
|
using MegaCrit.Sts2.Core.Multiplayer.Game;
|
||||||
using MegaCrit.Sts2.Core.Multiplayer.Messages.Lobby;
|
using MegaCrit.Sts2.Core.Multiplayer.Messages.Lobby;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Models;
|
using SlayTheSpire2.LAN.Multiplayer.Models;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable UnusedType.Global
|
// ReSharper disable UnusedType.Global
|
||||||
@@ -27,10 +27,12 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs
|
|||||||
if (joinFlow.NetService == null)
|
if (joinFlow.NetService == null)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
joinFlow.NetService.RegisterMessageHandler<LanPlayerNameResponseMessage>(LanPlayerNameHelper
|
var lanPlayerNameService = LanPlayerNameService.Instance;
|
||||||
|
|
||||||
|
joinFlow.NetService.RegisterMessageHandler<LanPlayerNameResponseMessage>(lanPlayerNameService
|
||||||
.HandleLanPlayerNameResponseMessage);
|
.HandleLanPlayerNameResponseMessage);
|
||||||
|
|
||||||
await LanPlayerNameHelper.AttemptPlayerName(joinFlow.NetService);
|
await lanPlayerNameService.AttemptPlayerName(joinFlow.NetService);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -52,10 +54,12 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs
|
|||||||
if (joinFlow.NetService == null)
|
if (joinFlow.NetService == null)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
joinFlow.NetService.RegisterMessageHandler<LanPlayerNameResponseMessage>(LanPlayerNameHelper
|
var lanPlayerNameService = LanPlayerNameService.Instance;
|
||||||
|
|
||||||
|
joinFlow.NetService.RegisterMessageHandler<LanPlayerNameResponseMessage>(lanPlayerNameService
|
||||||
.HandleLanPlayerNameResponseMessage);
|
.HandleLanPlayerNameResponseMessage);
|
||||||
|
|
||||||
await LanPlayerNameHelper.AttemptPlayerName(joinFlow.NetService);
|
await lanPlayerNameService.AttemptPlayerName(joinFlow.NetService);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -77,10 +81,12 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs
|
|||||||
if (joinFlow.NetService == null)
|
if (joinFlow.NetService == null)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
joinFlow.NetService.RegisterMessageHandler<LanPlayerNameResponseMessage>(LanPlayerNameHelper
|
var lanPlayerNameService = LanPlayerNameService.Instance;
|
||||||
|
|
||||||
|
joinFlow.NetService.RegisterMessageHandler<LanPlayerNameResponseMessage>(lanPlayerNameService
|
||||||
.HandleLanPlayerNameResponseMessage);
|
.HandleLanPlayerNameResponseMessage);
|
||||||
|
|
||||||
await LanPlayerNameHelper.AttemptPlayerName(joinFlow.NetService);
|
await lanPlayerNameService.AttemptPlayerName(joinFlow.NetService);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -95,7 +101,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs
|
|||||||
new ClientConnectionFailedException(
|
new ClientConnectionFailedException(
|
||||||
$"Unexpectedly disconnected from host while joining. Reason: {info.GetReason()}", info);
|
$"Unexpectedly disconnected from host while joining. Reason: {info.GetReason()}", info);
|
||||||
|
|
||||||
var lanPlayerNameCompletion = LanPlayerNameHelper.LanPlayerNameCompletion;
|
var lanPlayerNameCompletion = LanPlayerNameService.Instance.LanPlayerNameCompletion;
|
||||||
|
|
||||||
if (lanPlayerNameCompletion?.Task is { IsCompleted: false })
|
if (lanPlayerNameCompletion?.Task is { IsCompleted: false })
|
||||||
{
|
{
|
||||||
@@ -109,7 +115,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs
|
|||||||
{
|
{
|
||||||
private static void Postfix()
|
private static void Postfix()
|
||||||
{
|
{
|
||||||
var lanPlayerNameCompletion = LanPlayerNameHelper.LanPlayerNameCompletion;
|
var lanPlayerNameCompletion = LanPlayerNameService.Instance.LanPlayerNameCompletion;
|
||||||
|
|
||||||
if (lanPlayerNameCompletion?.Task is { IsCompleted: false })
|
if (lanPlayerNameCompletion?.Task is { IsCompleted: false })
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MegaCrit.Sts2.Core.Platform.Null;
|
using MegaCrit.Sts2.Core.Platform.Null;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable UnusedType.Global
|
// ReSharper disable UnusedType.Global
|
||||||
@@ -24,7 +24,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LanPlayerNameHelper.PlayerNameDictionary.TryGetValue(playerId, out var playerName))
|
if (LanPlayerNameService.Instance.PlayerNames.TryGetValue(playerId, out var playerName))
|
||||||
{
|
{
|
||||||
__result = playerName;
|
__result = playerName;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ using MegaCrit.Sts2.Core.Multiplayer.Game.Lobby;
|
|||||||
using MegaCrit.Sts2.Core.Platform;
|
using MegaCrit.Sts2.Core.Platform;
|
||||||
using MegaCrit.Sts2.Core.Runs;
|
using MegaCrit.Sts2.Core.Runs;
|
||||||
using MegaCrit.Sts2.Core.Saves;
|
using MegaCrit.Sts2.Core.Saves;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Models;
|
using SlayTheSpire2.LAN.Multiplayer.Models;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable UnusedType.Global
|
// ReSharper disable UnusedType.Global
|
||||||
@@ -34,14 +34,16 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs
|
|||||||
{
|
{
|
||||||
if (netService.Platform == PlatformType.None)
|
if (netService.Platform == PlatformType.None)
|
||||||
{
|
{
|
||||||
LanPlayerNameHelper.NetService = netService;
|
var lanPlayerNameService = LanPlayerNameService.Instance;
|
||||||
|
|
||||||
netService.RegisterMessageHandler<LanPlayerNameResponseMessage>(LanPlayerNameHelper
|
lanPlayerNameService.NetService = netService;
|
||||||
|
|
||||||
|
netService.RegisterMessageHandler<LanPlayerNameResponseMessage>(lanPlayerNameService
|
||||||
.HandleLanPlayerNameResponseMessage);
|
.HandleLanPlayerNameResponseMessage);
|
||||||
|
|
||||||
if (netService.Type == NetGameType.Host)
|
if (netService.Type == NetGameType.Host)
|
||||||
{
|
{
|
||||||
netService.RegisterMessageHandler<LanPlayerNameRequestMessage>(LanPlayerNameHelper
|
netService.RegisterMessageHandler<LanPlayerNameRequestMessage>(lanPlayerNameService
|
||||||
.HandleLanPlayerNameRequestMessage);
|
.HandleLanPlayerNameRequestMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,30 +55,57 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs
|
|||||||
{
|
{
|
||||||
private static IEnumerable<MethodBase> TargetMethods()
|
private static IEnumerable<MethodBase> TargetMethods()
|
||||||
{
|
{
|
||||||
yield return typeof(StartRunLobby).GetMethod("CleanUp", BindingFlags.Instance | BindingFlags.Public)!;
|
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
|
||||||
yield return typeof(RunLobby).GetMethod("Dispose", BindingFlags.Instance | BindingFlags.Public)!;
|
|
||||||
yield return typeof(LoadRunLobby).GetMethod("CleanUp", BindingFlags.Instance | BindingFlags.Public)!;
|
yield return typeof(StartRunLobby).GetMethod("CleanUp", flags)!;
|
||||||
|
yield return typeof(LoadRunLobby).GetMethod("CleanUp", flags)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Prefix(object __instance)
|
private static void Prefix(object __instance, bool disconnectSession)
|
||||||
{
|
{
|
||||||
var netService = __instance is StartRunLobby or LoadRunLobby
|
var netService = Traverse.Create(__instance).Property("NetService").GetValue<INetGameService>();
|
||||||
? Traverse.Create(__instance).Property("NetService").GetValue<INetGameService>()
|
|
||||||
: Traverse.Create(__instance).Field("_netService").GetValue<INetGameService>();
|
|
||||||
|
|
||||||
if (netService.Platform == PlatformType.None)
|
if (netService.Platform == PlatformType.None)
|
||||||
{
|
{
|
||||||
LanPlayerNameHelper.SetDefaultPlayerNameDictionary();
|
var lanPlayerNameService = LanPlayerNameService.Instance;
|
||||||
|
|
||||||
netService.UnregisterMessageHandler<LanPlayerNameResponseMessage>(LanPlayerNameHelper
|
if (disconnectSession)
|
||||||
|
{
|
||||||
|
lanPlayerNameService.SetDefaultPlayerNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
netService.UnregisterMessageHandler<LanPlayerNameResponseMessage>(lanPlayerNameService
|
||||||
.HandleLanPlayerNameResponseMessage);
|
.HandleLanPlayerNameResponseMessage);
|
||||||
|
|
||||||
if (netService.Type == NetGameType.Host)
|
if (netService.Type == NetGameType.Host)
|
||||||
{
|
{
|
||||||
netService.UnregisterMessageHandler<LanPlayerNameRequestMessage>(LanPlayerNameHelper
|
netService.UnregisterMessageHandler<LanPlayerNameRequestMessage>(lanPlayerNameService
|
||||||
|
.HandleLanPlayerNameRequestMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(RunLobby), "Dispose")]
|
||||||
|
internal class RunLobbyDisposePatch
|
||||||
|
{
|
||||||
|
private static void Prefix(INetGameService ____netService)
|
||||||
|
{
|
||||||
|
if (____netService.Platform == PlatformType.None)
|
||||||
|
{
|
||||||
|
var lanPlayerNameService = LanPlayerNameService.Instance;
|
||||||
|
|
||||||
|
lanPlayerNameService.SetDefaultPlayerNames();
|
||||||
|
|
||||||
|
____netService.UnregisterMessageHandler<LanPlayerNameResponseMessage>(lanPlayerNameService
|
||||||
|
.HandleLanPlayerNameResponseMessage);
|
||||||
|
|
||||||
|
if (____netService.Type == NetGameType.Host)
|
||||||
|
{
|
||||||
|
____netService.UnregisterMessageHandler<LanPlayerNameRequestMessage>(lanPlayerNameService
|
||||||
.HandleLanPlayerNameRequestMessage);
|
.HandleLanPlayerNameRequestMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MegaCrit.Sts2.Core.Runs;
|
using MegaCrit.Sts2.Core.Runs;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable UnusedType.Global
|
// ReSharper disable UnusedType.Global
|
||||||
@@ -12,8 +12,8 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs
|
|||||||
{
|
{
|
||||||
private static void Postfix()
|
private static void Postfix()
|
||||||
{
|
{
|
||||||
LanMapDrawingsHelper.DisableDrawingHashSet.Clear();
|
LanMapDrawingsService.Instance.DisableDrawingHashSet.Clear();
|
||||||
LanPlayerNameHelper.SetDefaultPlayerNameDictionary();
|
LanPlayerNameService.Instance.SetDefaultPlayerNames();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,8 +7,8 @@ using MegaCrit.Sts2.Core.Rooms;
|
|||||||
using MegaCrit.Sts2.Core.Runs;
|
using MegaCrit.Sts2.Core.Runs;
|
||||||
using MegaCrit.Sts2.Core.Saves;
|
using MegaCrit.Sts2.Core.Saves;
|
||||||
using MegaCrit.Sts2.Core.Saves.Managers;
|
using MegaCrit.Sts2.Core.Saves.Managers;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Models;
|
using SlayTheSpire2.LAN.Multiplayer.Models;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable UnusedType.Global
|
// ReSharper disable UnusedType.Global
|
||||||
@@ -42,7 +42,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs
|
|||||||
|
|
||||||
var savePath = isMultiplayer
|
var savePath = isMultiplayer
|
||||||
? isNonePlatform
|
? isNonePlatform
|
||||||
? LanRunSaveManagerHelper.CurrentMultiplayerRunSavePath
|
? LanRunSaveManagerService.Instance.CurrentMultiplayerRunSavePath
|
||||||
: Traverse.Create(runSaveManager).Property("CurrentMultiplayerRunSavePath").GetValue<string>()
|
: Traverse.Create(runSaveManager).Property("CurrentMultiplayerRunSavePath").GetValue<string>()
|
||||||
: Traverse.Create(runSaveManager).Property("CurrentRunSavePath").GetValue<string>();
|
: Traverse.Create(runSaveManager).Property("CurrentRunSavePath").GetValue<string>();
|
||||||
using var stream = new MemoryStream();
|
using var stream = new MemoryStream();
|
||||||
@@ -62,20 +62,22 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs
|
|||||||
|
|
||||||
if (isMultiplayer && isNonePlatform)
|
if (isMultiplayer && isNonePlatform)
|
||||||
{
|
{
|
||||||
|
var lanPlayerNameService = LanPlayerNameService.Instance;
|
||||||
|
|
||||||
using var playerNamesStream = new MemoryStream();
|
using var playerNamesStream = new MemoryStream();
|
||||||
if (!forceSynchronous)
|
if (!forceSynchronous)
|
||||||
{
|
{
|
||||||
await JsonSerializer.SerializeAsync(playerNamesStream, LanPlayerNameHelper.PlayerNameDictionary,
|
await JsonSerializer.SerializeAsync(playerNamesStream, lanPlayerNameService.PlayerNames,
|
||||||
LanPlayerNamesContext.Default.LanPlayerNames, CancellationToken.None);
|
PlayerNamesContext.Default.PlayerNames, CancellationToken.None);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await JsonSerializer.SerializeAsync(playerNamesStream, LanPlayerNameHelper.PlayerNameDictionary,
|
await JsonSerializer.SerializeAsync(playerNamesStream, lanPlayerNameService.PlayerNames,
|
||||||
LanPlayerNamesContext.Default.LanPlayerNames);
|
PlayerNamesContext.Default.PlayerNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
playerNamesStream.Seek(0L, SeekOrigin.Begin);
|
playerNamesStream.Seek(0L, SeekOrigin.Begin);
|
||||||
await saveStore.WriteFileAsync(LanRunSaveManagerHelper.CurrentMultiplayerRunPlayerNamesPath,
|
await saveStore.WriteFileAsync(LanRunSaveManagerService.Instance.CurrentMultiplayerRunPlayerNamesPath,
|
||||||
playerNamesStream.ToArray());
|
playerNamesStream.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using HarmonyLib;
|
|
||||||
using MegaCrit.Sts2.Core.Multiplayer.Game;
|
|
||||||
using MegaCrit.Sts2.Core.Nodes.Screens.CharacterSelect;
|
|
||||||
using MegaCrit.Sts2.Core.Platform;
|
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
|
||||||
// ReSharper disable UnusedType.Global
|
|
||||||
|
|
||||||
namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|
||||||
{
|
|
||||||
[HarmonyPatch]
|
|
||||||
internal class NCharacterSelectScreenInitializeMultiplayerPatchs
|
|
||||||
{
|
|
||||||
private static IEnumerable<MethodInfo> TargetMethods()
|
|
||||||
{
|
|
||||||
yield return typeof(NCharacterSelectScreen).GetMethod("InitializeMultiplayerAsClient",
|
|
||||||
BindingFlags.Instance | BindingFlags.Public)!;
|
|
||||||
yield return typeof(NCharacterSelectScreen).GetMethod("InitializeMultiplayerAsHost",
|
|
||||||
BindingFlags.Instance | BindingFlags.Public)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Prefix(NCharacterSelectScreen __instance, INetGameService gameService)
|
|
||||||
{
|
|
||||||
if (gameService.Platform == PlatformType.None)
|
|
||||||
{
|
|
||||||
LanPlayerNameHelper.CharacterSelectScreen = __instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ using MegaCrit.Sts2.Core.Multiplayer.Connection;
|
|||||||
using MegaCrit.Sts2.Core.Nodes.GodotExtensions;
|
using MegaCrit.Sts2.Core.Nodes.GodotExtensions;
|
||||||
using MegaCrit.Sts2.Core.Nodes.Screens.MainMenu;
|
using MegaCrit.Sts2.Core.Nodes.Screens.MainMenu;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Components;
|
using SlayTheSpire2.LAN.Multiplayer.Components;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable UnusedType.Global
|
// ReSharper disable UnusedType.Global
|
||||||
@@ -61,7 +61,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
|
|
||||||
vBoxContainer.AddChild(addressLineEdit);
|
vBoxContainer.AddChild(addressLineEdit);
|
||||||
|
|
||||||
addressLineEdit.Text = SettingsHelper.Instance.SettingsModel.IPAddress;
|
addressLineEdit.Text = SettingsService.Instance.SettingsModel.IPAddress;
|
||||||
addressLineEdit.Alignment = HorizontalAlignment.Center;
|
addressLineEdit.Alignment = HorizontalAlignment.Center;
|
||||||
addressLineEdit.CustomMinimumSize = new Vector2(300, 50);
|
addressLineEdit.CustomMinimumSize = new Vector2(300, 50);
|
||||||
addressLineEdit.SizeFlagsHorizontal = Control.SizeFlags.ShrinkCenter;
|
addressLineEdit.SizeFlagsHorizontal = Control.SizeFlags.ShrinkCenter;
|
||||||
@@ -83,8 +83,8 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
if (!addressInfo.IsValid)
|
if (!addressInfo.IsValid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SettingsHelper.Instance.SettingsModel.IPAddress = addressLineEdit.Text;
|
SettingsService.Instance.SettingsModel.IPAddress = addressLineEdit.Text;
|
||||||
SettingsHelper.Instance.WriteSettings();
|
SettingsService.Instance.WriteSettings();
|
||||||
|
|
||||||
ushort port = 33771;
|
ushort port = 33771;
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
{
|
{
|
||||||
TaskHelper.RunSafely(
|
TaskHelper.RunSafely(
|
||||||
__instance.JoinGameAsync(new ENetClientConnectionInitializer(
|
__instance.JoinGameAsync(new ENetClientConnectionInitializer(
|
||||||
SettingsHelper.Instance.SettingsModel.NetId, addressInfo.Address, port)));
|
SettingsService.Instance.SettingsModel.NetId, addressInfo.Address, port)));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using MegaCrit.Sts2.Core.Helpers;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.MainMenu;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Components;
|
||||||
|
|
||||||
|
// ReSharper disable UnusedMember.Global
|
||||||
|
// ReSharper disable UnusedType.Global
|
||||||
|
|
||||||
|
namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
||||||
|
{
|
||||||
|
[HarmonyPatch(typeof(NMainMenuSubmenuStack), "GetSubmenuType", typeof(Type))]
|
||||||
|
internal class NMainMenuSubmenuStackGetSubmenuTypePatch
|
||||||
|
{
|
||||||
|
private static bool Prefix(NMainMenuSubmenuStack __instance, Type type, ref NSubmenu __result)
|
||||||
|
{
|
||||||
|
if (type == typeof(LanMultiplayerHostSubmenu))
|
||||||
|
{
|
||||||
|
if (LanMultiplayerHostSubmenu.Instance == null)
|
||||||
|
{
|
||||||
|
var lanMultiplayerHostSubmenu = LanMultiplayerHostSubmenu.Create();
|
||||||
|
|
||||||
|
if (lanMultiplayerHostSubmenu != null)
|
||||||
|
{
|
||||||
|
lanMultiplayerHostSubmenu.Visible = false;
|
||||||
|
__instance.AddChildSafely(lanMultiplayerHostSubmenu);
|
||||||
|
|
||||||
|
__result = lanMultiplayerHostSubmenu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__result = LanMultiplayerHostSubmenu.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MegaCrit.Sts2.Core.Entities.Players;
|
using MegaCrit.Sts2.Core.Entities.Players;
|
||||||
using MegaCrit.Sts2.Core.Nodes.Screens.Map;
|
using MegaCrit.Sts2.Core.Nodes.Screens.Map;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable UnusedType.Global
|
// ReSharper disable UnusedType.Global
|
||||||
@@ -14,7 +14,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
{
|
{
|
||||||
private static void Postfix(Player player, Line2D __result)
|
private static void Postfix(Player player, Line2D __result)
|
||||||
{
|
{
|
||||||
if (LanMapDrawingsHelper.DisableDrawingHashSet.Contains(player.NetId))
|
if (LanMapDrawingsService.Instance.DisableDrawingHashSet.Contains(player.NetId))
|
||||||
{
|
{
|
||||||
__result.Visible = false;
|
__result.Visible = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using HarmonyLib;
|
|
||||||
using MegaCrit.Sts2.Core.Multiplayer.Game;
|
|
||||||
using MegaCrit.Sts2.Core.Nodes.Screens.CharacterSelect;
|
|
||||||
using MegaCrit.Sts2.Core.Platform;
|
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
|
||||||
// ReSharper disable UnusedType.Global
|
|
||||||
|
|
||||||
namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|
||||||
{
|
|
||||||
[HarmonyPatch]
|
|
||||||
internal class NMultiplayerLoadGameScreenInitializePatchs
|
|
||||||
{
|
|
||||||
private static IEnumerable<MethodInfo> TargetMethods()
|
|
||||||
{
|
|
||||||
yield return typeof(NMultiplayerLoadGameScreen).GetMethod("InitializeAsHost",
|
|
||||||
BindingFlags.Instance | BindingFlags.Public)!;
|
|
||||||
yield return typeof(NMultiplayerLoadGameScreen).GetMethod("InitializeAsClient",
|
|
||||||
BindingFlags.Instance | BindingFlags.Public)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Prefix(NMultiplayerLoadGameScreen __instance, INetGameService gameService)
|
|
||||||
{
|
|
||||||
if (gameService.Platform == PlatformType.None)
|
|
||||||
{
|
|
||||||
LanPlayerNameHelper.MultiplayerLoadGameScreen = __instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+16
-18
@@ -7,7 +7,7 @@ using MegaCrit.Sts2.Core.Nodes.Multiplayer;
|
|||||||
using MegaCrit.Sts2.Core.Nodes.Screens.CardLibrary;
|
using MegaCrit.Sts2.Core.Nodes.Screens.CardLibrary;
|
||||||
using MegaCrit.Sts2.Core.Nodes.Screens.Map;
|
using MegaCrit.Sts2.Core.Nodes.Screens.Map;
|
||||||
using MegaCrit.Sts2.Core.Runs;
|
using MegaCrit.Sts2.Core.Runs;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable UnusedType.Global
|
// ReSharper disable UnusedType.Global
|
||||||
@@ -21,32 +21,30 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
{
|
{
|
||||||
if (____player.NetId != RunManager.Instance.NetService.NetId)
|
if (____player.NetId != RunManager.Instance.NetService.NetId)
|
||||||
{
|
{
|
||||||
var lanPanel = new HBoxContainer { Name = "LANPanel" };
|
var container = __instance.GetNode("ScreenContents/Container");
|
||||||
__instance.AddChild(lanPanel);
|
|
||||||
|
|
||||||
lanPanel.AnchorLeft = 0.5f;
|
|
||||||
lanPanel.AnchorTop = 0;
|
|
||||||
lanPanel.AnchorRight = 0.5f;
|
|
||||||
lanPanel.AnchorBottom = 0;
|
|
||||||
|
|
||||||
lanPanel.OffsetLeft = -162;
|
|
||||||
lanPanel.OffsetTop = 100;
|
|
||||||
lanPanel.OffsetRight = 162;
|
|
||||||
lanPanel.OffsetBottom = 100;
|
|
||||||
|
|
||||||
var disableDrawing = PreloadManager.Cache
|
var disableDrawing = PreloadManager.Cache
|
||||||
.GetScene(SceneHelper.GetScenePath("screens/card_library/card_library_tickbox"))
|
.GetScene(SceneHelper.GetScenePath("screens/card_library/card_library_tickbox"))
|
||||||
.Instantiate<Control>();
|
.Instantiate<Control>();
|
||||||
|
|
||||||
if (disableDrawing is NLibraryStatTickbox cardLibraryTickBox)
|
if (disableDrawing is NLibraryStatTickbox cardLibraryTickBox &&
|
||||||
|
container.GetNode("MarginContainer") is MarginContainer marginContainer)
|
||||||
{
|
{
|
||||||
disableDrawing.Name = "DisableDrawing";
|
disableDrawing.Name = "DisableDrawing";
|
||||||
|
|
||||||
lanPanel.AddChild(cardLibraryTickBox);
|
container.AddChild(cardLibraryTickBox);
|
||||||
|
container.MoveChild(cardLibraryTickBox, 0);
|
||||||
|
|
||||||
|
marginContainer.RemoveThemeConstantOverride("margin_top");
|
||||||
|
|
||||||
|
cardLibraryTickBox.SizeFlagsHorizontal = Control.SizeFlags.ShrinkCenter;
|
||||||
|
|
||||||
cardLibraryTickBox.SetLabel("Disable drawing");
|
cardLibraryTickBox.SetLabel("Disable drawing");
|
||||||
|
|
||||||
cardLibraryTickBox.IsTicked = LanMapDrawingsHelper.DisableDrawingHashSet.Contains(____player.NetId);
|
var lanMapDrawingsService = LanMapDrawingsService.Instance;
|
||||||
|
|
||||||
|
cardLibraryTickBox.IsTicked =
|
||||||
|
lanMapDrawingsService.DisableDrawingHashSet.Contains(____player.NetId);
|
||||||
|
|
||||||
cardLibraryTickBox.Toggled += tickBox =>
|
cardLibraryTickBox.Toggled += tickBox =>
|
||||||
{
|
{
|
||||||
@@ -64,7 +62,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LanMapDrawingsHelper.DisableDrawingHashSet.Add(____player.NetId);
|
lanMapDrawingsService.DisableDrawingHashSet.Add(____player.NetId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -76,7 +74,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LanMapDrawingsHelper.DisableDrawingHashSet.Remove(____player.NetId);
|
lanMapDrawingsService.DisableDrawingHashSet.Remove(____player.NetId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ using MegaCrit.Sts2.Core.Helpers;
|
|||||||
using MegaCrit.Sts2.Core.Nodes.GodotExtensions;
|
using MegaCrit.Sts2.Core.Nodes.GodotExtensions;
|
||||||
using MegaCrit.Sts2.Core.Nodes.Screens.MainMenu;
|
using MegaCrit.Sts2.Core.Nodes.Screens.MainMenu;
|
||||||
using MegaCrit.Sts2.Core.Runs;
|
using MegaCrit.Sts2.Core.Runs;
|
||||||
|
using MegaCrit.Sts2.Core.Saves;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Components;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable UnusedType.Global
|
// ReSharper disable UnusedType.Global
|
||||||
@@ -30,11 +33,20 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
{
|
{
|
||||||
var traverse = Traverse.Create(__instance);
|
var traverse = Traverse.Create(__instance);
|
||||||
|
|
||||||
var settingsModel = SettingsHelper.Instance.SettingsModel;
|
var settingsModel = SettingsService.Instance.SettingsModel;
|
||||||
|
|
||||||
LanHostHelper.StartHost(GameMode.Standard, traverse.Field("_loadingOverlay").GetValue<Control>(),
|
var stack = traverse.Field("_stack").GetValue<NSubmenuStack>();
|
||||||
traverse.Field("_stack").GetValue<NSubmenuStack>(),
|
|
||||||
settingsModel.HostPort, settingsModel.HostMaxPlayers);
|
if (SaveManager.Instance.Progress.NumberOfRuns > 0)
|
||||||
|
{
|
||||||
|
stack.PushSubmenuType<LanMultiplayerHostSubmenu>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LanHostHelper.StartHost(GameMode.Standard,
|
||||||
|
traverse.Field("_loadingOverlay").GetValue<Control>(), stack, settingsModel.HostPort,
|
||||||
|
settingsModel.HostMaxPlayers);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
lanHostButton.SetIconAndLocalization("HOST");
|
lanHostButton.SetIconAndLocalization("HOST");
|
||||||
var lanHostTitle = Traverse.Create(lanHostButton).Field("_title").GetValue<MegaLabel>();
|
var lanHostTitle = Traverse.Create(lanHostButton).Field("_title").GetValue<MegaLabel>();
|
||||||
@@ -42,7 +54,9 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
|
|
||||||
NSubmenuButtonDuplicateMaterial(lanHostButton);
|
NSubmenuButtonDuplicateMaterial(lanHostButton);
|
||||||
|
|
||||||
NMultiplayerSubmenuButtonHelpers.LanHostButton = lanHostButton;
|
var lanMultiplayerSubmenuButtonService = LanMultiplayerSubmenuButtonService.Instance;
|
||||||
|
|
||||||
|
lanMultiplayerSubmenuButtonService.LanHostButton = lanHostButton;
|
||||||
|
|
||||||
if (buttonContainerNode.GetNode("LoadButton").Duplicate() is not NSubmenuButton lanLoadButton)
|
if (buttonContainerNode.GetNode("LoadButton").Duplicate() is not NSubmenuButton lanLoadButton)
|
||||||
return;
|
return;
|
||||||
@@ -55,7 +69,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
{
|
{
|
||||||
var traverse = Traverse.Create(__instance);
|
var traverse = Traverse.Create(__instance);
|
||||||
|
|
||||||
var settingsModel = SettingsHelper.Instance.SettingsModel;
|
var settingsModel = SettingsService.Instance.SettingsModel;
|
||||||
|
|
||||||
LanHostHelper.StartLoad(lanLoadButton, traverse.Field("_loadingOverlay").GetValue<Control>(),
|
LanHostHelper.StartLoad(lanLoadButton, traverse.Field("_loadingOverlay").GetValue<Control>(),
|
||||||
traverse.Field("_stack").GetValue<NSubmenuStack>(),
|
traverse.Field("_stack").GetValue<NSubmenuStack>(),
|
||||||
@@ -67,7 +81,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
|
|
||||||
NSubmenuButtonDuplicateMaterial(lanLoadButton);
|
NSubmenuButtonDuplicateMaterial(lanLoadButton);
|
||||||
|
|
||||||
NMultiplayerSubmenuButtonHelpers.LanLoadButton = lanLoadButton;
|
lanMultiplayerSubmenuButtonService.LanLoadButton = lanLoadButton;
|
||||||
|
|
||||||
if (buttonContainerNode.GetNode("AbandonButton").Duplicate() is not NSubmenuButton lanAbandonButton)
|
if (buttonContainerNode.GetNode("AbandonButton").Duplicate() is not NSubmenuButton lanAbandonButton)
|
||||||
return;
|
return;
|
||||||
@@ -89,7 +103,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
|
|
||||||
NSubmenuButtonDuplicateMaterial(lanAbandonButton);
|
NSubmenuButtonDuplicateMaterial(lanAbandonButton);
|
||||||
|
|
||||||
NMultiplayerSubmenuButtonHelpers.LanAbandonButton = lanAbandonButton;
|
lanMultiplayerSubmenuButtonService.LanAbandonButton = lanAbandonButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void NSubmenuButtonDuplicateMaterial(NSubmenuButton nSubmenuButton)
|
private static void NSubmenuButtonDuplicateMaterial(NSubmenuButton nSubmenuButton)
|
||||||
@@ -108,20 +122,24 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
{
|
{
|
||||||
private static void Postfix()
|
private static void Postfix()
|
||||||
{
|
{
|
||||||
if (NMultiplayerSubmenuButtonHelpers.LanHostButton != null)
|
var lanMultiplayerSubmenuButtonService = LanMultiplayerSubmenuButtonService.Instance;
|
||||||
|
|
||||||
|
if (lanMultiplayerSubmenuButtonService.LanHostButton != null)
|
||||||
{
|
{
|
||||||
NMultiplayerSubmenuButtonHelpers.LanHostButton.Visible = !LanRunSaveManagerHelper.HasMultiplayerRunSave;
|
lanMultiplayerSubmenuButtonService.LanHostButton.Visible =
|
||||||
|
!LanRunSaveManagerService.Instance.HasMultiplayerRunSave;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NMultiplayerSubmenuButtonHelpers.LanLoadButton != null)
|
if (lanMultiplayerSubmenuButtonService.LanLoadButton != null)
|
||||||
{
|
{
|
||||||
NMultiplayerSubmenuButtonHelpers.LanLoadButton.Visible = LanRunSaveManagerHelper.HasMultiplayerRunSave;
|
lanMultiplayerSubmenuButtonService.LanLoadButton.Visible =
|
||||||
|
LanRunSaveManagerService.Instance.HasMultiplayerRunSave;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NMultiplayerSubmenuButtonHelpers.LanAbandonButton != null)
|
if (lanMultiplayerSubmenuButtonService.LanAbandonButton != null)
|
||||||
{
|
{
|
||||||
NMultiplayerSubmenuButtonHelpers.LanAbandonButton.Visible =
|
lanMultiplayerSubmenuButtonService.LanAbandonButton.Visible =
|
||||||
LanRunSaveManagerHelper.HasMultiplayerRunSave;
|
LanRunSaveManagerService.Instance.HasMultiplayerRunSave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using MegaCrit.Sts2.Core.Nodes.Screens.Settings;
|
using MegaCrit.Sts2.Core.Nodes.Screens.Settings;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Components;
|
using SlayTheSpire2.LAN.Multiplayer.Components;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Helpers;
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable UnusedType.Global
|
// ReSharper disable UnusedType.Global
|
||||||
@@ -50,11 +50,11 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
hostPortLineEdit.Step = 1;
|
hostPortLineEdit.Step = 1;
|
||||||
hostPortLineEdit.MinValue = 0;
|
hostPortLineEdit.MinValue = 0;
|
||||||
hostPortLineEdit.MaxValue = 65535;
|
hostPortLineEdit.MaxValue = 65535;
|
||||||
hostPortLineEdit.Value = SettingsHelper.Instance.SettingsModel.HostPort;
|
hostPortLineEdit.Value = SettingsService.Instance.SettingsModel.HostPort;
|
||||||
hostPortLineEdit.ValueChanged += value =>
|
hostPortLineEdit.ValueChanged += value =>
|
||||||
{
|
{
|
||||||
SettingsHelper.Instance.SettingsModel.HostPort = (ushort)value;
|
SettingsService.Instance.SettingsModel.HostPort = (ushort)value;
|
||||||
SettingsHelper.Instance.WriteSettings();
|
SettingsService.Instance.WriteSettings();
|
||||||
};
|
};
|
||||||
|
|
||||||
hostPortLabel.Text = "Host Port";
|
hostPortLabel.Text = "Host Port";
|
||||||
@@ -90,11 +90,11 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
|
|
||||||
hostMaxPlayersInput.Step = 1;
|
hostMaxPlayersInput.Step = 1;
|
||||||
hostMaxPlayersInput.MinValue = 2;
|
hostMaxPlayersInput.MinValue = 2;
|
||||||
hostMaxPlayersInput.Value = SettingsHelper.Instance.SettingsModel.HostMaxPlayers;
|
hostMaxPlayersInput.Value = SettingsService.Instance.SettingsModel.HostMaxPlayers;
|
||||||
hostMaxPlayersInput.ValueChanged += value =>
|
hostMaxPlayersInput.ValueChanged += value =>
|
||||||
{
|
{
|
||||||
SettingsHelper.Instance.SettingsModel.HostMaxPlayers = (int)value;
|
SettingsService.Instance.SettingsModel.HostMaxPlayers = (int)value;
|
||||||
SettingsHelper.Instance.WriteSettings();
|
SettingsService.Instance.WriteSettings();
|
||||||
};
|
};
|
||||||
|
|
||||||
hostMaxPlayersLabel.Text = "Host Max Players";
|
hostMaxPlayersLabel.Text = "Host Max Players";
|
||||||
@@ -129,14 +129,14 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
playerNameInput.Alignment = HorizontalAlignment.Center;
|
playerNameInput.Alignment = HorizontalAlignment.Center;
|
||||||
|
|
||||||
playerNameInput.MaxLength = 16;
|
playerNameInput.MaxLength = 16;
|
||||||
playerNameInput.Text = SettingsHelper.Instance.SettingsModel.PlayerName;
|
playerNameInput.Text = SettingsService.Instance.SettingsModel.PlayerName;
|
||||||
playerNameInput.TextChanged += value =>
|
playerNameInput.TextChanged += value =>
|
||||||
{
|
{
|
||||||
if (playerNameInput.IsEmpty || !playerNameInput.IsInvalid)
|
if (playerNameInput.IsEmpty || !playerNameInput.IsInvalid)
|
||||||
{
|
{
|
||||||
SettingsHelper.Instance.SettingsModel.PlayerName = value;
|
SettingsService.Instance.SettingsModel.PlayerName = value;
|
||||||
LanPlayerNameHelper.SetHostPlayerName();
|
LanPlayerNameService.Instance.SetHostPlayerName();
|
||||||
SettingsHelper.Instance.WriteSettings();
|
SettingsService.Instance.WriteSettings();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -174,11 +174,11 @@ namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
|||||||
netIdInput.Step = 1;
|
netIdInput.Step = 1;
|
||||||
netIdInput.MinValue = 2;
|
netIdInput.MinValue = 2;
|
||||||
netIdInput.MaxValue = ulong.MaxValue;
|
netIdInput.MaxValue = ulong.MaxValue;
|
||||||
netIdInput.Value = SettingsHelper.Instance.SettingsModel.NetId;
|
netIdInput.Value = SettingsService.Instance.SettingsModel.NetId;
|
||||||
netIdInput.ValueChanged += value =>
|
netIdInput.ValueChanged += value =>
|
||||||
{
|
{
|
||||||
SettingsHelper.Instance.SettingsModel.NetId = (ulong)value;
|
SettingsService.Instance.SettingsModel.NetId = (ulong)value;
|
||||||
SettingsHelper.Instance.WriteSettings();
|
SettingsService.Instance.WriteSettings();
|
||||||
};
|
};
|
||||||
|
|
||||||
netIdLabel.Text = "NetID";
|
netIdLabel.Text = "NetID";
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using HarmonyLib;
|
||||||
|
using MegaCrit.Sts2.Core.Multiplayer.Game;
|
||||||
|
using MegaCrit.Sts2.Core.Multiplayer.Game.Lobby;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.CharacterSelect;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.CustomRun;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.DailyRun;
|
||||||
|
using MegaCrit.Sts2.Core.Platform;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
|
// ReSharper disable UnusedMember.Global
|
||||||
|
// ReSharper disable UnusedType.Global
|
||||||
|
|
||||||
|
namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
||||||
|
{
|
||||||
|
[HarmonyPatch]
|
||||||
|
internal class RunLoadScreenInitializePatchs
|
||||||
|
{
|
||||||
|
private static IEnumerable<MethodInfo> TargetMethods()
|
||||||
|
{
|
||||||
|
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
|
||||||
|
|
||||||
|
yield return typeof(NMultiplayerLoadGameScreen).GetMethod("InitializeAsHost", flags)!;
|
||||||
|
yield return typeof(NMultiplayerLoadGameScreen).GetMethod("InitializeAsClient", flags)!;
|
||||||
|
yield return typeof(NDailyRunLoadScreen).GetMethod("InitializeAsHost", flags)!;
|
||||||
|
yield return typeof(NDailyRunLoadScreen).GetMethod("InitializeAsClient", flags)!;
|
||||||
|
yield return typeof(NCustomRunLoadScreen).GetMethod("InitializeAsHost", flags)!;
|
||||||
|
yield return typeof(NCustomRunLoadScreen).GetMethod("InitializeAsClient", flags)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Prefix(object __instance, INetGameService gameService)
|
||||||
|
{
|
||||||
|
if (gameService.Platform == PlatformType.None)
|
||||||
|
{
|
||||||
|
var runScreenService = RunScreenService.Instance;
|
||||||
|
|
||||||
|
switch (__instance)
|
||||||
|
{
|
||||||
|
case NMultiplayerLoadGameScreen multiplayerLoadGameScreen:
|
||||||
|
runScreenService.MultiplayerLoadGameScreen = multiplayerLoadGameScreen;
|
||||||
|
break;
|
||||||
|
case NDailyRunLoadScreen dailyRunLoadScreen:
|
||||||
|
runScreenService.DailyRunLoadScreen = dailyRunLoadScreen;
|
||||||
|
break;
|
||||||
|
case NCustomRunLoadScreen customRunLoadScreen:
|
||||||
|
runScreenService.CustomRunLoadScreen = customRunLoadScreen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
internal class RunLoadScreenShouldAllowRunToBeginPatchs
|
||||||
|
{
|
||||||
|
private static IEnumerable<MethodInfo> TargetMethods()
|
||||||
|
{
|
||||||
|
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
|
||||||
|
|
||||||
|
yield return typeof(NDailyRunLoadScreen).GetMethod("ShouldAllowRunToBegin", flags)!;
|
||||||
|
yield return typeof(NCustomRunLoadScreen).GetMethod("ShouldAllowRunToBegin", flags)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool Prefix(LoadRunLobby ____lobby, ref Task<bool> __result)
|
||||||
|
{
|
||||||
|
if (____lobby.NetService.Platform == PlatformType.None)
|
||||||
|
{
|
||||||
|
__result = RunScreenService.ShouldAllowRunToBegin(____lobby);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(NMultiplayerLoadGameScreen), "ShouldAllowRunToBegin")]
|
||||||
|
internal class RunLoadScreenShouldAllowRunToBeginPatch
|
||||||
|
{
|
||||||
|
private static bool Prefix(LoadRunLobby ____runLobby, ref Task<bool> __result)
|
||||||
|
{
|
||||||
|
if (____runLobby.NetService.Platform == PlatformType.None)
|
||||||
|
{
|
||||||
|
__result = RunScreenService.ShouldAllowRunToBegin(____runLobby);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using HarmonyLib;
|
||||||
|
using MegaCrit.Sts2.Core.Multiplayer.Game;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.CharacterSelect;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.CustomRun;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.DailyRun;
|
||||||
|
using MegaCrit.Sts2.Core.Platform;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Services;
|
||||||
|
|
||||||
|
// ReSharper disable UnusedMember.Global
|
||||||
|
// ReSharper disable UnusedType.Global
|
||||||
|
|
||||||
|
namespace SlayTheSpire2.LAN.Multiplayer.Patchs.Screens
|
||||||
|
{
|
||||||
|
[HarmonyPatch]
|
||||||
|
internal class RunScreenInitializePatchs
|
||||||
|
{
|
||||||
|
private static IEnumerable<MethodInfo> TargetMethods()
|
||||||
|
{
|
||||||
|
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
|
||||||
|
|
||||||
|
yield return typeof(NCharacterSelectScreen).GetMethod("InitializeMultiplayerAsClient", flags)!;
|
||||||
|
yield return typeof(NCharacterSelectScreen).GetMethod("InitializeMultiplayerAsHost", flags)!;
|
||||||
|
yield return typeof(NDailyRunScreen).GetMethod("InitializeMultiplayerAsClient", flags)!;
|
||||||
|
yield return typeof(NDailyRunScreen).GetMethod("InitializeMultiplayerAsHost", flags)!;
|
||||||
|
yield return typeof(NCustomRunScreen).GetMethod("InitializeMultiplayerAsClient", flags)!;
|
||||||
|
yield return typeof(NCustomRunScreen).GetMethod("InitializeMultiplayerAsHost", flags)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Prefix(object __instance, INetGameService gameService)
|
||||||
|
{
|
||||||
|
if (gameService.Platform == PlatformType.None)
|
||||||
|
{
|
||||||
|
var runScreenService = RunScreenService.Instance;
|
||||||
|
|
||||||
|
switch (__instance)
|
||||||
|
{
|
||||||
|
case NCharacterSelectScreen characterSelectScreen:
|
||||||
|
runScreenService.CharacterSelectScreen = characterSelectScreen;
|
||||||
|
break;
|
||||||
|
case NDailyRunScreen dailyRunScreen:
|
||||||
|
runScreenService.DailyRunScreen = dailyRunScreen;
|
||||||
|
break;
|
||||||
|
case NCustomRunScreen customRunScreen:
|
||||||
|
runScreenService.CustomRunScreen = customRunScreen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// ReSharper disable ClassNeverInstantiated.Global
|
||||||
|
|
||||||
|
namespace SlayTheSpire2.LAN.Multiplayer.Services
|
||||||
|
{
|
||||||
|
internal class LanMapDrawingsService
|
||||||
|
{
|
||||||
|
private static readonly Lazy<LanMapDrawingsService> Lazy = new(() => new LanMapDrawingsService());
|
||||||
|
|
||||||
|
public static LanMapDrawingsService Instance => Lazy.Value;
|
||||||
|
|
||||||
|
public readonly HashSet<ulong> DisableDrawingHashSet = [];
|
||||||
|
|
||||||
|
private LanMapDrawingsService()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.MainMenu;
|
||||||
|
|
||||||
|
// ReSharper disable ClassNeverInstantiated.Global
|
||||||
|
|
||||||
|
namespace SlayTheSpire2.LAN.Multiplayer.Services
|
||||||
|
{
|
||||||
|
internal class LanMultiplayerSubmenuButtonService
|
||||||
|
{
|
||||||
|
private static readonly Lazy<LanMultiplayerSubmenuButtonService> Lazy = new(() =>
|
||||||
|
new LanMultiplayerSubmenuButtonService());
|
||||||
|
|
||||||
|
public static LanMultiplayerSubmenuButtonService Instance => Lazy.Value;
|
||||||
|
|
||||||
|
public NSubmenuButton? LanHostButton;
|
||||||
|
public NSubmenuButton? LanLoadButton;
|
||||||
|
public NSubmenuButton? LanAbandonButton;
|
||||||
|
|
||||||
|
private LanMultiplayerSubmenuButtonService()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
using Godot;
|
||||||
|
using HarmonyLib;
|
||||||
|
using MegaCrit.Sts2.addons.mega_text;
|
||||||
|
using MegaCrit.Sts2.Core.Multiplayer;
|
||||||
|
using MegaCrit.Sts2.Core.Multiplayer.Game;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Multiplayer;
|
||||||
|
using MegaCrit.Sts2.Core.Platform;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Components;
|
||||||
|
using SlayTheSpire2.LAN.Multiplayer.Models;
|
||||||
|
|
||||||
|
// ReSharper disable ClassNeverInstantiated.Global
|
||||||
|
|
||||||
|
namespace SlayTheSpire2.LAN.Multiplayer.Services
|
||||||
|
{
|
||||||
|
internal class LanPlayerNameService
|
||||||
|
{
|
||||||
|
private static readonly Lazy<LanPlayerNameService> Lazy = new(() => new LanPlayerNameService());
|
||||||
|
|
||||||
|
public static LanPlayerNameService Instance => Lazy.Value;
|
||||||
|
|
||||||
|
public PlayerNames PlayerNames = GetDefaultPlayerNames();
|
||||||
|
|
||||||
|
public INetGameService? NetService;
|
||||||
|
|
||||||
|
public TaskCompletionSource<LanPlayerNameResponseMessage>? LanPlayerNameCompletion;
|
||||||
|
|
||||||
|
private LanPlayerNameService()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetHostPlayerName()
|
||||||
|
{
|
||||||
|
if (!PlayerNameLineEdit.GetPlayerNameIsInvalid(SettingsService.Instance.SettingsModel.PlayerName))
|
||||||
|
{
|
||||||
|
PlayerNames[1u] = SettingsService.Instance.SettingsModel.PlayerName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlayerNames.Remove(1u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetDefaultPlayerNames()
|
||||||
|
{
|
||||||
|
PlayerNames = GetDefaultPlayerNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PlayerNames GetDefaultPlayerNames()
|
||||||
|
{
|
||||||
|
return !PlayerNameLineEdit.GetPlayerNameIsInvalid(SettingsService.Instance.SettingsModel.PlayerName)
|
||||||
|
? new PlayerNames { { 1u, SettingsService.Instance.SettingsModel.PlayerName } }
|
||||||
|
: new PlayerNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HandleLanPlayerNameResponseMessage(LanPlayerNameResponseMessage lanPlayerNameResponseMessage,
|
||||||
|
ulong senderId)
|
||||||
|
{
|
||||||
|
PlayerNames = lanPlayerNameResponseMessage.playerNames;
|
||||||
|
|
||||||
|
UpdatePlayerName();
|
||||||
|
|
||||||
|
LanPlayerNameCompletion?.SetResult(lanPlayerNameResponseMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HandleLanPlayerNameRequestMessage(LanPlayerNameRequestMessage lanPlayerNameRequestMessage,
|
||||||
|
ulong senderId)
|
||||||
|
{
|
||||||
|
if (PlayerNameLineEdit.GetPlayerNameIsInvalid(lanPlayerNameRequestMessage.playerName))
|
||||||
|
{
|
||||||
|
NetService?.SendMessage(
|
||||||
|
new LanPlayerNameResponseMessage { playerNames = PlayerNames }, senderId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerNames[senderId] = lanPlayerNameRequestMessage.playerName;
|
||||||
|
|
||||||
|
UpdatePlayerName();
|
||||||
|
|
||||||
|
NetService?.SendMessage(new LanPlayerNameResponseMessage { playerNames = PlayerNames });
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AttemptPlayerName(NetClientGameService gameService)
|
||||||
|
{
|
||||||
|
LanPlayerNameCompletion = new TaskCompletionSource<LanPlayerNameResponseMessage>();
|
||||||
|
var message = new LanPlayerNameRequestMessage
|
||||||
|
{ playerName = SettingsService.Instance.SettingsModel.PlayerName };
|
||||||
|
gameService.SendMessage(message);
|
||||||
|
await LanPlayerNameCompletion.Task;
|
||||||
|
LanPlayerNameCompletion = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdatePlayerName()
|
||||||
|
{
|
||||||
|
var runScreenService = RunScreenService.Instance;
|
||||||
|
|
||||||
|
if (runScreenService.CharacterSelectScreen != null)
|
||||||
|
{
|
||||||
|
UpdateNameplateLabel(runScreenService.CharacterSelectScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runScreenService.DailyRunScreen != null)
|
||||||
|
{
|
||||||
|
UpdateNameplateLabel(runScreenService.DailyRunScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runScreenService.CustomRunScreen != null)
|
||||||
|
{
|
||||||
|
UpdateNameplateLabel(runScreenService.CustomRunScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runScreenService.MultiplayerLoadGameScreen != null)
|
||||||
|
{
|
||||||
|
UpdateNameplateLabel(runScreenService.MultiplayerLoadGameScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runScreenService.DailyRunLoadScreen != null)
|
||||||
|
{
|
||||||
|
UpdateNameplateLabel(runScreenService.DailyRunLoadScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runScreenService.CustomRunLoadScreen != null)
|
||||||
|
{
|
||||||
|
UpdateNameplateLabel(runScreenService.CustomRunLoadScreen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateNameplateLabel(Control container)
|
||||||
|
{
|
||||||
|
var nodes = Traverse.Create(container).Field("_remotePlayerContainer")
|
||||||
|
.Field("_nodes").GetValue<List<NRemoteLobbyPlayer>>();
|
||||||
|
|
||||||
|
foreach (var node in nodes)
|
||||||
|
{
|
||||||
|
var megaLabel = Traverse.Create(node).Field("_nameplateLabel").GetValue<MegaLabel>();
|
||||||
|
|
||||||
|
if (!GodotObject.IsInstanceValid(megaLabel))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
megaLabel.SetTextAutoSize(PlatformUtil.GetPlayerName(PlatformType.None, node.PlayerId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+27
-17
@@ -7,45 +7,55 @@ using MegaCrit.Sts2.Core.Saves.Managers;
|
|||||||
using MegaCrit.Sts2.Core.Saves.Migrations;
|
using MegaCrit.Sts2.Core.Saves.Migrations;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Models;
|
using SlayTheSpire2.LAN.Multiplayer.Models;
|
||||||
|
|
||||||
|
// ReSharper disable MemberCanBeMadeStatic.Local
|
||||||
// ReSharper disable MemberCanBePrivate.Global
|
// ReSharper disable MemberCanBePrivate.Global
|
||||||
// ReSharper disable ClassNeverInstantiated.Global
|
// ReSharper disable ClassNeverInstantiated.Global
|
||||||
|
|
||||||
namespace SlayTheSpire2.LAN.Multiplayer.Helpers
|
namespace SlayTheSpire2.LAN.Multiplayer.Services
|
||||||
{
|
{
|
||||||
internal class LanRunSaveManagerHelper
|
internal class LanRunSaveManagerService
|
||||||
{
|
{
|
||||||
public static ISaveStore SaveStore =>
|
private static readonly Lazy<LanRunSaveManagerService> Lazy = new(() => new LanRunSaveManagerService());
|
||||||
Traverse.Create(SaveManager.Instance).Field("_saveStore").GetValue<ISaveStore>();
|
|
||||||
|
|
||||||
public static MigrationManager MigrationManager => Traverse.Create(SaveManager.Instance)
|
public static LanRunSaveManagerService Instance => Lazy.Value;
|
||||||
.Field("_migrationManager").GetValue<MigrationManager>();
|
|
||||||
|
|
||||||
public static IProfileIdProvider ProfileIdProvider => SaveManager.Instance;
|
private SaveManager ProfileIdProvider => SaveManager.Instance;
|
||||||
|
|
||||||
public static string CurrentMultiplayerRunSavePath =>
|
private ISaveStore SaveStore => Traverse.Create(ProfileIdProvider).Field("_saveStore").GetValue<ISaveStore>();
|
||||||
|
|
||||||
|
private MigrationManager MigrationManager => Traverse.Create(ProfileIdProvider).Field("_migrationManager")
|
||||||
|
.GetValue<MigrationManager>();
|
||||||
|
|
||||||
|
public string CurrentMultiplayerRunSavePath =>
|
||||||
RunSaveManager.GetRunSavePath(ProfileIdProvider.CurrentProfileId, "current_lan_run_mp.save");
|
RunSaveManager.GetRunSavePath(ProfileIdProvider.CurrentProfileId, "current_lan_run_mp.save");
|
||||||
|
|
||||||
public static string CurrentMultiplayerRunPlayerNamesPath =>
|
public string CurrentMultiplayerRunPlayerNamesPath =>
|
||||||
RunSaveManager.GetRunSavePath(ProfileIdProvider.CurrentProfileId, "current_lan_run_mp_player_names.json");
|
RunSaveManager.GetRunSavePath(ProfileIdProvider.CurrentProfileId, "current_lan_run_mp_player_names.json");
|
||||||
|
|
||||||
public static bool HasMultiplayerRunSave => SaveStore.FileExists(CurrentMultiplayerRunSavePath);
|
public bool HasMultiplayerRunSave => SaveStore.FileExists(CurrentMultiplayerRunSavePath);
|
||||||
|
|
||||||
public static ReadSaveResult<SerializableRun> LoadAndCanonicalizeMultiplayerRunSave(ulong localPlayerId)
|
private LanRunSaveManagerService()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReadSaveResult<SerializableRun> LoadAndCanonicalizeMultiplayerRunSave(ulong localPlayerId)
|
||||||
{
|
{
|
||||||
var readSaveResult = LoadMultiplayerRunSave();
|
var readSaveResult = LoadMultiplayerRunSave();
|
||||||
if (readSaveResult is { Success: true, SaveData: not null })
|
if (readSaveResult is { Success: true, SaveData: not null })
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var lanPlayerNameService = LanPlayerNameService.Instance;
|
||||||
|
|
||||||
var data = RunManager.CanonicalizeSave(readSaveResult.SaveData, localPlayerId);
|
var data = RunManager.CanonicalizeSave(readSaveResult.SaveData, localPlayerId);
|
||||||
var playerNamesJson = SaveStore.ReadFile(CurrentMultiplayerRunPlayerNamesPath);
|
var playerNamesJson = SaveStore.ReadFile(CurrentMultiplayerRunPlayerNamesPath);
|
||||||
if (!string.IsNullOrEmpty(playerNamesJson))
|
if (!string.IsNullOrEmpty(playerNamesJson))
|
||||||
{
|
{
|
||||||
LanPlayerNameHelper.PlayerNameDictionary =
|
lanPlayerNameService.PlayerNames = JsonSerializer.Deserialize<PlayerNames>(playerNamesJson) ??
|
||||||
JsonSerializer.Deserialize<LanPlayerNames>(playerNamesJson) ?? new LanPlayerNames();
|
new PlayerNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
LanPlayerNameHelper.SetHostPlayerName();
|
lanPlayerNameService.SetHostPlayerName();
|
||||||
return new ReadSaveResult<SerializableRun>(data, ReadSaveStatus.Success);
|
return new ReadSaveResult<SerializableRun>(data, ReadSaveStatus.Success);
|
||||||
}
|
}
|
||||||
catch (Exception value)
|
catch (Exception value)
|
||||||
@@ -60,7 +70,7 @@ namespace SlayTheSpire2.LAN.Multiplayer.Helpers
|
|||||||
return readSaveResult;
|
return readSaveResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ReadSaveResult<SerializableRun> LoadMultiplayerRunSave()
|
public ReadSaveResult<SerializableRun> LoadMultiplayerRunSave()
|
||||||
{
|
{
|
||||||
var readSaveResult = MigrationManager.LoadSave<SerializableRun>(CurrentMultiplayerRunSavePath);
|
var readSaveResult = MigrationManager.LoadSave<SerializableRun>(CurrentMultiplayerRunSavePath);
|
||||||
if (readSaveResult.Success)
|
if (readSaveResult.Success)
|
||||||
@@ -86,13 +96,13 @@ namespace SlayTheSpire2.LAN.Multiplayer.Helpers
|
|||||||
return readSaveResult;
|
return readSaveResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DeleteCurrentMultiplayerRun()
|
public void DeleteCurrentMultiplayerRun()
|
||||||
{
|
{
|
||||||
SaveStore.DeleteFile(CurrentMultiplayerRunSavePath);
|
SaveStore.DeleteFile(CurrentMultiplayerRunSavePath);
|
||||||
SaveStore.DeleteFile(CurrentMultiplayerRunPlayerNamesPath);
|
SaveStore.DeleteFile(CurrentMultiplayerRunPlayerNamesPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RenameBrokenMultiplayerRunSave(ReadSaveStatus status)
|
public void RenameBrokenMultiplayerRunSave(ReadSaveStatus status)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using Godot;
|
||||||
|
using HarmonyLib;
|
||||||
|
using MegaCrit.Sts2.Core.Localization;
|
||||||
|
using MegaCrit.Sts2.Core.Multiplayer.Game.Lobby;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.CommonUi;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Multiplayer;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.CharacterSelect;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.CustomRun;
|
||||||
|
using MegaCrit.Sts2.Core.Nodes.Screens.DailyRun;
|
||||||
|
|
||||||
|
namespace SlayTheSpire2.LAN.Multiplayer.Services
|
||||||
|
{
|
||||||
|
internal class RunScreenService
|
||||||
|
{
|
||||||
|
private static readonly Lazy<RunScreenService> Lazy = new(() => new RunScreenService());
|
||||||
|
|
||||||
|
public static RunScreenService Instance => Lazy.Value;
|
||||||
|
|
||||||
|
public NCharacterSelectScreen? CharacterSelectScreen;
|
||||||
|
|
||||||
|
public NDailyRunScreen? DailyRunScreen;
|
||||||
|
|
||||||
|
public NCustomRunScreen? CustomRunScreen;
|
||||||
|
|
||||||
|
public NMultiplayerLoadGameScreen? MultiplayerLoadGameScreen;
|
||||||
|
|
||||||
|
public NDailyRunLoadScreen? DailyRunLoadScreen;
|
||||||
|
|
||||||
|
public NCustomRunLoadScreen? CustomRunLoadScreen;
|
||||||
|
|
||||||
|
private RunScreenService()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<bool> ShouldAllowRunToBegin(LoadRunLobby runLobby)
|
||||||
|
{
|
||||||
|
if (runLobby.ConnectedPlayerIds.Count >= runLobby.Run.Players.Count)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var locString = new LocString("gameplay_ui", "CONFIRM_LOAD_SAVE.body");
|
||||||
|
locString.Add("MissingCount", runLobby.Run.Players.Count - runLobby.ConnectedPlayerIds.Count);
|
||||||
|
|
||||||
|
var nGenericPopup = NGenericPopup.Create();
|
||||||
|
if (nGenericPopup != null)
|
||||||
|
{
|
||||||
|
NModalContainer.Instance?.Add(nGenericPopup);
|
||||||
|
|
||||||
|
var nVerticalPopup = Traverse.Create(nGenericPopup).Field("_verticalPopup").GetValue<NVerticalPopup>();
|
||||||
|
|
||||||
|
nVerticalPopup.NoButton.SetAnchorsPreset(Control.LayoutPreset.CenterBottom);
|
||||||
|
nVerticalPopup.NoButton.OffsetLeft = -90;
|
||||||
|
nVerticalPopup.NoButton.OffsetTop = -152;
|
||||||
|
nVerticalPopup.NoButton.OffsetRight = 90;
|
||||||
|
nVerticalPopup.NoButton.OffsetBottom = -80;
|
||||||
|
|
||||||
|
nVerticalPopup.YesButton.Visible = false;
|
||||||
|
|
||||||
|
return await nGenericPopup.WaitForConfirmation(locString,
|
||||||
|
new LocString("gameplay_ui", "CONFIRM_LOAD_SAVE.header"),
|
||||||
|
new LocString("gameplay_ui", "CONFIRM_LOAD_SAVE.cancel"),
|
||||||
|
new LocString("gameplay_ui", "CONFIRM_LOAD_SAVE.confirm"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-5
@@ -2,20 +2,20 @@
|
|||||||
using MegaCrit.Sts2.Core.Saves;
|
using MegaCrit.Sts2.Core.Saves;
|
||||||
using SlayTheSpire2.LAN.Multiplayer.Models;
|
using SlayTheSpire2.LAN.Multiplayer.Models;
|
||||||
|
|
||||||
namespace SlayTheSpire2.LAN.Multiplayer.Helpers
|
namespace SlayTheSpire2.LAN.Multiplayer.Services
|
||||||
{
|
{
|
||||||
internal class SettingsHelper
|
internal class SettingsService
|
||||||
{
|
{
|
||||||
private static readonly Lazy<SettingsHelper> Lazy = new(() => new SettingsHelper());
|
private static readonly Lazy<SettingsService> Lazy = new(() => new SettingsService());
|
||||||
|
|
||||||
public static SettingsHelper Instance => Lazy.Value;
|
public static SettingsService Instance => Lazy.Value;
|
||||||
|
|
||||||
public readonly SettingsModel SettingsModel;
|
public readonly SettingsModel SettingsModel;
|
||||||
|
|
||||||
private readonly GodotFileIo _modsDir =
|
private readonly GodotFileIo _modsDir =
|
||||||
new(Path.Combine(UserDataPathProvider.GetAccountScopedBasePath(null), "mods"));
|
new(Path.Combine(UserDataPathProvider.GetAccountScopedBasePath(null), "mods"));
|
||||||
|
|
||||||
private SettingsHelper()
|
private SettingsService()
|
||||||
{
|
{
|
||||||
if (_modsDir.FileExists("lan_settings.json"))
|
if (_modsDir.FileExists("lan_settings.json"))
|
||||||
{
|
{
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
<TargetFramework>net9.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<AssemblyVersion>1.3.0.0</AssemblyVersion>
|
<AssemblyVersion>1.5.0.0</AssemblyVersion>
|
||||||
<FileVersion>1.3.0.0</FileVersion>
|
<FileVersion>1.5.0.0</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user