Internals rewritten. PHoton config can now be fetched from the server, and if it fails, fallback to the local configuration.
This commit is contained in:
@@ -35,10 +35,12 @@ namespace undead_universal_patch_il2cpp.Core.Config
|
|||||||
public static class ServerPatchesConfig
|
public static class ServerPatchesConfig
|
||||||
{
|
{
|
||||||
public static ConfigEntry<bool> CustomEmotes;
|
public static ConfigEntry<bool> CustomEmotes;
|
||||||
|
public static ConfigEntry<bool> CustomPhoton;
|
||||||
}
|
}
|
||||||
public static class ServerPatchesConfigDefaults
|
public static class ServerPatchesConfigDefaults
|
||||||
{
|
{
|
||||||
public static bool CustomEmotes = false;
|
public static bool CustomEmotes = false;
|
||||||
|
public static bool CustomPhoton = false;
|
||||||
}
|
}
|
||||||
public static class GameManagerConfig
|
public static class GameManagerConfig
|
||||||
{
|
{
|
||||||
@@ -69,6 +71,7 @@ namespace undead_universal_patch_il2cpp.Core.Config
|
|||||||
public static ConfigEntry<bool> SelfHosted;
|
public static ConfigEntry<bool> SelfHosted;
|
||||||
public static ConfigEntry<string> ServerAddress;
|
public static ConfigEntry<string> ServerAddress;
|
||||||
public static ConfigEntry<int> ServerPort;
|
public static ConfigEntry<int> ServerPort;
|
||||||
|
public static ConfigEntry<byte> ConnectionProtocol;
|
||||||
}
|
}
|
||||||
public static class PhotonConfigDefaults
|
public static class PhotonConfigDefaults
|
||||||
{
|
{
|
||||||
@@ -79,5 +82,6 @@ namespace undead_universal_patch_il2cpp.Core.Config
|
|||||||
public static bool SelfHosted = false;
|
public static bool SelfHosted = false;
|
||||||
public static string ServerAddress = "127.0.0.1";
|
public static string ServerAddress = "127.0.0.1";
|
||||||
public static int ServerPort = 5055;
|
public static int ServerPort = 5055;
|
||||||
|
public static byte ConnectionProtocol = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ using System.Collections.Concurrent;
|
|||||||
using Mapster;
|
using Mapster;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using undead_universal_patch_il2cpp.Core.Config;
|
using BestHTTP;
|
||||||
|
|
||||||
namespace undead_universal_patch_il2cpp.Core.CustomRecNet.CustomEmotes;
|
namespace undead_universal_patch_il2cpp.Core.Content.CustomRecNet.CustomEmotes;
|
||||||
|
|
||||||
public class EmoteConfigDTO
|
public class EmoteConfigDTO
|
||||||
{
|
{
|
||||||
@@ -18,9 +18,15 @@ public class EmoteConfigDTO
|
|||||||
public bool OnlyBroadcastToTeam { get; set; }
|
public bool OnlyBroadcastToTeam { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EmoteConfig
|
public class CustomEmotes : MonoBehaviour
|
||||||
{
|
{
|
||||||
public static void Patch(List<EmoteConfigDTO> emotes)
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
RecNetInteractions.postLocalAccountActions.Add(DownloadCustomEmotes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Patch(HTTPResponse _res, List<EmoteConfigDTO> emotes)
|
||||||
{
|
{
|
||||||
UniversalPatchPlugin.Log.LogInfo("Setting new emotes");
|
UniversalPatchPlugin.Log.LogInfo("Setting new emotes");
|
||||||
|
|
||||||
@@ -36,29 +42,10 @@ public class EmoteConfig
|
|||||||
|
|
||||||
Util.ConditionalDebug($"{emotes.Count} new emote configurations");
|
Util.ConditionalDebug($"{emotes.Count} new emote configurations");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public class CustomEmotes : MonoBehaviour
|
|
||||||
{
|
|
||||||
private static readonly ConcurrentQueue<Action> mainThreadQueue = new ConcurrentQueue<Action>();
|
|
||||||
|
|
||||||
public void Start()
|
|
||||||
{
|
|
||||||
if (ServerPatchesConfig.CustomEmotes.Value)
|
|
||||||
RecNetInteractions.postAuthenticationActions.Add(DownloadCustomEmotes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
while (mainThreadQueue.TryDequeue(out var action))
|
|
||||||
{
|
|
||||||
try { action(); }
|
|
||||||
catch (Exception ex) { UniversalPatchPlugin.Log.LogError(ex); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DownloadCustomEmotes()
|
void DownloadCustomEmotes()
|
||||||
{
|
{
|
||||||
RecNetInteractions.SendRequest<List<EmoteConfigDTO>>(BestHTTP.HTTPMethods.Get, RecNet.Service.API, "/api/undead/v1/emotes", EmoteConfig.Patch);
|
RecNetInteractions.SendRequest<List<EmoteConfigDTO>>(HTTPMethods.Get, RecNet.Service.API, "/api/undead/v1/emotes", Patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
67
Core/Content/CustomRecNet/CustomPhoton/CustomPhoton.cs
Normal file
67
Core/Content/CustomRecNet/CustomPhoton/CustomPhoton.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using BestHTTP;
|
||||||
|
using Il2CppInterop.Runtime;
|
||||||
|
using undead_universal_patch_il2cpp.Core.Config;
|
||||||
|
using undead_universal_patch_il2cpp.Patches.Photon;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace undead_universal_patch_il2cpp.Core.Content.CustomRecNet.CustomPhoton;
|
||||||
|
|
||||||
|
public class PhotonConfigDTO
|
||||||
|
{
|
||||||
|
public bool Logging { get; set; }
|
||||||
|
public string AppID { get; set; }
|
||||||
|
public string VoiceAppID { get; set; }
|
||||||
|
public bool SelfHosted { get; set; }
|
||||||
|
public string ServerAddress { get; set; }
|
||||||
|
public int ServerPort { get; set; }
|
||||||
|
public byte ConnectionProtocol { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CustomPhoton : MonoBehaviour
|
||||||
|
{
|
||||||
|
public static bool ServerConfigFailed { get; set; } = false;
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
RecNetInteractions.postLocalAccountActions.Add(DownloadServerConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnServerConfigFailed(HTTPResponse res)
|
||||||
|
{
|
||||||
|
ServerConfigFailed = true;
|
||||||
|
if (PhotonConfig.PatchPhotonIds.Value)
|
||||||
|
{
|
||||||
|
UniversalPatchPlugin.Log.LogInfo("Attempting Photon patch from local configuration");
|
||||||
|
PhotonPatch.Patch(new PhotonConfigDTO
|
||||||
|
{
|
||||||
|
Logging = PhotonConfig.PunLogging.Value,
|
||||||
|
AppID = PhotonConfig.AppID.Value,
|
||||||
|
VoiceAppID = PhotonConfig.VoiceAppID.Value,
|
||||||
|
SelfHosted = PhotonConfig.SelfHosted.Value,
|
||||||
|
ServerAddress = PhotonConfig.ServerAddress.Value,
|
||||||
|
ServerPort = PhotonConfig.ServerPort.Value,
|
||||||
|
ConnectionProtocol = PhotonConfig.ConnectionProtocol.Value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ApplyPhotonConfig(HTTPResponse res, PhotonConfigDTO photonConfig)
|
||||||
|
{
|
||||||
|
if (!ServerPatchesConfig.CustomPhoton.Value) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UniversalPatchPlugin.Log.LogInfo("Attempting Photon patch from server configuration");
|
||||||
|
PhotonPatch.Patch(photonConfig);
|
||||||
|
}
|
||||||
|
catch (Exception err)
|
||||||
|
{
|
||||||
|
UniversalPatchPlugin.Log.LogError($"Failed to apply Photon configuration from server: {err}");
|
||||||
|
OnServerConfigFailed(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void DownloadServerConfig()
|
||||||
|
{
|
||||||
|
RecNetInteractions.SendRequest<PhotonConfigDTO>(HTTPMethods.Get, RecNet.Service.API, "/api/undead/v1/photon", ApplyPhotonConfig, OnServerConfigFailed);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,16 +4,17 @@ using System.Text.Json;
|
|||||||
using BestHTTP;
|
using BestHTTP;
|
||||||
using Il2CppInterop.Runtime;
|
using Il2CppInterop.Runtime;
|
||||||
using RecNet;
|
using RecNet;
|
||||||
using RecRoom.Async;
|
|
||||||
|
|
||||||
namespace undead_universal_patch_il2cpp.Core.CustomRecNet;
|
namespace undead_universal_patch_il2cpp.Core.Content.CustomRecNet;
|
||||||
|
|
||||||
public class RecNetInteractions
|
public class RecNetInteractions
|
||||||
{
|
{
|
||||||
|
public static int AccountId { get; set; }
|
||||||
public static string AccessToken { get; set; }
|
public static string AccessToken { get; set; }
|
||||||
|
|
||||||
public static List<Action> postNameServerActions = [];
|
public static List<Action> postNameServerActions = [];
|
||||||
public static List<Action> postAuthenticationActions = [];
|
public static List<Action> postAuthenticationActions = [];
|
||||||
|
public static List<Action> postLocalAccountActions = [];
|
||||||
|
|
||||||
public static Il2CppSystem.Uri CreateServiceUri(Service service, string pathAndQuery)
|
public static Il2CppSystem.Uri CreateServiceUri(Service service, string pathAndQuery)
|
||||||
{
|
{
|
||||||
@@ -28,7 +29,7 @@ public class RecNetInteractions
|
|||||||
return RecNet.Core.ServiceUris.Count > 1;
|
return RecNet.Core.ServiceUris.Count > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendRequest<T>(HTTPMethods method, Service service, string requestUri, Action<T> reqFinished)
|
public static void SendRequest<T>(HTTPMethods method, Service service, string requestUri, Action<HTTPResponse, T> reqFinished, Action<HTTPResponse>? reqFailed = null)
|
||||||
{
|
{
|
||||||
var res = RecNet.Core.SendRequest(method, service, requestUri);
|
var res = RecNet.Core.SendRequest(method, service, requestUri);
|
||||||
|
|
||||||
@@ -37,11 +38,12 @@ public class RecNetInteractions
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var data = JsonSerializer.Deserialize<T>(res.DataAsText);
|
var data = JsonSerializer.Deserialize<T>(res.DataAsText);
|
||||||
reqFinished(data);
|
reqFinished(res, data);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
UniversalPatchPlugin.Log.LogError($"'{requestUri}' failed\n{ex}");
|
UniversalPatchPlugin.Log.LogError($"'{requestUri}' failed\n{ex}");
|
||||||
|
if (reqFailed != null) reqFailed(res);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using RecRoom.Tools;
|
using RecRoom.Tools;
|
||||||
|
|
||||||
namespace undead_universal_patch_il2cpp.Core.UndeadGameManager;
|
namespace undead_universal_patch_il2cpp.Core.Content.UndeadGameManager;
|
||||||
|
|
||||||
public class AutoHealSettingsDTO
|
public class AutoHealSettingsDTO
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace undead_universal_patch_il2cpp.Core.UndeadGameManager;
|
namespace undead_universal_patch_il2cpp.Core.Content.UndeadGameManager;
|
||||||
|
|
||||||
public static class GameConfigurator
|
public static class GameConfigurator
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace undead_universal_patch_il2cpp.Core.UndeadGameManager;
|
namespace undead_universal_patch_il2cpp.Core.Content.UndeadGameManager;
|
||||||
|
|
||||||
public static class GameFreeSpawns
|
public static class GameFreeSpawns
|
||||||
{
|
{
|
||||||
29
Core/Init.cs
29
Core/Init.cs
@@ -4,8 +4,10 @@ using System.Linq;
|
|||||||
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using undead_universal_patch_il2cpp.Core.Config;
|
using undead_universal_patch_il2cpp.Core.Config;
|
||||||
using undead_universal_patch_il2cpp.Core.CustomRecNet.CustomEmotes;
|
using undead_universal_patch_il2cpp.Core.Content.CustomRecNet.CustomEmotes;
|
||||||
using undead_universal_patch_il2cpp.Core.UndeadGameManager;
|
using undead_universal_patch_il2cpp.Core.Content.CustomRecNet.CustomPhoton;
|
||||||
|
using undead_universal_patch_il2cpp.Core.Content.UndeadGameManager;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace undead_universal_patch_il2cpp.Core;
|
namespace undead_universal_patch_il2cpp.Core;
|
||||||
|
|
||||||
@@ -13,8 +15,6 @@ public class Initialization
|
|||||||
{
|
{
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
Util.LocalInstanceGuid = Guid.NewGuid().ToString();
|
|
||||||
|
|
||||||
AddMapsterGlobalTypeConfigs();
|
AddMapsterGlobalTypeConfigs();
|
||||||
FetchConfigurations();
|
FetchConfigurations();
|
||||||
AttachGameObjects();
|
AttachGameObjects();
|
||||||
@@ -55,7 +55,9 @@ public class Initialization
|
|||||||
private static void AttachGameObjects()
|
private static void AttachGameObjects()
|
||||||
{
|
{
|
||||||
UniversalPatchPlugin.Log.LogInfo("Attaching game objects");
|
UniversalPatchPlugin.Log.LogInfo("Attaching game objects");
|
||||||
UniversalPatchPlugin.Instance.AddComponent<CustomEmotes>();
|
|
||||||
|
if (ServerPatchesConfig.CustomEmotes.Value) UniversalPatchPlugin.Instance.AddComponent<CustomEmotes>();
|
||||||
|
UniversalPatchPlugin.Instance.AddComponent<CustomPhoton>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void FetchConfigurations()
|
private static void FetchConfigurations()
|
||||||
@@ -70,7 +72,7 @@ public class Initialization
|
|||||||
"The game expects a certain certificate from rec.net when making HTTPS requests. Enable this to allow any valid certificate.");
|
"The game expects a certain certificate from rec.net when making HTTPS requests. Enable this to allow any valid certificate.");
|
||||||
PatchConfig.HilePatch = UniversalPatchPlugin.Instance.Config.Bind("Generic", "HilePatch", PatchConfigDefaults.HilePatch,
|
PatchConfig.HilePatch = UniversalPatchPlugin.Instance.Config.Bind("Generic", "HilePatch", PatchConfigDefaults.HilePatch,
|
||||||
"The game will close after a short period of time if BepInEx is found. Enable to stop this from happening." +
|
"The game will close after a short period of time if BepInEx is found. Enable to stop this from happening." +
|
||||||
"This will also enable the AGRoomRuntimeConfig patch. See the README for more info.");
|
"\nThis will also enable the AGRoomRuntimeConfig patch. See the README for more info.");
|
||||||
PatchConfig.SignalRHandshakeFix = UniversalPatchPlugin.Instance.Config.Bind("Generic", "SignalRHandshakeFix", PatchConfigDefaults.SignalRHandshakeFix,
|
PatchConfig.SignalRHandshakeFix = UniversalPatchPlugin.Instance.Config.Bind("Generic", "SignalRHandshakeFix", PatchConfigDefaults.SignalRHandshakeFix,
|
||||||
"Replace apostrophes with quotes in the initial SignalR handshake.");
|
"Replace apostrophes with quotes in the initial SignalR handshake.");
|
||||||
PatchConfig.ImageSignaturePatch = UniversalPatchPlugin.Instance.Config.Bind("Generic", "ImageSignaturePatch", PatchConfigDefaults.ImageSignaturePatch,
|
PatchConfig.ImageSignaturePatch = UniversalPatchPlugin.Instance.Config.Bind("Generic", "ImageSignaturePatch", PatchConfigDefaults.ImageSignaturePatch,
|
||||||
@@ -83,6 +85,10 @@ public class Initialization
|
|||||||
|
|
||||||
ServerPatchesConfig.CustomEmotes = UniversalPatchPlugin.Instance.Config.Bind("ServerPatches", "CustomEmotes", ServerPatchesConfigDefaults.CustomEmotes,
|
ServerPatchesConfig.CustomEmotes = UniversalPatchPlugin.Instance.Config.Bind("ServerPatches", "CustomEmotes", ServerPatchesConfigDefaults.CustomEmotes,
|
||||||
"Modify the game's emote text with a configuration from the server. Requires a custom server.");
|
"Modify the game's emote text with a configuration from the server. Requires a custom server.");
|
||||||
|
ServerPatchesConfig.CustomPhoton = UniversalPatchPlugin.Instance.Config.Bind("ServerPatches", "CustomPhoton", ServerPatchesConfigDefaults.CustomPhoton,
|
||||||
|
"Patch ServerSettings values with a configuration from the server." +
|
||||||
|
"\nWhen the server fails to provide a valid configuration, values from the local config will be used." +
|
||||||
|
"\nPhoton.PatchPhotonIds must be enabled for this fallback to work.");
|
||||||
|
|
||||||
GameManagerConfig.AnyGameFreeSpawn = UniversalPatchPlugin.Instance.Config.Bind("GameManagerConfig", "AnyGameFreeSpawn", GameManagerConfigDefaults.AnyGameFreeSpawn,
|
GameManagerConfig.AnyGameFreeSpawn = UniversalPatchPlugin.Instance.Config.Bind("GameManagerConfig", "AnyGameFreeSpawn", GameManagerConfigDefaults.AnyGameFreeSpawn,
|
||||||
$"Use patches from '{GameFreeSpawns.config.path}' to spawn in any valid player spawnpoint in specified games. See README.md");
|
$"Use patches from '{GameFreeSpawns.config.path}' to spawn in any valid player spawnpoint in specified games. See README.md");
|
||||||
@@ -103,9 +109,14 @@ public class Initialization
|
|||||||
"The new target Voice App ID from the Photon dashboard." +
|
"The new target Voice App ID from the Photon dashboard." +
|
||||||
"\nWhen self-hosting, this value is ignored, since Photon voice in Rec Room is based on PUN.");
|
"\nWhen self-hosting, this value is ignored, since Photon voice in Rec Room is based on PUN.");
|
||||||
PhotonConfig.ServerAddress = UniversalPatchPlugin.Instance.Config.Bind("Photon", "ServerAddress", PhotonConfigDefaults.ServerAddress,
|
PhotonConfig.ServerAddress = UniversalPatchPlugin.Instance.Config.Bind("Photon", "ServerAddress", PhotonConfigDefaults.ServerAddress,
|
||||||
"Address of the Photon master server (ignored if not using self-hosted)");
|
"Address of the Photon target server (ignored if not using self-hosted)");
|
||||||
PhotonConfig.ServerPort = UniversalPatchPlugin.Instance.Config.Bind("Photon", "ServerPort", PhotonConfigDefaults.ServerPort,
|
PhotonConfig.ServerPort = UniversalPatchPlugin.Instance.Config.Bind("Photon", "ServerPort", PhotonConfigDefaults.ServerPort,
|
||||||
"Photon master server UDP port (ignored if not using self-hosted)");
|
"Photon target server port (ignored if not using self-hosted)." +
|
||||||
|
"\nYou can set this port to the matching protocol port from the server, e.g. 5055 for UDP, 9091 for WebSockets");
|
||||||
|
PhotonConfig.ConnectionProtocol = UniversalPatchPlugin.Instance.Config.Bind("Photon", "ConnectionProtocol", PhotonConfigDefaults.ConnectionProtocol,
|
||||||
|
"Connection protocol to use when connecting to the target port (ignored if not using self-hosted)." +
|
||||||
|
"\n0: UDP, 1: TCP;" +
|
||||||
|
"\nWebSockets are not supported by Photon in this build.");
|
||||||
|
|
||||||
NameserverConfig.Rewrite = UniversalPatchPlugin.Instance.Config.Bind("Nameserver", "Rewrite", NameserverConfigDefaults.Rewrite,
|
NameserverConfig.Rewrite = UniversalPatchPlugin.Instance.Config.Bind("Nameserver", "Rewrite", NameserverConfigDefaults.Rewrite,
|
||||||
"Enable/disable rewriting the URL for nameserver requests.");
|
"Enable/disable rewriting the URL for nameserver requests.");
|
||||||
@@ -118,9 +129,11 @@ public class Initialization
|
|||||||
TypeAdapterConfig.GlobalSettings
|
TypeAdapterConfig.GlobalSettings
|
||||||
.ForType<List<TeamConfigurationDTO>, Il2CppStructArray<TeamConfiguration>>()
|
.ForType<List<TeamConfigurationDTO>, Il2CppStructArray<TeamConfiguration>>()
|
||||||
.MapWith(src => new Il2CppStructArray<TeamConfiguration>(src.Select(x => x.Adapt<TeamConfiguration>()).ToArray()));
|
.MapWith(src => new Il2CppStructArray<TeamConfiguration>(src.Select(x => x.Adapt<TeamConfiguration>()).ToArray()));
|
||||||
|
|
||||||
TypeAdapterConfig.GlobalSettings
|
TypeAdapterConfig.GlobalSettings
|
||||||
.ForType<List<StatConfigurationDTO>, Il2CppReferenceArray<StatConfiguration>>()
|
.ForType<List<StatConfigurationDTO>, Il2CppReferenceArray<StatConfiguration>>()
|
||||||
.MapWith(src => new Il2CppReferenceArray<StatConfiguration>(src.Select(x => x.Adapt<StatConfiguration>()).ToArray()));
|
.MapWith(src => new Il2CppReferenceArray<StatConfiguration>(src.Select(x => x.Adapt<StatConfiguration>()).ToArray()));
|
||||||
|
|
||||||
TypeAdapterConfig.GlobalSettings
|
TypeAdapterConfig.GlobalSettings
|
||||||
.ForType<EmoteConfigDTO, RecRoom.AGUI.Expresso.ContextualEmotesConfig.ExpressoEmote>()
|
.ForType<EmoteConfigDTO, RecRoom.AGUI.Expresso.ContextualEmotesConfig.ExpressoEmote>()
|
||||||
.Map(dest => dest.emoteUniqueName, source => source.UniqueName)
|
.Map(dest => dest.emoteUniqueName, source => source.UniqueName)
|
||||||
|
|||||||
19
Core/Util.cs
19
Core/Util.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using BepInEx.Configuration;
|
using BepInEx.Configuration;
|
||||||
|
using CodeStage.AntiCheat.ObscuredTypes;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using undead_universal_patch_il2cpp.Core.Config;
|
using undead_universal_patch_il2cpp.Core.Config;
|
||||||
|
|
||||||
@@ -16,6 +17,22 @@ namespace undead_universal_patch_il2cpp.Core
|
|||||||
public bool Success;
|
public bool Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class RecNetUtil
|
||||||
|
{
|
||||||
|
public static ObscuredInt GetAccountId()
|
||||||
|
{
|
||||||
|
PropertyInfo selfAccountProp = AccessTools.Property("RecNet.Accounts:LocalAccount");
|
||||||
|
|
||||||
|
object acc = selfAccountProp.GetValue(null);
|
||||||
|
Type selfAccountType = acc.GetType();
|
||||||
|
|
||||||
|
PropertyInfo accountIdProp = AccessTools.Property(selfAccountType, "AccountId");
|
||||||
|
ObscuredInt val = (ObscuredInt)accountIdProp.GetValue(acc);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class Util
|
public class Util
|
||||||
{
|
{
|
||||||
private static readonly PatchTypesResult UnsuccessfulPatchResult = new()
|
private static readonly PatchTypesResult UnsuccessfulPatchResult = new()
|
||||||
@@ -25,8 +42,6 @@ namespace undead_universal_patch_il2cpp.Core
|
|||||||
Success = false
|
Success = false
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string LocalInstanceGuid { set; get; }
|
|
||||||
|
|
||||||
public static void ConditionalDebug(string msg)
|
public static void ConditionalDebug(string msg)
|
||||||
{
|
{
|
||||||
if (GenericConfig.PatchDebug.Value) UniversalPatchPlugin.Log.LogDebug(msg);
|
if (GenericConfig.PatchDebug.Value) UniversalPatchPlugin.Log.LogDebug(msg);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using System.Reflection;
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using undead_universal_patch_il2cpp.Core;
|
using undead_universal_patch_il2cpp.Core;
|
||||||
using undead_universal_patch_il2cpp.Core.Config;
|
using undead_universal_patch_il2cpp.Core.Config;
|
||||||
using undead_universal_patch_il2cpp.Core.UndeadGameManager;
|
using undead_universal_patch_il2cpp.Core.Content.UndeadGameManager;
|
||||||
|
|
||||||
namespace undead_universal_patch_il2cpp.Patches.UndeadGameManager;
|
namespace undead_universal_patch_il2cpp.Patches.UndeadGameManager;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using Mapster;
|
|||||||
using RecRoom.Core.GameManagement;
|
using RecRoom.Core.GameManagement;
|
||||||
using undead_universal_patch_il2cpp.Core.Config;
|
using undead_universal_patch_il2cpp.Core.Config;
|
||||||
using undead_universal_patch_il2cpp.Core;
|
using undead_universal_patch_il2cpp.Core;
|
||||||
using undead_universal_patch_il2cpp.Core.UndeadGameManager;
|
using undead_universal_patch_il2cpp.Core.Content.UndeadGameManager;
|
||||||
|
|
||||||
namespace undead_universal_patch_il2cpp.Patches.UndeadGameManager;
|
namespace undead_universal_patch_il2cpp.Patches.UndeadGameManager;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using Il2CppInterop.Runtime;
|
|
||||||
using RecRoom.Async;
|
|
||||||
using undead_universal_patch_il2cpp.Core;
|
using undead_universal_patch_il2cpp.Core;
|
||||||
using undead_universal_patch_il2cpp.Core.CustomRecNet;
|
using undead_universal_patch_il2cpp.Core.Content.CustomRecNet;
|
||||||
|
|
||||||
namespace undead_universal_patch_il2cpp.Patches;
|
namespace undead_universal_patch_il2cpp.Patches.Internals;
|
||||||
|
|
||||||
[HarmonyPatch]
|
[HarmonyPatch]
|
||||||
public class AuthenticationEventPatch
|
public class AuthenticationEventPatch
|
||||||
@@ -24,7 +22,6 @@ public class AuthenticationEventPatch
|
|||||||
|
|
||||||
static MethodBase TargetMethod() => patchResult.Method;
|
static MethodBase TargetMethod() => patchResult.Method;
|
||||||
|
|
||||||
|
|
||||||
private static bool RanPostActions { get; set; } = false;
|
private static bool RanPostActions { get; set; } = false;
|
||||||
static void Postfix(ref string accessToken)
|
static void Postfix(ref string accessToken)
|
||||||
{
|
{
|
||||||
32
Patches/Internals/PostGetMyAccount.cs
Normal file
32
Patches/Internals/PostGetMyAccount.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using BestHTTP;
|
||||||
|
using HarmonyLib;
|
||||||
|
using Il2CppInterop.Runtime;
|
||||||
|
using RecRoom.Async;
|
||||||
|
using undead_universal_patch_il2cpp.Core;
|
||||||
|
using undead_universal_patch_il2cpp.Core.Content.CustomRecNet;
|
||||||
|
|
||||||
|
namespace undead_universal_patch_il2cpp.Patches.Internals;
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class GetMyAccountEventPatch
|
||||||
|
{
|
||||||
|
static PatchTypesResult patchResult = Util.PreparePatchTypes(
|
||||||
|
"RecNet GetLocalAccount event patch",
|
||||||
|
"RecNet.Accounts",
|
||||||
|
"GetLocalAccount"
|
||||||
|
);
|
||||||
|
|
||||||
|
static bool Prepare() => patchResult.Success;
|
||||||
|
|
||||||
|
static MethodBase TargetMethod() => patchResult.Method;
|
||||||
|
|
||||||
|
static void Postfix(ref IPromise<RecNet.SelfAccount> __result)
|
||||||
|
{
|
||||||
|
__result.Then(DelegateSupport.ConvertDelegate<Il2CppSystem.Action>(() =>
|
||||||
|
{
|
||||||
|
UniversalPatchPlugin.Log.LogInfo("Running post-GetLocalAccount actions");
|
||||||
|
foreach (var action in RecNetInteractions.postLocalAccountActions) action();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using HarmonyLib;
|
||||||
using Il2CppInterop.Runtime;
|
using Il2CppInterop.Runtime;
|
||||||
using RecRoom.Async;
|
using RecRoom.Async;
|
||||||
using undead_universal_patch_il2cpp.Core;
|
using undead_universal_patch_il2cpp.Core;
|
||||||
using undead_universal_patch_il2cpp.Core.CustomRecNet;
|
using undead_universal_patch_il2cpp.Core.Content.CustomRecNet;
|
||||||
|
|
||||||
namespace undead_universal_patch_il2cpp.Patches;
|
namespace undead_universal_patch_il2cpp.Patches.Internals;
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
public class NameserverConnectEventPatch
|
public class NameserverConnectEventPatch
|
||||||
{
|
{
|
||||||
static PatchTypesResult patchResult = Util.PreparePatchTypes(
|
static PatchTypesResult patchResult = Util.PreparePatchTypes(
|
||||||
@@ -25,7 +27,7 @@ public class NameserverConnectEventPatch
|
|||||||
if (RecNetInteractions.HasNameserverConnected())
|
if (RecNetInteractions.HasNameserverConnected())
|
||||||
{
|
{
|
||||||
UniversalPatchPlugin.Log.LogInfo("Running post-nameserver actions");
|
UniversalPatchPlugin.Log.LogInfo("Running post-nameserver actions");
|
||||||
foreach (var action in RecNetInteractions.postAuthenticationActions) action();
|
foreach (var action in RecNetInteractions.postNameServerActions) action();
|
||||||
}
|
}
|
||||||
else Util.ConditionalDebug("The nameserver request did not resolve successfully, skipping post-nameserver actions.");
|
else Util.ConditionalDebug("The nameserver request did not resolve successfully, skipping post-nameserver actions.");
|
||||||
}));
|
}));
|
||||||
18
Patches/Photon/NameserverTest.cs
Normal file
18
Patches/Photon/NameserverTest.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using HarmonyLib;
|
||||||
|
using undead_universal_patch_il2cpp.Core;
|
||||||
|
|
||||||
|
namespace undead_universal_patch_il2cpp.Patches.Photon;
|
||||||
|
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class NameserverTest
|
||||||
|
{
|
||||||
|
static PatchTypesResult patchTypesResult = Util.PreparePatchTypes(
|
||||||
|
"Photon nameserver test",
|
||||||
|
"NetworkingPeer",
|
||||||
|
"GetNameServerAddress"
|
||||||
|
);
|
||||||
|
|
||||||
|
static bool Prepare() => patchTypesResult.Success;
|
||||||
|
static MethodBase TargetMethod() => patchTypesResult.Method;
|
||||||
|
}
|
||||||
108
Patches/Photon/PUNNetworkManager.cs
Normal file
108
Patches/Photon/PUNNetworkManager.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
93
Patches/Photon/PhotonPatch.cs
Normal file
93
Patches/Photon/PhotonPatch.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using System;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class PhotonPatch
|
||||||
|
{
|
||||||
|
public static void Patch(PhotonConfigDTO photonConfig)
|
||||||
|
{
|
||||||
|
// It's fine to reference enums after we're pretty sure the relevant types exist
|
||||||
|
// i think
|
||||||
|
Type photonNetworkType = AccessTools.TypeByName("PhotonNetwork");
|
||||||
|
Type serverSettingsType = AccessTools.TypeByName("ServerSettings");
|
||||||
|
|
||||||
|
if (photonNetworkType == null || serverSettingsType == null)
|
||||||
|
{
|
||||||
|
UniversalPatchPlugin.Log.LogError("Cannot patch Photon: PhotonNetwork or ServerSettings types were not found. Is this build supported?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyInfo photonServerSettingsProperty = photonNetworkType.GetRuntimeProperty("PhotonServerSettings");
|
||||||
|
object serverSettings = photonServerSettingsProperty.GetValue(serverSettingsType);
|
||||||
|
|
||||||
|
if (PhotonConfig.PunLogging.Value)
|
||||||
|
{
|
||||||
|
PropertyInfo loggingProperty = serverSettingsType.GetRuntimeProperty("PunLogging");
|
||||||
|
loggingProperty.SetValue(serverSettings, PhotonLogLevel.Full);
|
||||||
|
PropertyInfo networkLoggingProperty = serverSettingsType.GetRuntimeProperty("NetworkLogging");
|
||||||
|
networkLoggingProperty.SetValue(serverSettings, ExitGames.Client.Photon.DebugLevel.ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyInfo appIdProperty = serverSettingsType.GetRuntimeProperty("AppID");
|
||||||
|
PropertyInfo voiceAppIdProperty = serverSettingsType.GetRuntimeProperty("VoiceAppID");
|
||||||
|
|
||||||
|
Util.ConditionalDebug($"New Photon AppID: '{photonConfig.AppID}'");
|
||||||
|
Util.ConditionalDebug($"New Photon AppID: '{photonConfig.VoiceAppID}'");
|
||||||
|
appIdProperty.SetValue(serverSettings, photonConfig.AppID);
|
||||||
|
voiceAppIdProperty.SetValue(serverSettings, photonConfig.VoiceAppID);
|
||||||
|
|
||||||
|
if (photonConfig.SelfHosted)
|
||||||
|
{
|
||||||
|
MethodInfo useMyServerMethod = serverSettingsType.GetMethod("UseMyServer");
|
||||||
|
useMyServerMethod.Invoke(serverSettings, [
|
||||||
|
photonConfig.ServerAddress,
|
||||||
|
photonConfig.ServerPort,
|
||||||
|
photonConfig.AppID,
|
||||||
|
]);
|
||||||
|
|
||||||
|
Type authValuesType = AccessTools.TypeByName("AuthenticationValues");
|
||||||
|
if (authValuesType != null)
|
||||||
|
{
|
||||||
|
PropertyInfo networkingPeerProperty = photonNetworkType.GetRuntimeProperty("networkingPeer");
|
||||||
|
if (networkingPeerProperty == null)
|
||||||
|
{
|
||||||
|
UniversalPatchPlugin.Log.LogError("Cannot continue to patch Photon: networkingPeerProperty was null. Is this build supported?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (networkingPeerProperty.GetValue(null) == null)
|
||||||
|
{
|
||||||
|
UniversalPatchPlugin.Log.LogError("Cannot continue to patch Photon: networkingPeerInstance was null. Is this build supported?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int id = RecNetUtil.GetAccountId();
|
||||||
|
PhotonNetwork.AuthValues = new AuthenticationValues
|
||||||
|
{
|
||||||
|
UserId = id.ToString()
|
||||||
|
};
|
||||||
|
|
||||||
|
Util.ConditionalDebug($"Set the authValues userId to {id}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Type connectionProtocolType = AccessTools.TypeByName("ExitGames.Client.Photon.ConnectionProtocol");
|
||||||
|
PropertyInfo protocolProp = serverSettingsType.GetRuntimeProperty("Protocol");
|
||||||
|
if (connectionProtocolType != null && protocolProp != null)
|
||||||
|
{
|
||||||
|
protocolProp.SetValue(serverSettings, photonConfig.ConnectionProtocol);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UniversalPatchPlugin.Log.LogError("Cannot continue to patch Photon: connectionProtocolType or protocolProp was null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UniversalPatchPlugin.Log.LogInfo($"Photon patch ({(photonConfig.SelfHosted ? "self-hosted" : "cloud")}) succeeded.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using HarmonyLib;
|
|
||||||
using undead_universal_patch_il2cpp.Core;
|
|
||||||
using undead_universal_patch_il2cpp.Core.Config;
|
|
||||||
|
|
||||||
namespace undead_universal_patch_il2cpp.Patches
|
|
||||||
{
|
|
||||||
[HarmonyPatch]
|
|
||||||
public class PhotonPatchEvent
|
|
||||||
{
|
|
||||||
static PatchTypesResult patchResult = Util.ConfigPreparePatchTypes(
|
|
||||||
PhotonConfig.PatchPhotonIds,
|
|
||||||
"Photon ConnectUsingSettings event path",
|
|
||||||
"PhotonNetwork",
|
|
||||||
"ConnectUsingSettings"
|
|
||||||
);
|
|
||||||
|
|
||||||
static bool Prepare() => patchResult.Success;
|
|
||||||
|
|
||||||
static MethodInfo TargetMethod() => patchResult.Method;
|
|
||||||
|
|
||||||
static void Prefix()
|
|
||||||
{
|
|
||||||
Util.ConditionalDebug("Attempting Photon patch");
|
|
||||||
PhotonPatch.Patch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[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)
|
|
||||||
{
|
|
||||||
__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("Forcing masterserver");
|
|
||||||
}
|
|
||||||
|
|
||||||
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("Masterserver regionId roundtrip");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PhotonPatch
|
|
||||||
{
|
|
||||||
public static void Patch()
|
|
||||||
{
|
|
||||||
// It's fine to reference enums after we're pretty sure the relevant types exist
|
|
||||||
// i think
|
|
||||||
Type photonNetworkType = AccessTools.TypeByName("PhotonNetwork");
|
|
||||||
Type serverSettingsType = AccessTools.TypeByName("ServerSettings");
|
|
||||||
|
|
||||||
if (photonNetworkType == null || serverSettingsType == null)
|
|
||||||
{
|
|
||||||
UniversalPatchPlugin.Log.LogError("Cannot patch Photon: PhotonNetwork or ServerSettings types were not found. Is this build supported?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyInfo photonServerSettingsProperty = photonNetworkType.GetRuntimeProperty("PhotonServerSettings");
|
|
||||||
object serverSettings = photonServerSettingsProperty.GetValue(serverSettingsType);
|
|
||||||
|
|
||||||
if (PhotonConfig.PunLogging.Value)
|
|
||||||
{
|
|
||||||
PropertyInfo loggingProperty = serverSettingsType.GetRuntimeProperty("PunLogging");
|
|
||||||
loggingProperty.SetValue(serverSettings, PhotonLogLevel.Full);
|
|
||||||
PropertyInfo networkLoggingProperty = serverSettingsType.GetRuntimeProperty("NetworkLogging");
|
|
||||||
networkLoggingProperty.SetValue(serverSettings, ExitGames.Client.Photon.DebugLevel.ALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyInfo appIdProperty = serverSettingsType.GetRuntimeProperty("AppID");
|
|
||||||
PropertyInfo voiceAppIdProperty = serverSettingsType.GetRuntimeProperty("VoiceAppID");
|
|
||||||
|
|
||||||
Util.ConditionalDebug($"New Photon AppID: '{PhotonConfig.AppID.Value}'");
|
|
||||||
Util.ConditionalDebug($"New Photon AppID: '{PhotonConfig.VoiceAppID.Value}'");
|
|
||||||
appIdProperty.SetValue(serverSettings, PhotonConfig.AppID.Value);
|
|
||||||
voiceAppIdProperty.SetValue(serverSettings, PhotonConfig.VoiceAppID.Value);
|
|
||||||
|
|
||||||
if (PhotonConfig.SelfHosted.Value)
|
|
||||||
{
|
|
||||||
MethodInfo useMyServerMethod = serverSettingsType.GetMethod("UseMyServer");
|
|
||||||
useMyServerMethod.Invoke(serverSettings, [
|
|
||||||
PhotonConfig.ServerAddress.Value,
|
|
||||||
PhotonConfig.ServerPort.Value,
|
|
||||||
PhotonConfig.AppID.Value,
|
|
||||||
]);
|
|
||||||
|
|
||||||
Type authValuesType = AccessTools.TypeByName("AuthenticationValues");
|
|
||||||
if (authValuesType != null)
|
|
||||||
{
|
|
||||||
PropertyInfo networkingPeerProperty = photonNetworkType.GetRuntimeProperty("networkingPeer");
|
|
||||||
if (networkingPeerProperty == null)
|
|
||||||
{
|
|
||||||
UniversalPatchPlugin.Log.LogError("Cannot patch Photon: networkingPeerProperty was null. Is this build supported?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (networkingPeerProperty.GetValue(null) == null)
|
|
||||||
{
|
|
||||||
UniversalPatchPlugin.Log.LogError("Cannot patch Photon: networkingPeerInstance was null. Is this build supported?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string id = Util.LocalInstanceGuid;
|
|
||||||
Util.ConditionalDebug($"Instance GUID is {id}");
|
|
||||||
|
|
||||||
PhotonNetwork.AuthValues = new AuthenticationValues
|
|
||||||
{
|
|
||||||
UserId = id
|
|
||||||
};
|
|
||||||
|
|
||||||
Util.ConditionalDebug($"Set the authValues userId to {id}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UniversalPatchPlugin.Log.LogInfo($"Photon patch ({(PhotonConfig.SelfHosted.Value ? "self-hosted" : "cloud")}) succeeded.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,7 @@ using undead_universal_patch_il2cpp.Core;
|
|||||||
|
|
||||||
namespace undead_universal_patch_il2cpp;
|
namespace undead_universal_patch_il2cpp;
|
||||||
|
|
||||||
[BepInPlugin("dev.proxnet.recroom.universalpatch.noneac.il2cpp", "Undead Universal Patch", "2.0.0")]
|
[BepInPlugin("dev.proxnet.recroom.universalpatch.noneac.il2cpp", "Undead Universal Patch", "2.1.0")]
|
||||||
public class UniversalPatchPlugin : BasePlugin
|
public class UniversalPatchPlugin : BasePlugin
|
||||||
{
|
{
|
||||||
public static new readonly ManualLogSource Log = Logger.CreateLogSource("UUPatch");
|
public static new readonly ManualLogSource Log = Logger.CreateLogSource("UUPatch");
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<AssemblyName>undead_universal_patch_il2cpp</AssemblyName>
|
<AssemblyName>undead_universal_patch_il2cpp</AssemblyName>
|
||||||
<Description>Non-EAC, IL2CPP build patcher for Rec Room (Late 2018*-*April 2020) </Description>
|
<Description>Non-EAC, IL2CPP build patcher for Rec Room (Late 2018*-*April 2020) </Description>
|
||||||
<Version>2.0.0</Version>
|
<Version>2.1.0</Version>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<RestoreAdditionalProjectSources>
|
<RestoreAdditionalProjectSources>
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.*" IncludeAssets="compile" />
|
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.*" IncludeAssets="compile" />
|
||||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||||
|
<PackageReference Include="WebSocketSharp" Version="1.0.3-rc11" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user