Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of VBNetTweaks v0.3.0
VBNetTweaks.dll
Decompiled 2 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Entities; using Jotunn.Extensions; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using VBNetTweaks.Patches; using VBNetTweaks.Utils; using VBNetTweaks.ZDOUtills; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("VBNetTweaks")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("VBNetTweaks")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("d9c87954-ce20-459d-81ec-96599caed427")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.9.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VBNetTweaks { [HarmonyPatch] public static class ShipSyncSystem { private class ShipData { public Vector3 pos; public Quaternion rot; public Vector3 vel; public float t; public bool ok; public long lastOwner; public float lastUpdateTime; } private class PlayerShipState { public Ship ship; public Vector3 localPos; public Quaternion localRot; public float lastUpdate; } private static readonly Dictionary<long, ShipData> _shipData; private static readonly Dictionary<long, PlayerShipState> _playerStates; private static readonly Dictionary<ZDOID, int> _playersOnShip; private static readonly Dictionary<long, ZDOID> _playerShipMap; private const float SMOOTH_POS_ON_SHIP = 0.35f; private const float SMOOTH_ROT_ON_SHIP = 0.25f; private const float SMOOTH_POS_OFF_SHIP = 0.25f; private const float SMOOTH_ROT_OFF_SHIP = 0.15f; private const float CORRECTION_THRESHOLD = 0.5f; private const float ROT_CORRECTION_THRESHOLD = 10f; private const string RPC_SYNC_SHIP = "VBNT.SyncShip"; static ShipSyncSystem() { _shipData = new Dictionary<long, ShipData>(); _playerStates = new Dictionary<long, PlayerShipState>(); _playersOnShip = new Dictionary<ZDOID, int>(); _playerShipMap = new Dictionary<long, ZDOID>(); if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register<long, ZDOID>("VBNT.SyncShip", (Action<long, long, ZDOID>)RPC_SyncShip); } } private static void SyncShip(long playerId, ZDOID shipId) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)ZNet.instance) && ZRoutedRpc.instance != null && playerId != 0) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "VBNT.SyncShip", new object[2] { playerId, shipId }); PlayerCache.UpdatePlayerState(playerId, PlayerCache.IsPlayerAttached(playerId), shipId); } } private static void RPC_SyncShip(long sender, long playerId, ZDOID shipId) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (sender != ZNet.GetUID()) { PlayerCache.UpdatePlayerState(playerId, PlayerCache.IsPlayerAttached(playerId), shipId); } } public static void CleanupPeer(long uid) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) lock (_shipData) { _shipData.Remove(uid); } lock (_playerStates) { if (_playerShipMap.TryGetValue(uid, out var value)) { if (_playersOnShip.TryGetValue(value, out var value2)) { if (value2 <= 1) { _playersOnShip.Remove(value); } else { _playersOnShip[value] = value2 - 1; } } _playerShipMap.Remove(uid); } _playerStates.Remove(uid); } PlayerCache.RemovePlayer(uid); } private static Ship GetShipUnderPlayer(Player p) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)p == (Object)null) { return null; } Vector3 val = ((Component)p).transform.position + Vector3.up * 0.2f; RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val, Vector3.down, ref val2, 2f)) { return ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Ship>(); } return null; } [HarmonyPatch(typeof(ZNetView), "Deserialize")] [HarmonyPostfix] public static void CaptureShipState(ZNetView __instance) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) if (Helper.IsServer() || (Object)(object)__instance == (Object)null) { return; } Ship component = ((Component)__instance).GetComponent<Ship>(); if ((Object)(object)component == (Object)null) { return; } ZDO zDO = __instance.GetZDO(); if (zDO == null || !zDO.IsValid()) { return; } long owner = zDO.GetOwner(); if (owner == 0L || owner == ZNet.GetUID()) { return; } Vector3 position = zDO.GetPosition(); Quaternion rotation = zDO.GetRotation(); float time = Time.time; if (!_shipData.TryGetValue(owner, out var value)) { value = new ShipData { pos = position, rot = rotation, t = time, ok = true, lastOwner = owner, lastUpdateTime = time }; _shipData[owner] = value; return; } if (value.lastOwner != owner) { value.vel = Vector3.zero; value.lastOwner = owner; value.lastUpdateTime = time; } float num = time - value.t; if (num > 0.01f && num < 0.5f) { Vector3 val = (position - value.pos) / num; value.vel = Vector3.Lerp(value.vel, val, 0.3f); } else if (num >= 0.5f) { value.vel = Vector3.zero; } value.pos = position; value.rot = rotation; value.t = time; value.ok = true; } [HarmonyPatch(typeof(Ship), "CustomFixedUpdate")] [HarmonyPostfix] public static void SmoothShip(Ship __instance) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) if (Helper.IsServer()) { return; } ZNetView nview = __instance.m_nview; ZDO val = ((nview != null) ? nview.GetZDO() : null); if (val == null) { return; } long owner = val.GetOwner(); if (owner == 0L || owner == ZNet.GetUID() || !_shipData.TryGetValue(owner, out var value) || !value.ok) { return; } Transform transform = ((Component)__instance).transform; float time = Time.time; float num = Mathf.Min(Time.deltaTime, 0.033f); Vector3 val2 = value.pos + value.vel * num; Vector3 val3 = val2 - transform.position; if (((Vector3)(ref val3)).magnitude > 5f) { val2 = transform.position + ((Vector3)(ref val3)).normalized * 5f; } Player localPlayer = Player.m_localPlayer; bool flag = PlayerCache.IsPlayerOnShip((localPlayer != null) ? localPlayer.GetPlayerID() : 0); float num2 = (flag ? 0.35f : 0.25f); float num3 = (flag ? 0.25f : 0.15f); float num4 = Vector3.Distance(transform.position, val2); if (num4 > 0.5f) { transform.position = val2; transform.rotation = value.rot; return; } float num5 = Quaternion.Angle(transform.rotation, value.rot); if (num5 > 10f) { transform.rotation = value.rot; } else { transform.rotation = Quaternion.Slerp(transform.rotation, value.rot, num3); } transform.position = Vector3.Lerp(transform.position, val2, num2); } [HarmonyPatch(typeof(Player), "Update")] [HarmonyPostfix] public static void TrackLocalPlayer(Player __instance) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } long playerID = __instance.GetPlayerID(); PlayerShipState value; Ship val = (_playerStates.TryGetValue(playerID, out value) ? value.ship : null); Ship shipUnderPlayer = GetShipUnderPlayer(__instance); if ((Object)(object)val == (Object)(object)shipUnderPlayer && Object.op_Implicit((Object)(object)shipUnderPlayer)) { if (_playerStates.TryGetValue(playerID, out var value2)) { value2.localPos = ((Component)shipUnderPlayer).transform.InverseTransformPoint(((Component)__instance).transform.position); value2.localRot = Quaternion.Inverse(((Component)shipUnderPlayer).transform.rotation) * ((Component)__instance).transform.rotation; value2.lastUpdate = Time.time; } return; } if (Object.op_Implicit((Object)(object)val)) { ZNetView nview = val.m_nview; ZDO val2 = ((nview != null) ? nview.GetZDO() : null); if (val2 != null) { ZDOID uid = val2.m_uid; if (_playersOnShip.TryGetValue(uid, out var value3)) { if (value3 <= 1) { _playersOnShip.Remove(uid); } else { _playersOnShip[uid] = value3 - 1; } } } } if (Object.op_Implicit((Object)(object)shipUnderPlayer)) { ZNetView nview2 = shipUnderPlayer.m_nview; ZDO val3 = ((nview2 != null) ? nview2.GetZDO() : null); if (val3 != null) { ZDOID uid2 = val3.m_uid; _playersOnShip[uid2] = ((!_playersOnShip.TryGetValue(uid2, out var value4)) ? 1 : (value4 + 1)); _playerShipMap[playerID] = uid2; } } if (!_playerStates.TryGetValue(playerID, out var value5)) { value5 = new PlayerShipState(); _playerStates[playerID] = value5; } value5.ship = shipUnderPlayer; if (Object.op_Implicit((Object)(object)shipUnderPlayer)) { value5.localPos = ((Component)shipUnderPlayer).transform.InverseTransformPoint(((Component)__instance).transform.position); value5.localRot = Quaternion.Inverse(((Component)shipUnderPlayer).transform.rotation) * ((Component)__instance).transform.rotation; } value5.lastUpdate = Time.time; if ((Object)(object)val != (Object)(object)shipUnderPlayer) { ZDOID? obj; if (shipUnderPlayer == null) { obj = null; } else { ZNetView nview3 = shipUnderPlayer.m_nview; obj = ((nview3 == null) ? null : nview3.GetZDO()?.m_uid); } ZDOID? val4 = obj; ZDOID valueOrDefault = val4.GetValueOrDefault(); SyncShip(playerID, valueOrDefault); } } [HarmonyPatch(typeof(Player), "LateUpdate")] [HarmonyPostfix] public static void LateUpdate_PlayerSync(Player __instance) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)(object)Player.m_localPlayer)) { long playerID = __instance.GetPlayerID(); if (_playerStates.TryGetValue(playerID, out var value) && !((Object)(object)value.ship == (Object)null) && !((Character)__instance).IsAttached()) { float num = 20f; Vector3 val = ((Component)value.ship).transform.TransformPoint(value.localPos); Quaternion val2 = ((Component)value.ship).transform.rotation * value.localRot; ((Component)__instance).transform.position = Vector3.Lerp(((Component)__instance).transform.position, val, Time.deltaTime * num); ((Component)__instance).transform.rotation = Quaternion.Slerp(((Component)__instance).transform.rotation, val2, Time.deltaTime * num); } } } } [BepInPlugin("VitByr.VBNetTweaks", "VBNetTweaks", "0.3.0")] [BepInIncompatibility("CacoFFF.valheim.LeanNet")] [BepInIncompatibility("redseiko.valheim.scenic")] [BepInIncompatibility("Searica.Valheim.NetworkTweaks")] [BepInIncompatibility("Searica.Valheim.OpenSesame")] [BepInIncompatibility("org.bepinex.plugins.network")] [BepInIncompatibility("CW_Jesse.BetterNetworking")] [BepInIncompatibility("com.Fire.FiresGhettoNetworkMod")] public class VBNetTweaks : BaseUnityPlugin { private const string ModName = "VBNetTweaks"; private const string ModVersion = "0.3.0"; private const string ModGUID = "VitByr.VBNetTweaks"; public CustomRPC _configSyncRPC; private ConfigFile _serverConfig; public static ConfigEntry<bool> ModEnabled; public static ConfigEntry<bool> DebugEnabled; public static ConfigEntry<bool> VerboseLogging; public static ConfigEntry<bool> ModuleSteamOptimizations; public static ConfigEntry<bool> ModuleShipSync; public static ConfigEntry<int> SteamSendRateMaxKB; public static ConfigEntry<int> SteamSendBufferSizeKB; public static ConfigEntry<float> SendInterval; public static ConfigEntry<int> PeersPerUpdate; public static ConfigEntry<int> ZDOQueueLimit; private Harmony _harmony; public static VBNetTweaks Instance { get; private set; } private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00ad: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown _serverConfig = new ConfigFile(Path.Combine(Paths.ConfigPath, "VitByr/VBNetTweaks/ServerConfig.cfg"), true); SynchronizationManager.Instance.RegisterCustomConfig(_serverConfig); Instance = this; ModEnabled = ConfigFileExtensions.BindConfig<bool>(_serverConfig, "00 - Master", "ModEnabled", true, "Полностью включить/выключить мод VBNetTweaks", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); if (ModEnabled.Value) { InitClientConfigs(); InitServerConfigs(); _configSyncRPC = NetworkManager.Instance.AddRPC("VBNetTweaks_ConfigSync", new CoroutineHandler(OnAdminConfigSync), new CoroutineHandler(OnClientConfigSync)); SynchronizationManager.Instance.AddInitialSynchronization(_configSyncRPC, (Func<ZPackage>)(() => BuildConfigPackage())); CreateConfigWatcher(); _harmony = new Harmony("VitByr.VBNetTweaks"); if (ModuleSteamOptimizations.Value) { _harmony.PatchAll(typeof(ZSteamSocket_Patchs)); } if (ModuleShipSync.Value) { _harmony.PatchAll(typeof(ShipSyncSystem)); } _harmony.PatchAll(typeof(PlayerCache)); _harmony.PatchAll(typeof(ZNet_Paths)); _harmony.PatchAll(typeof(NetworkSyncPatches)); _harmony.PatchAll(typeof(ZDONetworkOptimizer)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"VBNetTweaks загружен!"); if (DebugEnabled.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Режим отладки включен"); } } } private void InitClientConfigs() { string text = "01 - Debug"; DebugEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "DebugEnabled", false, "Включить отладочный вывод"); VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "VerboseLogging", false, "Включить подробное логирование"); } private void InitServerConfigs() { string text = "02 - Modules"; ModuleSteamOptimizations = ConfigFileExtensions.BindConfig<bool>(_serverConfig, text, "SteamOptimizations", true, "Оптимизации Steam сокета", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ModuleShipSync = ConfigFileExtensions.BindConfig<bool>(_serverConfig, text, "ShipSync", true, "Синхронизация кораблей", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); string text2 = "04 - Steam Settings"; ConfigFile serverConfig = _serverConfig; AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(256, 10240); SteamSendRateMaxKB = ConfigFileExtensions.BindConfig<int>(serverConfig, text2, "MaxRateKB", 4096, "Максимальная скорость отправки Steam (vanilla = 150 KB/s)", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile serverConfig2 = _serverConfig; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(512, 8192); SteamSendBufferSizeKB = ConfigFileExtensions.BindConfig<int>(serverConfig2, text2, "SendBufferSizeKB", 2048, "Размер буфера отправки Steam в KB (vanilla = ~260KB). Рекомендуется 1024-4096", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); string text3 = "05 - Server Settings"; ConfigFile serverConfig3 = _serverConfig; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.5f); SendInterval = ConfigFileExtensions.BindConfig<float>(serverConfig3, text3, "SendInterval", 0.03f, "Интервал отправки данных (vanilla = 0.05)", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile serverConfig4 = _serverConfig; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 200); PeersPerUpdate = ConfigFileExtensions.BindConfig<int>(serverConfig4, text3, "PeersPerUpdate", 30, "Количество пиров за один апдейт (vanilla = 1)", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ZDOQueueLimit = ConfigFileExtensions.BindConfig<int>(_serverConfig, text3, "ZDOQueueLimit", 20480, "Размер буфера отправки ZDO пакетов (vanilla = 10240 Kb)", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); } public ZPackage BuildConfigPackage() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown ZPackage val = new ZPackage(); try { val.Write(ModEnabled.Value); val.Write(ModuleSteamOptimizations.Value); val.Write(ModuleShipSync.Value); val.Write(SendInterval.Value); val.Write(PeersPerUpdate.Value); val.Write(ZDOQueueLimit.Value); } catch (Exception ex) { Debug.LogError((object)("[VBNetTweaks] Error building config package: " + ex.Message)); return new ZPackage(); } return val; } private void ApplyConfigFromPackage(ZPackage pkg) { if (pkg == null || pkg.GetArray().Length == 0) { Debug.LogWarning((object)"[VBNetTweaks] Received empty config package"); return; } try { pkg.SetPos(0); ModEnabled.Value = pkg.ReadBool(); ModuleSteamOptimizations.Value = pkg.ReadBool(); ModuleShipSync.Value = pkg.ReadBool(); SendInterval.Value = pkg.ReadSingle(); PeersPerUpdate.Value = pkg.ReadInt(); ZDOQueueLimit.Value = pkg.ReadInt(); } catch (Exception ex) { Debug.LogError((object)("[VBNetTweaks] Error applying config package: " + ex.Message)); } } private IEnumerator OnAdminConfigSync(long sender, ZPackage pkg) { if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer()) { yield break; } ZPackage serverConfigPkg = BuildConfigPackage(); byte[] data = serverConfigPkg.GetArray(); foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { ZPackage copyPkg = new ZPackage(data); _configSyncRPC.SendPackage(new List<ZNetPeer> { peer }, copyPkg); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"[VBNetTweaks] Server config broadcast to all clients"); } public IEnumerator OnClientConfigSync(long sender, ZPackage pkg) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[VBNetTweaks] Клиент получил конфиг от сервера {sender}"); ApplyConfigFromPackage(pkg); ConfigFileExtensions.SetSaveOnConfigSet(_serverConfig, true); _serverConfig.Save(); yield break; } private void CreateConfigWatcher() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown ConfigFileWatcher val = new ConfigFileWatcher(_serverConfig, 1000L); val.OnConfigFileReloaded += delegate { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { Debug.Log((object)"[VBNetTweaks] Server config changed, broadcasting to all clients"); ((MonoBehaviour)this).StartCoroutine(ApplyServerConfigChanges()); } }; } public IEnumerator ApplyServerConfigChanges() { yield return null; ZPackage pkg = BuildConfigPackage(); if (pkg.GetArray().Length != 0) { byte[] data = pkg.GetArray(); foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { ZPackage copyPkg = new ZPackage(data); _configSyncRPC.SendPackage(new List<ZNetPeer> { peer }, copyPkg); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"[VBNetTweaks] Server config broadcast to all clients"); } if (SendInterval.Value <= 0.001f) { SendInterval.Value = 0.03f; } if (PeersPerUpdate.Value <= 0) { PeersPerUpdate.Value = 30; } } private void OnDestroy() { _serverConfig.Save(); _harmony.UnpatchSelf(); } } } namespace VBNetTweaks.ZDOUtills { [HarmonyPatch] public static class ZDONetworkOptimizer { public static class NetworkMetrics { public static int ZdosSent { get; private set; } public static int ZdosReceived { get; private set; } public static void RecordZdoSent() { ZdosSent++; } public static void RecordZdoReceived() { ZdosReceived++; } } public static void OptimizedSendZDOToPeers(ZDOMan zdoManager, float dt) { try { int count = zdoManager.m_peers.Count; if (count <= 0) { return; } ZDOMan obj = zdoManager; obj.m_sendTimer += dt; float num = VBNetTweaks.SendInterval?.Value ?? 0.05f; if (zdoManager.m_sendTimer < num) { return; } zdoManager.m_sendTimer = 0f; int num2 = Mathf.Max(zdoManager.m_nextSendPeer, 0); int num3 = VBNetTweaks.PeersPerUpdate?.Value ?? 40; int num4 = 0; for (int i = 0; i < Mathf.Min(num3, count); i++) { int index = (num2 + i) % count; ZDOPeer peer = zdoManager.m_peers[index]; ZDOPeer obj2 = peer; if (obj2 == null) { continue; } ZNetPeer peer2 = obj2.m_peer; bool? obj3; if (peer2 == null) { obj3 = null; } else { ISocket socket = peer2.m_socket; obj3 = ((socket != null) ? new bool?(socket.IsConnected()) : null); } if (obj3 == true) { PerformanceMonitor.Track("SendZDOs", delegate { zdoManager.SendZDOs(peer, false); NetworkMetrics.RecordZdoSent(); }); num4++; } } zdoManager.m_nextSendPeer = (num2 + num4) % count; } catch (Exception ex) { ZLog.LogError((object)("[VBNetTweaks] ERROR in OptimizedSendZDOToPeers: " + ex.Message)); zdoManager.SendZDOToPeers2(dt); } } [HarmonyTranspiler] [HarmonyPatch(typeof(ZDOMan), "Update")] private static IEnumerable<CodeInstruction> ZDOManUpdateTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).Start(); val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(ZDOMan), "SendZDOToPeers2", (Type[])null, (Type[])null), (string)null) }); if (val.IsInvalid) { ZLog.LogError((object)"WARNING: SendZDOToPeers2 not found"); return instructions; } val.SetOperandAndAdvance((object)AccessTools.Method(typeof(ZDONetworkOptimizer), "OptimizedSendZDOToPeers", (Type[])null, (Type[])null)); return val.InstructionEnumeration(); } [HarmonyPrefix] [HarmonyPatch(typeof(ZNetScene), "RemoveObjects")] private static bool RemoveObjectsPrefix(ZNetScene __instance, List<ZDO> currentNearObjects, List<ZDO> currentDistantObjects) { if (!Object.op_Implicit((Object)(object)__instance) || __instance.m_instances == null || __instance.m_tempRemoved == null) { return true; } try { PerformanceMonitor.Track("PrepareRemoval", delegate { ZDORemoval.PrepareRemovalList(__instance, currentNearObjects, currentDistantObjects); }); return true; } catch (Exception ex) { ZLog.LogError((object)("[VBNetTweaks] Error in RemoveObjectsPrefix: " + ex.Message)); return true; } } } public class ZDORemoval { public static void PrepareRemovalList(ZNetScene scene, List<ZDO> near, List<ZDO> distant) { if (!Object.op_Implicit((Object)(object)scene)) { return; } byte b = (byte)((uint)Time.frameCount & 0xFFu); if (near != null) { foreach (ZDO item in near) { if (item != null) { item.TempRemoveEarmark = b; } } } if (distant != null) { foreach (ZDO item2 in distant) { if (item2 != null) { item2.TempRemoveEarmark = b; } } } Dictionary<ZDO, ZNetView> instances = scene.m_instances; List<ZNetView> tempRemoved = scene.m_tempRemoved; tempRemoved.Clear(); foreach (KeyValuePair<ZDO, ZNetView> item3 in instances) { ZDO key = item3.Key; ZNetView value = item3.Value; if (key != null && Object.op_Implicit((Object)(object)value) && key.TempRemoveEarmark != b) { tempRemoved.Add(value); } } } } } namespace VBNetTweaks.Patches { [HarmonyPatch] public static class NetworkSyncPatches { private const float SmoothPos = 0.22f; private const float SmoothRot = 0.45f; private const float MicroThreshold = 0.004f; private static bool _loggedSettings; private static float _teleportBoostEnd; public static void TriggerTeleportWindow() { _teleportBoostEnd = Time.time + 5f; } [HarmonyPatch(typeof(ZDOMan), "Update")] [HarmonyPostfix] private static void LogNetworkSettingsOnce() { if (!_loggedSettings && Object.op_Implicit((Object)(object)ZNet.instance)) { _loggedSettings = true; float num = VBNetTweaks.SendInterval?.Value ?? 0.05f; int num2 = VBNetTweaks.PeersPerUpdate?.Value ?? 20; Helper.LogVerbose($"[VBNetTweaks] Network Config Applied -> SendInterval: {num:F3}s ({1f / num:F1}Hz) | PeersPerUpdate: {num2}"); } } [HarmonyPatch(typeof(ZSyncTransform), "SyncPosition")] [HarmonyTranspiler] public static IEnumerable<CodeInstruction> SyncPosition_Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldc_R4) { float num = (float)list[i].operand; if (Mathf.Approximately(num, 0.2f)) { list[i].operand = 0.22f; } else if (Mathf.Approximately(num, 0.5f)) { list[i].operand = 0.45f; } else if (Mathf.Approximately(num, 0.001f)) { list[i].operand = 0.004f; } } } return list; } [HarmonyPatch(typeof(ZSyncTransform), "ClientSync")] [HarmonyTranspiler] public static IEnumerable<CodeInstruction> ClientSync_Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldc_R4) { float num = (float)list[i].operand; if (Mathf.Approximately(num, 0.2f)) { list[i].operand = 0.22f; } else if (Mathf.Approximately(num, 0.001f)) { list[i].operand = 0.004f; } else if (Mathf.Approximately(num, 0.01f)) { list[i].operand = 0.005f; } } } return list; } [HarmonyPatch(typeof(ZDOMan), "SendZDOs")] [HarmonyTranspiler] public static IEnumerable<CodeInstruction> SendZDOs_QueueLimitFix(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); int num = 0; for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldc_I4 && (int)list[i].operand == 10240) { list[i].operand = VBNetTweaks.ZDOQueueLimit.Value; num++; } } if (num < 2) { ZLog.LogWarning((object)"[VBNetTweaks] ZDOQueueLimit patch failed: found less than 2 instances of 10240!"); } else if (num == 2) { ZLog.LogWarning((object)$"[VBNetTweaks] ZDOQueueLimit patch to: {VBNetTweaks.ZDOQueueLimit.Value}"); } return list; } [HarmonyPatch(typeof(ZSyncTransform), "OwnerSync")] [HarmonyTranspiler] public static IEnumerable<CodeInstruction> OwnerSync_Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldc_R4 && Mathf.Approximately((float)list[i].operand, 0.001f)) { list[i].operand = 0.004f; } } return list; } [HarmonyPatch(typeof(ZNetScene), "InLoadingScreen")] [HarmonyPrefix] public static bool InLoadingScreen_Extend(ref bool __result) { if (Time.time < _teleportBoostEnd) { __result = true; return false; } return true; } [HarmonyPatch(typeof(ZNetScene), "CreateDestroyObjects")] [HarmonyPostfix] public static void CreateDestroyObjects_TriggerTeleport() { Player localPlayer = Player.m_localPlayer; if (localPlayer != null && ((Character)localPlayer).IsTeleporting()) { TriggerTeleportWindow(); } } } [HarmonyPatch] public static class ZSteamSocket_Patchs { private static bool _steamConfigApplied; private static float _lastApplyTime; private const float REAPPLY_INTERVAL = 30f; [HarmonyTranspiler] [HarmonyPatch(typeof(ZSteamSocket), "RegisterGlobalCallbacks")] private static IEnumerable<CodeInstruction> RegisterGlobalCallbacks_Transpiler(IEnumerable<CodeInstruction> instructions) { if (!VBNetTweaks.ModuleSteamOptimizations.Value) { return instructions; } List<CodeInstruction> list = new List<CodeInstruction>(instructions); bool flag = false; for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldc_I4 && (int)list[i].operand == 153600) { int num = Math.Max(64, VBNetTweaks.SteamSendRateMaxKB.Value) * 1024; list[i].operand = num; flag = true; ZLog.LogWarning((object)$"[VBNetTweaks] Steam rate patched: 153600 -> {num} bytes/s ({VBNetTweaks.SteamSendRateMaxKB.Value}KB/s)"); break; } } if (!flag) { ZLog.LogWarning((object)"[VBNetTweaks] Steam rate constant 153600 not found in IL!"); } return list; } [HarmonyPostfix] [HarmonyPatch(typeof(ZSteamSocket), "RegisterGlobalCallbacks")] private static void ApplySteamBuffersViaReflection() { if (!VBNetTweaks.ModuleSteamOptimizations.Value || (Time.time - _lastApplyTime < 30f && _steamConfigApplied)) { return; } _lastApplyTime = Time.time; try { ZLog.LogWarning((object)"[VBNetTweaks] Applying Steam buffer settings via reflection..."); Type type = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type type2 = assembly.GetType("Steamworks.SteamNetworkingUtils"); if (type2 != null) { type = type2; break; } type2 = assembly.GetType("Steamworks.SteamGameServerNetworkingUtils"); if (type2 != null) { type = type2; break; } } if (type == null) { ZLog.LogWarning((object)"[VBNetTweaks] SteamNetworkingUtils type not found, buffer settings skipped."); return; } MethodInfo setConfigMethod = type.GetMethod("SetConfigValue", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[5] { typeof(int), typeof(int), typeof(IntPtr), typeof(int), typeof(IntPtr) }, null); if (setConfigMethod == null) { ZLog.LogWarning((object)"[VBNetTweaks] SetConfigValue method not found, buffer settings skipped."); return; } Type configValueType = null; Type type3 = null; Type type4 = null; Assembly[] assemblies2 = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly2 in assemblies2) { if (configValueType == null) { configValueType = assembly2.GetType("Steamworks.ESteamNetworkingConfigValue"); } if (type3 == null) { type3 = assembly2.GetType("Steamworks.ESteamNetworkingConfigScope"); } if (type4 == null) { type4 = assembly2.GetType("Steamworks.ESteamNetworkingConfigDataType"); } if (configValueType != null && type3 != null && type4 != null) { break; } } if (configValueType == null || type3 == null || type4 == null) { ZLog.LogWarning((object)"[VBNetTweaks] Steam enums not found, buffer settings skipped."); return; } object globalScope = Enum.Parse(type3, "k_ESteamNetworkingConfig_Global"); object intDataType = Enum.Parse(type4, "k_ESteamNetworkingConfig_Int32"); int num = Math.Max(524288, VBNetTweaks.SteamSendBufferSizeKB.Value * 1024); SetConfigValue("k_ESteamNetworkingConfig_SendBufferSize", num); SetConfigValue("k_ESteamNetworkingConfig_RecvBufferSize", num); SetConfigValue("k_ESteamNetworkingConfig_RecvMaxMessageSize", 4194304); int num2 = Math.Max(262144, VBNetTweaks.SteamSendRateMaxKB.Value * 1024 / 2); SetConfigValue("k_ESteamNetworkingConfig_SendRateMin", num2); _steamConfigApplied = true; ZLog.LogWarning((object)$"[VBNetTweaks] Steam buffers applied: SendBuffer={num / 1024}KB, MinRate={num2 / 1024}KB/s"); void SetConfigValue(string keyName, int value) { try { object obj = Enum.Parse(configValueType, keyName); GCHandle gCHandle = GCHandle.Alloc(value, GCHandleType.Pinned); try { setConfigMethod.Invoke(null, new object[5] { (int)obj, (int)globalScope, IntPtr.Zero, (int)intDataType, gCHandle.AddrOfPinnedObject() }); } finally { gCHandle.Free(); } } catch (Exception ex2) { ZLog.LogWarning((object)("[VBNetTweaks] Failed to set " + keyName + ": " + ex2.Message)); } } } catch (Exception ex) { ZLog.LogError((object)("[VBNetTweaks] Failed to apply Steam buffer settings: " + ex.Message)); } } } [HarmonyPatch(typeof(ZNet), "Update")] public static class ZNet_Paths { [HarmonyPostfix] public static void Postfix(ZNet __instance) { if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)ZNet.instance)) { PerformanceMonitor.Track("ZNet.Update", delegate { }); } } } } namespace VBNetTweaks.Utils { public static class PerformanceMonitor { private struct Sample { public string Name; public float TotalTime; public int Count; public float LastLogTime; } private static Dictionary<string, Sample> _samples = new Dictionary<string, Sample>(); private const float LOG_INTERVAL = 5f; public static void Track(string name, Action action) { if (!VBNetTweaks.DebugEnabled.Value) { action(); return; } Stopwatch stopwatch = Stopwatch.StartNew(); action(); stopwatch.Stop(); if (!_samples.TryGetValue(name, out var value)) { Sample sample = default(Sample); sample.Name = name; value = sample; } value.TotalTime += stopwatch.ElapsedMilliseconds; value.Count++; float time = Time.time; if (time - value.LastLogTime > 5f) { float num = value.TotalTime / (float)value.Count; Helper.LogDebug($"{name}: avg={num:F2}ms over {value.Count} samples"); value.TotalTime = 0f; value.Count = 0; value.LastLogTime = time; } _samples[name] = value; } } [HarmonyPatch] public static class PlayerCache { private static List<Player> _cachedPlayers = new List<Player>(); private static Dictionary<long, Player> _playersById = new Dictionary<long, Player>(); private static Dictionary<long, bool> _playerAttachedState = new Dictionary<long, bool>(); private static Dictionary<long, ZDOID> _playerShipMap = new Dictionary<long, ZDOID>(); private static int _cachedFrame = -1; private static float _cachedTime = -1f; public static List<Player> GetAll() { return GetCached(); } public static List<Player> GetCurrentFrame() { return GetCached(0f); } public static List<Player> GetCached(float maxAgeSeconds = 0.5f) { if (Time.time - _cachedTime > maxAgeSeconds || _cachedFrame != Time.frameCount) { RefreshCache(); _cachedTime = Time.time; _cachedFrame = Time.frameCount; } return _cachedPlayers; } public static Player GetById(long id) { if (_cachedFrame != Time.frameCount) { RefreshCache(); } Player value; return _playersById.TryGetValue(id, out value) ? value : null; } public static bool IsPlayerOnShip(long playerId) { return _playerShipMap.ContainsKey(playerId); } public static bool IsPlayerAttached(long playerId) { bool value; return _playerAttachedState.TryGetValue(playerId, out value) && value; } public static ZDOID GetPlayerShip(long playerId) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) ZDOID value; return (ZDOID)(_playerShipMap.TryGetValue(playerId, out value) ? value : default(ZDOID)); } public static void UpdatePlayerState(long playerId, bool attached, ZDOID shipId) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) _playerAttachedState[playerId] = attached; if (((ZDOID)(ref shipId)).IsNone()) { _playerShipMap.Remove(playerId); } else { _playerShipMap[playerId] = shipId; } } public static void RemovePlayer(long playerId) { _playersById.Remove(playerId); _playerAttachedState.Remove(playerId); _playerShipMap.Remove(playerId); } private static void RefreshCache() { _cachedPlayers.Clear(); _playersById.Clear(); List<Player> allPlayers = Player.GetAllPlayers(); _cachedPlayers.AddRange(allPlayers); foreach (Player item in allPlayers) { if (Object.op_Implicit((Object)(object)item)) { long playerID = item.GetPlayerID(); _playersById[playerID] = item; } } ZLog.Log((object)$"PlayerCache refreshed: {_cachedPlayers.Count} players"); } public static void Invalidate() { _cachedFrame = -1; _cachedTime = -1f; } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] [HarmonyPostfix] private static void OnNewConnection(ZNet __instance, ZNetPeer peer) { Invalidate(); } [HarmonyPatch(typeof(ZNet), "Disconnect")] [HarmonyPostfix] private static void OnDisconnect(ZNet __instance, ZNetPeer peer) { Invalidate(); if (peer != null) { RemovePlayer(peer.m_uid); } } [HarmonyPatch(typeof(Player), "AttachStart")] [HarmonyPostfix] private static void OnAttachStart(Player __instance) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) long playerID = __instance.GetPlayerID(); UpdatePlayerState(playerID, attached: true, default(ZDOID)); } [HarmonyPatch(typeof(Player), "AttachStop")] [HarmonyPostfix] private static void OnAttachStop(Player __instance) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) long playerID = __instance.GetPlayerID(); UpdatePlayerState(playerID, attached: false, default(ZDOID)); } } public static class Helper { public static bool IsServer() { return Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer(); } public static ZNet SafeZNetInstance() { return ZNet.instance; } public static void LogErrorWithContext(string module, string message, Exception ex = null) { string text = ((ex != null) ? (" [" + ex.Message + "]") : ""); Debug.LogError((object)("[VBNetTweaks][" + module + "] " + message + text)); } public static bool IsServerInitialized() { return IsServer() && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer(); } public static void LogDebug(string message) { if (VBNetTweaks.DebugEnabled.Value) { Debug.LogWarning((object)("[VBNetTweaks] " + message)); } } public static void LogVerbose(string message) { if (VBNetTweaks.VerboseLogging.Value) { Debug.LogWarning((object)("[VBNetTweaks] " + message)); } } } }