From 7c656c3f70742c553f83fb76fa3c39df469200f4 Mon Sep 17 00:00:00 2001 From: MT Date: Mon, 1 Feb 2021 15:54:58 -0500 Subject: [PATCH 1/5] fix soft restart --- MultiplayerExtensions/Installers/InterfaceInstaller.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/MultiplayerExtensions/Installers/InterfaceInstaller.cs b/MultiplayerExtensions/Installers/InterfaceInstaller.cs index 8ad0158..31514fa 100644 --- a/MultiplayerExtensions/Installers/InterfaceInstaller.cs +++ b/MultiplayerExtensions/Installers/InterfaceInstaller.cs @@ -2,6 +2,7 @@ using MultiplayerExtensions.Environments; using MultiplayerExtensions.OverrideClasses; using MultiplayerExtensions.UI; +using UnityEngine; using Zenject; namespace MultiplayerExtensions.Installers @@ -33,9 +34,11 @@ public override void Start() ServerPlayerListController playerListController = Container.Resolve(); GameServerPlayersTableView playersTableView = playerListController.GetField("_gameServerPlayersTableView"); GameServerPlayerTableCell playerTableCell = playersTableView.GetField("_gameServerPlayerCellPrefab"); - PlayerTableCellStub playerTableCellStub = playerTableCell.gameObject.AddComponent(); - playerTableCellStub.Construct(playerTableCell); - Destroy(playerTableCell.GetComponent()); + GameServerPlayerTableCell newPlayerTableCell = GameObject.Instantiate(playerTableCell); + newPlayerTableCell.gameObject.SetActive(false); + PlayerTableCellStub playerTableCellStub = newPlayerTableCell.gameObject.AddComponent(); + playerTableCellStub.Construct(newPlayerTableCell); + Destroy(newPlayerTableCell.GetComponent()); playersTableView.SetField("_gameServerPlayerCellPrefab", playerTableCellStub); } } From 5b6d7b829f68ce30ecfff0b4afd74ca00eb8f56d Mon Sep 17 00:00:00 2001 From: MT Date: Wed, 3 Feb 2021 19:02:33 -0500 Subject: [PATCH 2/5] fix bugs quickplay nullref unreliableupdate fix --- .../HarmonyPatches/NetworkingPatches.cs | 21 ++++++++++++------- .../OverrideClasses/PlayersDataModelStub.cs | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/MultiplayerExtensions/HarmonyPatches/NetworkingPatches.cs b/MultiplayerExtensions/HarmonyPatches/NetworkingPatches.cs index 8f5d201..cb3b959 100644 --- a/MultiplayerExtensions/HarmonyPatches/NetworkingPatches.cs +++ b/MultiplayerExtensions/HarmonyPatches/NetworkingPatches.cs @@ -1,6 +1,8 @@ using HarmonyLib; +using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Reflection.Emit; using UnityEngine; @@ -57,20 +59,23 @@ internal static bool Prefix() } } - [HarmonyPatch(typeof(ConnectedPlayerManager), "FlushUnreliableQueue", MethodType.Normal)] + [HarmonyPatch(typeof(ConnectedPlayerManager), "PollUpdate", MethodType.Normal)] internal class UpdateUnreliableFrequencyPatch { - private static float nextTime = 0f; - private static float frequency = 0.1f; + private static readonly MethodInfo _updateUnreliableMethod = typeof(ConnectedPlayerManager).GetMethod("FlushUnreliableQueue", BindingFlags.NonPublic | BindingFlags.Instance); - internal static bool Prefix() + internal static IEnumerable Transpiler(IEnumerable instructions) { - if (Time.time > nextTime) + var codes = instructions.ToList(); + for (int i = 0; i < codes.Count; i++) { - nextTime = Time.time + frequency; - return true; + if (codes[i].opcode == OpCodes.Ldarg_0 && codes[i+1].Calls(_updateUnreliableMethod)) + { + codes.RemoveRange(i, 2); + } } - return false; + + return codes.AsEnumerable(); } } diff --git a/MultiplayerExtensions/OverrideClasses/PlayersDataModelStub.cs b/MultiplayerExtensions/OverrideClasses/PlayersDataModelStub.cs index 1fd27c6..70d5384 100644 --- a/MultiplayerExtensions/OverrideClasses/PlayersDataModelStub.cs +++ b/MultiplayerExtensions/OverrideClasses/PlayersDataModelStub.cs @@ -80,7 +80,7 @@ public override void HandleMenuRpcManagerClearBeatmap(string userId) public async override void HandleMenuRpcManagerGetSelectedBeatmap(string userId) { ILobbyPlayerDataModel lobbyPlayerDataModel = this.GetLobbyPlayerDataModel(this.localUserId); - if (_multiplayerSessionManager.GetPlayerByUserId(userId).HasState("modded") && lobbyPlayerDataModel?.beatmapLevel is PreviewBeatmapStub preview) + if (lobbyPlayerDataModel != null && MPState.CurrentGameType != MultiplayerGameType.QuickPlay && _multiplayerSessionManager.GetPlayerByUserId(userId).HasState("modded") && lobbyPlayerDataModel?.beatmapLevel is PreviewBeatmapStub preview) _packetManager.Send(await PreviewBeatmapPacket.FromPreview(preview, lobbyPlayerDataModel.beatmapCharacteristic.serializedName, lobbyPlayerDataModel.beatmapDifficulty)); else if (lobbyPlayerDataModel != null && lobbyPlayerDataModel.beatmapLevel != null) this._menuRpcManager.SelectBeatmap(new BeatmapIdentifierNetSerializable(lobbyPlayerDataModel.beatmapLevel.levelID, lobbyPlayerDataModel.beatmapCharacteristic.serializedName, lobbyPlayerDataModel.beatmapDifficulty)); From 6c1c99598cacc7189050084bf85bed733a9a6075 Mon Sep 17 00:00:00 2001 From: MT Date: Thu, 11 Feb 2021 19:38:56 -0500 Subject: [PATCH 3/5] fixed an issue with beatmap selection --- .../Beatmaps/PreviewBeatmapStub.cs | 4 ++-- .../Environments/LobbyPlaceManager.cs | 5 ++++- .../HarmonyPatches/CustomSongsPatches.cs | 18 +++++++++++++++--- .../HarmonyPatches/HarmonyManager.cs | 1 + .../HarmonyPatches/NetworkingPatches.cs | 2 +- ...tiplayerInstaller.cs => MPCoreInstaller.cs} | 2 +- ...nterfaceInstaller.cs => MPMenuInstaller.cs} | 2 +- .../OverrideClasses/PlayerTableCellStub.cs | 2 ++ .../OverrideClasses/PlayersDataModelStub.cs | 10 +++++----- MultiplayerExtensions/Plugin.cs | 4 ++-- .../UI/ClientLobbySetupPanel.bsml | 2 +- .../UI/HostLobbySetupPanel.bsml | 2 +- 12 files changed, 36 insertions(+), 18 deletions(-) rename MultiplayerExtensions/Installers/{MultiplayerInstaller.cs => MPCoreInstaller.cs} (96%) rename MultiplayerExtensions/Installers/{InterfaceInstaller.cs => MPMenuInstaller.cs} (98%) diff --git a/MultiplayerExtensions/Beatmaps/PreviewBeatmapStub.cs b/MultiplayerExtensions/Beatmaps/PreviewBeatmapStub.cs index 673fa55..730a1da 100644 --- a/MultiplayerExtensions/Beatmaps/PreviewBeatmapStub.cs +++ b/MultiplayerExtensions/Beatmaps/PreviewBeatmapStub.cs @@ -91,9 +91,9 @@ public PreviewBeatmapStub(PreviewBeatmapPacket packet) _rawCoverTask = Task.FromResult(packet.coverImage); } - public PreviewBeatmapStub(Beatmap bm) + public PreviewBeatmapStub(string levelID, Beatmap bm) { - this.levelID = bm.ID; + this.levelID = levelID; this.levelHash = bm.Hash; this.beatmap = bm; diff --git a/MultiplayerExtensions/Environments/LobbyPlaceManager.cs b/MultiplayerExtensions/Environments/LobbyPlaceManager.cs index 5dc0da0..a8ebd63 100644 --- a/MultiplayerExtensions/Environments/LobbyPlaceManager.cs +++ b/MultiplayerExtensions/Environments/LobbyPlaceManager.cs @@ -53,7 +53,10 @@ public void SetCenterScreenScale() float angleBetweenPlayersWithEvenAdjustment = MultiplayerPlayerPlacement.GetAngleBetweenPlayersWithEvenAdjustment(_lobbyStateDataModel.maxPartySize, MultiplayerPlayerLayout.Circle); float outerCircleRadius = Mathf.Max(MultiplayerPlayerPlacement.GetOuterCircleRadius(angleBetweenPlayersWithEvenAdjustment, innerCircleRadius), minOuterCircleRadius); float scaleRatio = outerCircleRadius / minOuterCircleRadius; - MultiplayerLobbyCenterStageManager centerscreen = Resources.FindObjectsOfTypeAll().First(); + MultiplayerLobbyCenterStageManager[] centerscreens = Resources.FindObjectsOfTypeAll(); + if (centerscreens.Length == 0) + return; + MultiplayerLobbyCenterStageManager centerscreen = centerscreens.First(); centerscreen.transform.localScale = new Vector3(scaleRatio, scaleRatio, scaleRatio); } diff --git a/MultiplayerExtensions/HarmonyPatches/CustomSongsPatches.cs b/MultiplayerExtensions/HarmonyPatches/CustomSongsPatches.cs index d6ad64b..664fa63 100644 --- a/MultiplayerExtensions/HarmonyPatches/CustomSongsPatches.cs +++ b/MultiplayerExtensions/HarmonyPatches/CustomSongsPatches.cs @@ -8,7 +8,7 @@ namespace MultiplayerExtensions.HarmonyPatches { [HarmonyPatch(typeof(MultiplayerLevelSelectionFlowCoordinator), "enableCustomLevels", MethodType.Getter)] - public class EnableCustomLevelsPatch + internal class EnableCustomLevelsPatch { /// /// Overrides getter for @@ -20,8 +20,20 @@ static bool Prefix(ref bool __result) } } + [HarmonyPatch(typeof(HostLobbySetupViewController), "SetPlayersMissingLevelText", MethodType.Normal)] + internal class MissingLevelStartPatch + { + /// + /// Disables starting of game if not all players have song. + /// + static void Prefix(HostLobbySetupViewController __instance, string playersMissingLevelText) + { + __instance.SetStartGameEnabled(playersMissingLevelText == null, HostLobbySetupViewController.CannotStartGameReason.None); + } + } + [HarmonyPatch(typeof(NetworkPlayerEntitlementChecker), "GetEntitlementStatus", MethodType.Normal)] - public class CustomLevelEntitlementPatch + internal class CustomLevelEntitlementPatch { /// /// Changes the return value of the entitlement checker if it is a custom song. @@ -48,7 +60,7 @@ static bool Prefix(string levelId, ref Task __result) } [HarmonyPatch(typeof(NetworkPlayerEntitlementChecker), "GetPlayerLevelEntitlementsAsync", MethodType.Normal)] - public class StartGameLevelEntitlementPatch + internal class StartGameLevelEntitlementPatch { /// /// Changes the return value if it returns 'NotDownloaded' so that the host can start the game. diff --git a/MultiplayerExtensions/HarmonyPatches/HarmonyManager.cs b/MultiplayerExtensions/HarmonyPatches/HarmonyManager.cs index e03e96f..ba20158 100644 --- a/MultiplayerExtensions/HarmonyPatches/HarmonyManager.cs +++ b/MultiplayerExtensions/HarmonyPatches/HarmonyManager.cs @@ -40,6 +40,7 @@ static HarmonyManager() AddDefaultPatch(); AddDefaultPatch(); AddDefaultPatch(); + AddDefaultPatch(); //AddDefaultPatch(); (doesn't support generics) } diff --git a/MultiplayerExtensions/HarmonyPatches/NetworkingPatches.cs b/MultiplayerExtensions/HarmonyPatches/NetworkingPatches.cs index cb3b959..673e86a 100644 --- a/MultiplayerExtensions/HarmonyPatches/NetworkingPatches.cs +++ b/MultiplayerExtensions/HarmonyPatches/NetworkingPatches.cs @@ -79,7 +79,7 @@ internal static IEnumerable Transpiler(IEnumerable getLevelEntitlementTask) { + if (getLevelEntitlementTask != null) + getLevelEntitlementTask = getLevelEntitlementTask.ContinueWith(r => AdditionalContentModel.EntitlementStatus.Owned); base.SetData(connectedPlayer, playerDataModel, isHost, getLevelEntitlementTask); GetLevelEntitlement(connectedPlayer); lastPlayer = connectedPlayer; diff --git a/MultiplayerExtensions/OverrideClasses/PlayersDataModelStub.cs b/MultiplayerExtensions/OverrideClasses/PlayersDataModelStub.cs index 70d5384..350e172 100644 --- a/MultiplayerExtensions/OverrideClasses/PlayersDataModelStub.cs +++ b/MultiplayerExtensions/OverrideClasses/PlayersDataModelStub.cs @@ -109,7 +109,7 @@ public async override void HandleMenuRpcManagerSelectedBeatmap(string userId, Be if (localPreview != null) preview = new PreviewBeatmapStub(hash, localPreview); if (preview == null) - preview = await FetchBeatSaverPreview(hash); + preview = await FetchBeatSaverPreview(beatmapId.levelID, hash); HMMainThreadDispatcher.instance.Enqueue(() => base.SetPlayerBeatmapLevel(userId, preview, beatmapId.difficulty, characteristic)); } } @@ -123,7 +123,7 @@ public async override void HandleMenuRpcManagerSelectedBeatmap(string userId, Be public async new void SetLocalPlayerBeatmapLevel(string levelId, BeatmapDifficulty beatmapDifficulty, BeatmapCharacteristicSO characteristic) { string? hash = Utilities.Utils.LevelIdToHash(levelId); - Plugin.Log?.Debug($"Local user selected song '{hash}'."); + Plugin.Log?.Debug($"Local user selected song '{hash ?? levelId}'."); if (hash != null) { if (_playersData.Values.Any(playerData => playerData.beatmapLevel?.levelID == levelId)) @@ -139,7 +139,7 @@ public async override void HandleMenuRpcManagerSelectedBeatmap(string userId, Be if (localPreview != null) preview = new PreviewBeatmapStub(hash, localPreview); if (preview == null) - preview = await FetchBeatSaverPreview(hash); + preview = await FetchBeatSaverPreview(levelId, hash); HMMainThreadDispatcher.instance.Enqueue(() => base.SetPlayerBeatmapLevel(base.localUserId, preview, beatmapDifficulty, characteristic)); _packetManager.Send(await PreviewBeatmapPacket.FromPreview(preview, characteristic.serializedName, beatmapDifficulty)); @@ -195,12 +195,12 @@ private void OnSelectedBeatmap(string userId, BeatmapIdentifierNetSerializable? /// /// Creates a preview from a BeatSaver request. /// - public async Task FetchBeatSaverPreview(string hash) + public async Task FetchBeatSaverPreview(string levelID, string hash) { try { Beatmap bm = await Plugin.BeatSaver.Hash(hash); - return new PreviewBeatmapStub(bm); + return new PreviewBeatmapStub(levelID, bm); } catch(Exception ex) { diff --git a/MultiplayerExtensions/Plugin.cs b/MultiplayerExtensions/Plugin.cs index bf45af7..22a5119 100644 --- a/MultiplayerExtensions/Plugin.cs +++ b/MultiplayerExtensions/Plugin.cs @@ -43,8 +43,8 @@ public Plugin(IPALogger logger, Config conf, Zenjector zenjector, PluginMetadata PluginMetadata = pluginMetadata; Log = logger; Config = conf.Generated(); - zenjector.OnApp(); - zenjector.OnMenu(); + zenjector.OnApp(); + zenjector.OnMenu(); HttpOptions options = new HttpOptions("MultiplayerExtensions", new Version(pluginMetadata.Version.ToString())); BeatSaver = new BeatSaver(options); } diff --git a/MultiplayerExtensions/UI/ClientLobbySetupPanel.bsml b/MultiplayerExtensions/UI/ClientLobbySetupPanel.bsml index 09ffa5c..e2c0f0f 100644 --- a/MultiplayerExtensions/UI/ClientLobbySetupPanel.bsml +++ b/MultiplayerExtensions/UI/ClientLobbySetupPanel.bsml @@ -1,5 +1,5 @@ - + diff --git a/MultiplayerExtensions/UI/HostLobbySetupPanel.bsml b/MultiplayerExtensions/UI/HostLobbySetupPanel.bsml index 105d925..9b165f5 100644 --- a/MultiplayerExtensions/UI/HostLobbySetupPanel.bsml +++ b/MultiplayerExtensions/UI/HostLobbySetupPanel.bsml @@ -1,5 +1,5 @@ - + From 9d7eaf2f6780cea6fa0bfc016ed78949b2ba3d8f Mon Sep 17 00:00:00 2001 From: MT Date: Fri, 12 Feb 2021 18:57:33 -0500 Subject: [PATCH 4/5] fixed player table --- .../HarmonyPatches/CustomSongsPatches.cs | 2 +- .../OverrideClasses/LevelLoaderStub.cs | 2 +- .../OverrideClasses/PlayerTableCellStub.cs | 12 +++++++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/MultiplayerExtensions/HarmonyPatches/CustomSongsPatches.cs b/MultiplayerExtensions/HarmonyPatches/CustomSongsPatches.cs index 664fa63..7f04821 100644 --- a/MultiplayerExtensions/HarmonyPatches/CustomSongsPatches.cs +++ b/MultiplayerExtensions/HarmonyPatches/CustomSongsPatches.cs @@ -44,7 +44,7 @@ static bool Prefix(string levelId, ref Task __result) if (hash == null) return true; - if (SongCore.Loader.GetLevelByHash(hash) != null) + if (SongCore.Collections.songWithHashPresent(hash)) __result = Task.FromResult(EntitlementsStatus.Ok); else __result = Plugin.BeatSaver.Hash(hash).ContinueWith(r => diff --git a/MultiplayerExtensions/OverrideClasses/LevelLoaderStub.cs b/MultiplayerExtensions/OverrideClasses/LevelLoaderStub.cs index 6185669..fe79681 100644 --- a/MultiplayerExtensions/OverrideClasses/LevelLoaderStub.cs +++ b/MultiplayerExtensions/OverrideClasses/LevelLoaderStub.cs @@ -10,7 +10,7 @@ public override void LoadLevel(BeatmapIdentifierNetSerializable beatmapId, Gamep { string? levelId = beatmapId.levelID; string? hash = Utilities.Utils.LevelIdToHash(beatmapId.levelID); - if (SongCore.Loader.GetLevelById(levelId) != null || hash == null) + if (SongCore.Collections.songWithHashPresent(hash) || hash == null) { Plugin.Log?.Debug($"(SongLoader) Level with ID '{levelId}' already exists."); base.LoadLevel(beatmapId, gameplayModifiers, initialStartTime); diff --git a/MultiplayerExtensions/OverrideClasses/PlayerTableCellStub.cs b/MultiplayerExtensions/OverrideClasses/PlayerTableCellStub.cs index 2412d1d..33aaf65 100644 --- a/MultiplayerExtensions/OverrideClasses/PlayerTableCellStub.cs +++ b/MultiplayerExtensions/OverrideClasses/PlayerTableCellStub.cs @@ -86,12 +86,18 @@ private async void GetLevelEntitlement(IConnectedPlayer player) entitlementCts = new CancellationTokenSource(); string? levelId = _playersDataModel.GetPlayerBeatmapLevel(_playersDataModel.hostUserId)?.levelID; - if (levelId == null) + if (levelId == null) return; lastLevelId = levelId; - EntitlementsStatus entitlement = player.isMe ? await _entitlementChecker.GetEntitlementStatus(levelId) : await _entitlementChecker.GetTcsTaskCanPlayerPlayLevel(player, levelId, entitlementCts.Token, out _); - SetLevelEntitlement(player, entitlement); + + bool needsRpc = false; + Task entitlement = player.isMe ? + _entitlementChecker.GetEntitlementStatus(levelId) : + _entitlementChecker.GetTcsTaskCanPlayerPlayLevel(player, levelId, entitlementCts.Token, out needsRpc); + if (needsRpc) + _menuRpcManager.GetIsEntitledToLevel(levelId); + SetLevelEntitlement(player, await entitlement); } private void SetLevelEntitlement(IConnectedPlayer player, EntitlementsStatus status) From 3efa4118f72742175719328ef4efdf813dd675ae Mon Sep 17 00:00:00 2001 From: MT Date: Fri, 12 Feb 2021 19:00:17 -0500 Subject: [PATCH 5/5] update versions --- MultiplayerExtensions/MultiplayerExtensions.csproj | 2 +- MultiplayerExtensions/manifest.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MultiplayerExtensions/MultiplayerExtensions.csproj b/MultiplayerExtensions/MultiplayerExtensions.csproj index daac61a..3ae4750 100644 --- a/MultiplayerExtensions/MultiplayerExtensions.csproj +++ b/MultiplayerExtensions/MultiplayerExtensions.csproj @@ -4,7 +4,7 @@ Library Properties MultiplayerExtensions - 0.4.4 + 0.4.5 net472 true portable diff --git a/MultiplayerExtensions/manifest.json b/MultiplayerExtensions/manifest.json index c713458..4d86171 100644 --- a/MultiplayerExtensions/manifest.json +++ b/MultiplayerExtensions/manifest.json @@ -3,7 +3,7 @@ "id": "MultiplayerExtensions", "name": "MultiplayerExtensions", "author": "Zingabopp and Goobwabber", - "version": "0.4.4", + "version": "0.4.5", "description": "Expands the functionality of Beat Saber Multiplayer.", "gameVersion": "1.13.2", "dependsOn": {