mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-21 18:40:03 +00:00
commit
401f3de7bd
58
QSB-NH/Patches/GameStateMessagePatches.cs
Normal file
58
QSB-NH/Patches/GameStateMessagePatches.cs
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
32
QSB-NH/QSB-NH.csproj
Normal file
32
QSB-NH/QSB-NH.csproj
Normal file
@ -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>
|
59
QSB-NH/QSBNH.cs
Normal file
59
QSB-NH/QSBNH.cs
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
QSB-NH/QuantumPlanet/QuantumPlanetManager.cs
Normal file
13
QSB-NH/QuantumPlanet/QuantumPlanetManager.cs
Normal file
@ -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>();
|
||||
}
|
7
QSB-NH/QuantumPlanet/WorldObjects/QSBQuantumPlanet.cs
Normal file
7
QSB-NH/QuantumPlanet/WorldObjects/QSBQuantumPlanet.cs
Normal file
@ -0,0 +1,7 @@
|
||||
using QSB.QuantumSync.WorldObjects;
|
||||
|
||||
namespace QSBNH.QuantumPlanet.WorldObjects;
|
||||
|
||||
public class QSBQuantumPlanet : QSBQuantumObject<NewHorizons.Components.Quantum.QuantumPlanet>
|
||||
{
|
||||
}
|
168
QSB-NH/WarpManager.cs
Normal file
168
QSB-NH/WarpManager.cs
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
QSB-NH/lib/NewHorizons.dll
Normal file
BIN
QSB-NH/lib/NewHorizons.dll
Normal file
Binary file not shown.
6
QSB.sln
6
QSB.sln
@ -34,6 +34,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APITestMod", "APITestMod\AP
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QSBPatcher", "QSBPatcher\QSBPatcher.csproj", "{CA4CBA2B-54D5-4C4B-9B51-957BC6D77D6B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QSB-NH", "QSB-NH\QSB-NH.csproj", "{74F84A39-1C9D-4EF7-889A-485D33B7B324}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -64,6 +66,10 @@ Global
|
||||
{CA4CBA2B-54D5-4C4B-9B51-957BC6D77D6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CA4CBA2B-54D5-4C4B-9B51-957BC6D77D6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CA4CBA2B-54D5-4C4B-9B51-957BC6D77D6B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{74F84A39-1C9D-4EF7-889A-485D33B7B324}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{74F84A39-1C9D-4EF7-889A-485D33B7B324}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{74F84A39-1C9D-4EF7-889A-485D33B7B324}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{74F84A39-1C9D-4EF7-889A-485D33B7B324}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -9,6 +9,7 @@ using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using QSB.Utility.Deterministic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
@ -41,8 +42,9 @@ public class ConversationManager : WorldObjectManager
|
||||
|
||||
public override async UniTask BuildWorldObjects(OWScene scene, CancellationToken ct)
|
||||
{
|
||||
QSBWorldSync.Init<QSBRemoteDialogueTrigger, RemoteDialogueTrigger>();
|
||||
QSBWorldSync.Init<QSBCharacterDialogueTree, CharacterDialogueTree>();
|
||||
// dont create worldobjects
|
||||
QSBWorldSync.Init<QSBRemoteDialogueTrigger, RemoteDialogueTrigger>(QSBWorldSync.GetUnityObjects<RemoteDialogueTrigger>().Where(x => x.name != "WarpDriveRemoteTrigger").SortDeterministic());
|
||||
QSBWorldSync.Init<QSBCharacterDialogueTree, CharacterDialogueTree>(QSBWorldSync.GetUnityObjects<CharacterDialogueTree>().Where(x => x.name != "WarpDriveDialogue").SortDeterministic());
|
||||
}
|
||||
|
||||
public uint GetPlayerTalkingToTree(CharacterDialogueTree tree) =>
|
||||
|
@ -1,6 +1,7 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using QSB.MeteorSync.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace QSB.MeteorSync;
|
||||
@ -16,7 +17,9 @@ public class MeteorManager : WorldObjectManager
|
||||
// wait for all late initializers (which includes meteor launchers) to finish
|
||||
await UniTask.WaitUntil(() => LateInitializerManager.isDoneInitializing, cancellationToken: ct);
|
||||
|
||||
WhiteHoleVolume = QSBWorldSync.GetUnityObject<WhiteHoleVolume>();
|
||||
// NH can make multiple so ensure its the stock whitehole
|
||||
var whiteHole = QSBWorldSync.GetUnityObjects<AstroObject>().First(x => x.GetAstroObjectName() == AstroObject.Name.WhiteHole);
|
||||
WhiteHoleVolume = whiteHole?.GetComponentInChildren<WhiteHoleVolume>();
|
||||
QSBWorldSync.Init<QSBFragment, FragmentIntegrity>();
|
||||
QSBWorldSync.Init<QSBMeteorLauncher, MeteorLauncher>();
|
||||
QSBWorldSync.Init<QSBMeteor, MeteorController>();
|
||||
|
@ -84,12 +84,12 @@ public class QSBCore : ModBehaviour
|
||||
private static string randomSkinType;
|
||||
private static string randomJetpackType;
|
||||
|
||||
public static Assembly QSBNHAssembly = null;
|
||||
|
||||
public static readonly string[] IncompatibleMods =
|
||||
{
|
||||
// incompatible mods
|
||||
"Raicuparta.NomaiVR",
|
||||
"xen.NewHorizons",
|
||||
"Vesper.AutoResume",
|
||||
"Vesper.OuterWildsMMO",
|
||||
"_nebula.StopTime",
|
||||
@ -227,7 +227,7 @@ public class QSBCore : ModBehaviour
|
||||
Helper = ModHelper;
|
||||
DebugLog.ToConsole($"* Start of QSB version {QSBVersion} - authored by {Helper.Manifest.Author}", MessageType.Info);
|
||||
|
||||
CheckCompatibilityMods();
|
||||
CheckNewHorizons();
|
||||
|
||||
DebugSettings = Helper.Storage.Load<DebugSettings>("debugsettings.json") ?? new DebugSettings();
|
||||
|
||||
@ -463,23 +463,13 @@ public class QSBCore : ModBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckCompatibilityMods()
|
||||
private void CheckNewHorizons()
|
||||
{
|
||||
var mainMod = "";
|
||||
var compatMod = "";
|
||||
var missingCompat = false;
|
||||
|
||||
/*if (Helper.Interaction.ModExists(NEW_HORIZONS) && !Helper.Interaction.ModExists(NEW_HORIZONS_COMPAT))
|
||||
if (ModHelper.Interaction.ModExists("xen.NewHorizons"))
|
||||
{
|
||||
mainMod = NEW_HORIZONS;
|
||||
compatMod = NEW_HORIZONS_COMPAT;
|
||||
missingCompat = true;
|
||||
}*/
|
||||
|
||||
if (missingCompat)
|
||||
{
|
||||
DebugLog.ToConsole($"FATAL - You have mod \"{mainMod}\" installed, which is not compatible with QSB without the compatibility mod \"{compatMod}\". " +
|
||||
$"Either disable the mod, or install/enable the compatibility mod.", MessageType.Fatal);
|
||||
// NH compat has to be in a different DLL since it uses IAddComponentOnStart, and depends on the NH DLL.
|
||||
QSBNHAssembly = Assembly.LoadFrom(Path.Combine(ModHelper.Manifest.ModFolderPath, "QSB-NH.dll"));
|
||||
gameObject.AddComponent(QSBNHAssembly.GetType("QSBNH.QSBNH", true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,6 +205,8 @@ public class DebugGUI : MonoBehaviour, IAddComponentOnStart
|
||||
|
||||
WriteLine(2, $" - Ref. Sector : {(referenceSector == null ? "NULL" : referenceSector.Name)}", referenceSector == null ? Color.red : Color.white);
|
||||
WriteLine(2, $" - Ref. Transform : {(referenceTransform == null ? "NULL" : referenceTransform.name)}", referenceTransform == null ? Color.red : Color.white);
|
||||
WriteLine(2, $" - Local Position : {player.Body.transform.localPosition}");
|
||||
WriteLine(2, $" - Position : {player.Body.transform.position}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,13 +182,21 @@ public static class Extensions
|
||||
multiDelegate.SafeInvoke(args);
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> GetDerivedTypes(this Type type) =>
|
||||
QSBCore.Addons.Values
|
||||
public static IEnumerable<Type> GetDerivedTypes(this Type type)
|
||||
{
|
||||
var assemblies = QSBCore.Addons.Values
|
||||
.Select(x => x.GetType().Assembly)
|
||||
.Append(type.Assembly)
|
||||
.SelectMany(x => x.GetTypes())
|
||||
.Append(type.Assembly);
|
||||
|
||||
if (QSBCore.QSBNHAssembly != null)
|
||||
{
|
||||
assemblies = assemblies.Append(QSBCore.QSBNHAssembly);
|
||||
}
|
||||
|
||||
return assemblies.SelectMany(x => x.GetTypes())
|
||||
.Where(x => !x.IsInterface && !x.IsAbstract && type.IsAssignableFrom(x))
|
||||
.OrderBy(x => x.FullName);
|
||||
}
|
||||
|
||||
public static Guid ToGuid(this int value)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user