ModdingGuides
Version Enforcement
Make the host kick players who join without your mod installed
To make your mod required by all players, making the host kick those that join without the mod, you may use this script!
Using Intermediary names from CrabDevKit:
using HarmonyLib;
using SteamworksNative;
namespace YourNamespace
{
internal static class RequiredMod
{
private const string ModIdentifier = "YourModIdentifier"; // Must change! ex. $"lammas123.{MyPluginInfo.PLUGIN_GUID}";
private const string ModVersion = MyPluginInfo.PLUGIN_VERSION; // If you're certain there won't be incompatibilities between versions, you may just set this to "1"; to accept anyone with the mod
private static Harmony _harmony;
// Call this once in your mod's Load method
internal static void Init()
{
_harmony = new(ModIdentifier);
_harmony.PatchAll(typeof(RequiredMod));
}
// Logic to allow or prevent a client from joining
// clientModVersion will be string.Empty when the client doesn't have the mod, SteamMatchmaking.GetLobbyMemberData doesn't return null
private static bool MayClientJoin(string clientModVersion)
{
// Some may want to improve this, say, let everyone playing on 1.1.X join, but not those on other major/minor versions (SemVer)
return clientModVersion == ModVersion;
}
// Tell the host you have the mod via lobby member data
[HarmonyPatch(typeof(SteamManager), nameof(SteamManager.Method_Private_Void_LobbyEnter_t_PDM_1))]
[HarmonyPostfix]
internal static void PostSteamManagerLobbyEnter()
=> SteamMatchmaking.SetLobbyMemberData(SteamManager.Instance.currentLobby, ModIdentifier, ModVersion);
// Kick clients that may not join when they request to
[HarmonyPatch(typeof(ServerHandle), nameof(ServerHandle.LoadMapRequest))]
[HarmonyPrefix]
internal static bool PreServerHandleLoadMapRequest(ulong param_0)
{
bool mayJoin = MayClientJoin(SteamMatchmaking.GetLobbyMemberData(SteamManager.Instance.currentLobby, new(param_0), ModIdentifier));
if (mayJoin)
return true;
LobbyManager.Instance.KickPlayer(param_0);
return false;
}
}
}The only modifications you'll need to include:
- Changing the namespace to fit your project's structure
- Putting
RequiredMod.Init();in your mod'sLoadmethod - Setting
ModIdentifierto something unique that won't clash with other mods
Otherwise, you could also change ModVersion or the logic for MayClientJoin depending on your use case!
As of writing this, this script hasn't been fully tested, but will be tested and likely improved in the future.