-
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #668 from qsb-dev/nh-compat
NH compatibility
- Loading branch information
Showing
13 changed files
with
372 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using HarmonyLib; | ||
using Mirror; | ||
using NewHorizons; | ||
using QSB; | ||
using QSB.Patches; | ||
using QSB.Player; | ||
using QSB.SaveSync.Messages; | ||
using QSB.Utility; | ||
|
||
namespace QSBNH.Patches; | ||
|
||
|
||
internal class GameStateMessagePatches : QSBPatch | ||
{ | ||
public override QSBPatchTypes Type => QSBPatchTypes.OnModStart; | ||
|
||
private static string _initialSystem; | ||
private static int[] _hostAddonHash; | ||
|
||
[HarmonyPostfix] | ||
[HarmonyPatch(typeof(GameStateMessage), nameof(GameStateMessage.Serialize))] | ||
public static void GameStateMessage_Serialize(GameStateMessage __instance, NetworkWriter writer) | ||
{ | ||
var currentSystem = QSBNH.Instance.NewHorizonsAPI.GetCurrentStarSystem(); | ||
|
||
writer.Write(currentSystem); | ||
writer.WriteArray(QSBNH.HashAddonsForSystem(currentSystem)); | ||
} | ||
|
||
[HarmonyPostfix] | ||
[HarmonyPatch(typeof(GameStateMessage), nameof(GameStateMessage.Deserialize))] | ||
public static void GameStateMessage_Deserialize(GameStateMessage __instance, NetworkReader reader) | ||
{ | ||
_initialSystem = reader.Read<string>(); | ||
_hostAddonHash = reader.ReadArray<int>(); | ||
} | ||
|
||
[HarmonyPostfix] | ||
[HarmonyPatch(typeof(GameStateMessage), nameof(GameStateMessage.OnReceiveRemote))] | ||
public static void GameStateMessage_OnReceiveRemote() | ||
{ | ||
if (QSBCore.IsHost) | ||
{ | ||
DebugLog.DebugWrite($"Why is the host being given the initial state info?"); | ||
} | ||
else | ||
{ | ||
DebugLog.DebugWrite($"Player#{QSBPlayerManager.LocalPlayerId} is being sent to {_initialSystem}"); | ||
|
||
WarpManager.RemoteChangeStarSystem(_initialSystem, false, false, _hostAddonHash); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net48</TargetFramework> | ||
<RootNamespace>QSBNH</RootNamespace> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<OutputPath Condition="Exists('$(OwmlDir)')">$(OwmlDir)\Mods\Raicuparta.QuantumSpaceBuddies</OutputPath> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Folder Include="lib\" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\QSB\QSB.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Reference Include="Mirror"> | ||
<HintPath>..\Lib\Mirror.dll</HintPath> | ||
</Reference> | ||
<Reference Include="NewHorizons"> | ||
<HintPath>lib\NewHorizons.dll</HintPath> | ||
<Private>false</Private> | ||
</Reference> | ||
<Reference Include="UniTask"> | ||
<HintPath>..\Lib\UniTask.dll</HintPath> | ||
</Reference> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using Mirror; | ||
using NewHorizons; | ||
using OWML.Common; | ||
using OWML.ModHelper; | ||
using QSB; | ||
using QSB.Utility; | ||
using UnityEngine; | ||
|
||
namespace QSBNH | ||
{ | ||
public class QSBNH : MonoBehaviour | ||
{ | ||
public static QSBNH Instance; | ||
|
||
public INewHorizons NewHorizonsAPI; | ||
|
||
private void Start() | ||
{ | ||
Instance = this; | ||
DebugLog.DebugWrite($"Start of QSB-NH compatibility code.", MessageType.Success); | ||
NewHorizonsAPI = QSBCore.Helper.Interaction.TryGetModApi<INewHorizons>("xen.NewHorizons"); | ||
} | ||
|
||
public static string HashToMod(int hash) | ||
{ | ||
foreach (var mod in NewHorizons.Main.MountedAddons) | ||
{ | ||
var name = mod.ModHelper.Manifest.UniqueName; | ||
if (name.GetStableHashCode() == hash) | ||
{ | ||
return name; | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
|
||
public static int[] HashAddonsForSystem(string system) | ||
{ | ||
if (NewHorizons.Main.BodyDict.TryGetValue(system, out var bodies)) | ||
{ | ||
var addonHashes = bodies | ||
.Where(x => x.Mod.ModHelper.Manifest.UniqueName != "xen.NewHorizons") | ||
.Select(x => x.Mod.ModHelper.Manifest.UniqueName.GetStableHashCode()) | ||
.Distinct(); | ||
|
||
var nhPlanetHashes = bodies | ||
.Where(x => x.Mod.ModHelper.Manifest.UniqueName == "xen.NewHorizons") | ||
.Select(x => x.Config.name.GetStableHashCode()); | ||
|
||
return addonHashes.Concat(nhPlanetHashes).ToArray(); | ||
} | ||
else | ||
{ | ||
return null; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using Cysharp.Threading.Tasks; | ||
using QSB.WorldSync; | ||
using QSBNH.QuantumPlanet.WorldObjects; | ||
|
||
namespace QSBNH.QuantumPlanet; | ||
public class QuantumPlanetManager : WorldObjectManager | ||
{ | ||
public override WorldObjectScene WorldObjectScene => WorldObjectScene.Both; | ||
public override bool DlcOnly => false; | ||
|
||
public override async UniTask BuildWorldObjects(OWScene scene, CancellationToken ct) => | ||
QSBWorldSync.Init<QSBQuantumPlanet, NewHorizons.Components.Quantum.QuantumPlanet>(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
using QSB.QuantumSync.WorldObjects; | ||
|
||
namespace QSBNH.QuantumPlanet.WorldObjects; | ||
|
||
public class QSBQuantumPlanet : QSBQuantumObject<NewHorizons.Components.Quantum.QuantumPlanet> | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
using HarmonyLib; | ||
using NewHorizons; | ||
using QSB.Menus; | ||
using QSB.Messaging; | ||
using QSB.Player; | ||
using QSB; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Mirror; | ||
using QSB.Patches; | ||
using QSB.Utility; | ||
|
||
namespace QSBNH; | ||
public static class WarpManager | ||
{ | ||
internal static bool RemoteWarp = false; | ||
|
||
private static void Kick(string reason) | ||
{ | ||
DebugLog.DebugWrite(reason); | ||
MenuManager.Instance.OnKicked(reason); | ||
NetworkClient.Disconnect(); | ||
} | ||
|
||
public static void RemoteChangeStarSystem(string system, bool ship, bool vessel, int[] hostAddonHash) | ||
{ | ||
// Flag to not send a message | ||
RemoteWarp = true; | ||
|
||
DebugLog.DebugWrite($"Remote request received to go to {system}"); | ||
|
||
if (!NewHorizons.Main.SystemDict.ContainsKey(system)) | ||
{ | ||
// If you can't go to that system then you have to be disconnected | ||
Kick($"You don't have the mod installed for {system}"); | ||
} | ||
else | ||
{ | ||
var localHash = QSBNH.HashAddonsForSystem(system); | ||
if (localHash != hostAddonHash) | ||
{ | ||
var missingAddonHashes = hostAddonHash.Except(localHash); | ||
var extraAddonHashes = localHash.Except(hostAddonHash); | ||
|
||
if (missingAddonHashes.Count() > 0) | ||
{ | ||
Kick($"You are missing {missingAddonHashes.Count()} addon(s) that effect {system}"); | ||
return; | ||
} | ||
|
||
if (extraAddonHashes.Count() > 0) | ||
{ | ||
var extraMods = extraAddonHashes.Select(x => QSBNH.HashToMod(x)); | ||
|
||
// TODO: Disable these mods for the client and do not kick them | ||
|
||
Kick($"You have {extraAddonHashes.Count()} extra addon(s) that effect {system}. Check the logs."); | ||
DebugLog.DebugWrite($"You have mods affecting {system} that the host does not: {string.Join(", ", extraMods)}"); | ||
return; | ||
} | ||
} | ||
|
||
NewHorizons.Main.Instance.ChangeCurrentStarSystem(system, ship, vessel); | ||
} | ||
} | ||
|
||
public class NHWarpMessage : QSBMessage | ||
{ | ||
private string _starSystem; | ||
private bool _shipWarp; | ||
private bool _vesselWarp; | ||
|
||
public NHWarpMessage(string starSystem, bool shipWarp, bool vesselWarp) : base() | ||
{ | ||
_starSystem = starSystem; | ||
_shipWarp = shipWarp; | ||
_vesselWarp = vesselWarp; | ||
} | ||
|
||
public override void Serialize(NetworkWriter writer) | ||
{ | ||
base.Serialize(writer); | ||
|
||
writer.Write(_starSystem); | ||
writer.Write(_shipWarp); | ||
writer.Write(_vesselWarp); | ||
} | ||
|
||
public override void Deserialize(NetworkReader reader) | ||
{ | ||
base.Deserialize(reader); | ||
|
||
_starSystem = reader.Read<string>(); | ||
_shipWarp = reader.Read<bool>(); | ||
_vesselWarp = reader.Read<bool>(); | ||
} | ||
|
||
public override void OnReceiveRemote() | ||
{ | ||
DebugLog.DebugWrite($"Player#{From} is telling Player#{To} to warp to {_starSystem}"); | ||
if (QSBCore.IsHost && !NewHorizons.Main.SystemDict.ContainsKey(_starSystem)) | ||
{ | ||
// If the host doesn't have that system then we can't | ||
DebugLog.DebugWrite($"The host doesn't have {_starSystem} installed: aborting"); | ||
} | ||
else | ||
{ | ||
if (QSBCore.IsHost) | ||
{ | ||
new NHWarpMessage(_starSystem, _shipWarp, _vesselWarp).Send(); | ||
} | ||
|
||
RemoteChangeStarSystem(_starSystem, _shipWarp, _vesselWarp, QSBNH.HashAddonsForSystem(_starSystem)); | ||
} | ||
} | ||
} | ||
|
||
[HarmonyPatch] | ||
public class NHWarpPatch : QSBPatch | ||
{ | ||
public override QSBPatchTypes Type => QSBPatchTypes.OnModStart; | ||
|
||
[HarmonyPrefix] | ||
[HarmonyPatch(typeof(NewHorizons.Main), nameof(NewHorizons.Main.ChangeCurrentStarSystem))] | ||
public static bool NewHorizons_ChangeCurrentStarSystem(string newStarSystem, bool warp, bool vessel) | ||
{ | ||
if (RemoteWarp) | ||
{ | ||
// We're being told to warp so just do it | ||
RemoteWarp = false; | ||
return true; | ||
} | ||
|
||
DebugLog.DebugWrite($"Local request received to go to {newStarSystem}"); | ||
if (QSBCore.IsHost) | ||
{ | ||
// The host will tell all other users to warp | ||
DebugLog.DebugWrite($"Host: Telling others to go to {newStarSystem}"); | ||
new NHWarpMessage(newStarSystem, warp, vessel).Send(); | ||
// The host can now warp | ||
return true; | ||
} | ||
else | ||
{ | ||
// We're a client that has to tell the host to start warping people | ||
DebugLog.DebugWrite($"Client: Telling host to send us to {newStarSystem}"); | ||
new NHWarpMessage(newStarSystem, warp, vessel) { To = 0 }.Send(); | ||
|
||
// We have to wait for the host to get back to us | ||
return false; | ||
} | ||
} | ||
|
||
[HarmonyPostfix] | ||
[HarmonyPatch(typeof(NewHorizons.Main), nameof(NewHorizons.Main.ChangeCurrentStarSystem))] | ||
public static void NewHorizons_ChangeCurrentStarSystem(NewHorizons.Main __instance) | ||
{ | ||
if (__instance.IsWarpingFromShip) | ||
{ | ||
// If QSB doesn't say we're piloting the ship then dont keep them on as the one warping | ||
__instance.GetType().GetProperty(nameof(NewHorizons.Main.IsWarpingFromShip)).SetValue(__instance, QSBPlayerManager.LocalPlayer.FlyingShip); | ||
} | ||
} | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.