using System.Reflection; using HarmonyLib; using undead_universal_patch_il2cpp.Core; using undead_universal_patch_il2cpp.Core.Config; using undead_universal_patch_il2cpp.Core.Content.CustomRecNet.CustomPhoton; namespace undead_universal_patch_il2cpp.Patches.Photon; [HarmonyPatch] public class ForceSelfHostedPhoton { class HarmonyState { public object code; } static PatchTypesResult patchResult = Util.ConfigsPreparePatchTypes( [ PhotonConfig.PatchPhotonIds, PhotonConfig.SelfHosted ], "Force JoinOrCreateRoom when connected to master", "PUNNetworkManager", "OnConnectedToMaster" ); static bool Prepare() => patchResult.Success; static MethodBase TargetMethod() => patchResult.Method; static void Prefix(ref PUNNetworkManager __instance, ref HarmonyState __state) { if (ServerPatchesConfig.CustomPhoton.Value && !CustomPhoton.ServerConfigFailed) { Util.ConditionalDebug("Skipping Selfhost Photon target server regionId roundtrip, CustomPhoton is enabled."); return; } __state = new HarmonyState(); PropertyInfo targetGameSessionProperty = __instance.GetType().GetRuntimeProperty("targetGameSession"); if (targetGameSessionProperty == null) { UniversalPatchPlugin.Log.LogFatal("Cannot force masterserver: targetGameSessionProperty was null."); return; } var targetGameSession = targetGameSessionProperty.GetValue(__instance); if (targetGameSession == null) { UniversalPatchPlugin.Log.LogFatal("Cannot force masterserver: targetGameSession was null."); return; } PropertyInfo photonRegionIdProperty = targetGameSession.GetType().GetRuntimeProperty("PhotonRegionId"); if (photonRegionIdProperty == null) { UniversalPatchPlugin.Log.LogFatal("Cannot force masterserver: photonRegionIdProperty was null."); return; } __state.code = photonRegionIdProperty.GetValue(targetGameSession); photonRegionIdProperty.SetValue(targetGameSession, 4); Util.ConditionalDebug("Selfhost Photon target server regionId pre-roundtrip"); } static void Postfix(ref PUNNetworkManager __instance, ref HarmonyState __state) { PropertyInfo targetGameSessionProperty = __instance.GetType().GetRuntimeProperty("targetGameSession"); if (targetGameSessionProperty == null) { UniversalPatchPlugin.Log.LogFatal("Cannot force masterserver postfix: targetGameSessionProperty was null."); return; } var targetGameSession = targetGameSessionProperty.GetValue(__instance); if (targetGameSession == null) { UniversalPatchPlugin.Log.LogFatal("Cannot force masterserver postfix: targetGameSession was null."); return; } PropertyInfo photonRegionIdProperty = targetGameSession.GetType().GetRuntimeProperty("PhotonRegionId"); if (photonRegionIdProperty == null) { UniversalPatchPlugin.Log.LogFatal("Cannot force masterserver: photonRegionIdProperty was null."); return; } photonRegionIdProperty.SetValue(targetGameSession, __state.code); Util.ConditionalDebug("Selfhost Photon target server regionId post-roundtrip"); } } // Fixes some reflection used by Rec Room that, when TCP is used in the Photon patch config, // incorrectly assumes that ENetPeer (UDP) is in use // Allows TPeer (TCP) to be specified by PhotonConfig.ConnectionProtocol [HarmonyPatch] public class PhotonThrottlingPatch { static PatchTypesResult patchTypesResult = Util.ConfigPreparePatchTypes( PhotonConfig.SelfHosted, "ENet incorrect assumption patch", "PUNNetworkManager", "UpdatePhotonThrottling" ); static bool Prepare() => patchTypesResult.Success; static MethodBase TargetMethod() => patchTypesResult.Method; static bool Prefix() => PhotonConfig.ConnectionProtocol.Value != 1; }