These are two code snippets that add an extra class to make a client-side mod require all players in the lobby to have it installed.
- if you have AssemblyPublicizer:
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
[HarmonyPatch(typeof(NetworkManager))]
internal static class NetworkPrefabPatch1
{
private static readonly string MOD_GUID = MyPluginInfo.PLUGIN_GUID;
[HarmonyPostfix]
[HarmonyPatch(nameof(NetworkManager.SetSingleton))]
private static void RegisterPrefab()
{
var prefab = new GameObject(MOD_GUID + " Prefab");
prefab.hideFlags |= HideFlags.HideAndDontSave;
Object.DontDestroyOnLoad(prefab);
var networkObject = prefab.AddComponent<NetworkObject>();
networkObject.GlobalObjectIdHash = GetHash(MOD_GUID);
NetworkManager.Singleton.PrefabHandler.AddNetworkPrefab(prefab);
return;
static uint GetHash(string value)
{
return value?.Aggregate(17u, (current, c) => unchecked((current * 31) ^ c)) ?? 0u;
}
}
}
if you don't:
using System.Reflection;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
[HarmonyPatch(typeof(NetworkManager))]
internal static class NetworkPrefabPatch2
{
private static readonly string MOD_GUID = MyPluginInfo.PLUGIN_GUID;
[HarmonyPostfix]
[HarmonyPatch(nameof(NetworkManager.SetSingleton))]
private static void RegisterPrefab()
{
var prefab = new GameObject(MOD_GUID + " Prefab");
prefab.hideFlags |= HideFlags.HideAndDontSave;
Object.DontDestroyOnLoad(prefab);
var networkObject = prefab.AddComponent<NetworkObject>();
var fieldInfo = typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.NonPublic);
fieldInfo!.SetValue(networkObject, GetHash(MOD_GUID));
NetworkManager.Singleton.PrefabHandler.AddNetworkPrefab(prefab);
return;
static uint GetHash(string value)
{
return value?.Aggregate(17u, (current, c) => unchecked((current * 31) ^ c)) ?? 0u;
}
}
}
original discussion in: https://discord.com/channels/1168655651455639582/1348089079673393152