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.2.7
VBNetTweaks.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; 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 System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Entities; using Jotunn.Extensions; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Steamworks; using UnityEngine; using VBNetTweaks.CompressionUtills; 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; } private class PlayerShipState { public Ship ship; public Vector3 localPos; public Quaternion localRot; public float lastUpdate; } private static readonly object _shipDataLock; private static readonly object _playerStatesLock; 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 string RPC_SYNC_SHIP = "VBNT.SyncShip"; public static bool ShipHasPlayers(ZDOID shipId) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) lock (_shipDataLock) { return _playersOnShip.ContainsKey(shipId); } } public static int GetPlayersOnShipCount(ZDOID shipId) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) lock (_shipDataLock) { int value; return _playersOnShip.TryGetValue(shipId, out value) ? value : 0; } } public static bool IsPlayerOnShip(long playerId) { return PlayerCache.IsPlayerOnShip(playerId); } public static bool IsPlayerAttached(long playerId) { return PlayerCache.IsPlayerAttached(playerId); } static ShipSyncSystem() { _shipDataLock = new object(); _playerStatesLock = new object(); _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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) lock (_shipDataLock) { _shipData.Remove(uid); } lock (_playerStatesLock) { if (_playerShipMap.TryGetValue(uid, out var value)) { lock (_shipDataLock) { 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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_012d: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) if (Helper.IsServer() || !Object.op_Implicit((Object)(object)__instance)) { return; } Ship component = ((Component)__instance).GetComponent<Ship>(); if (!Object.op_Implicit((Object)(object)component)) { return; } ZDO zDO = __instance.GetZDO(); if (zDO == null || !zDO.IsValid()) { return; } long owner = zDO.GetOwner(); if (owner == 0 || owner == ZNet.GetUID()) { return; } Vector3 position = zDO.GetPosition(); Quaternion rotation = zDO.GetRotation(); if (!_shipData.TryGetValue(owner, out var value)) { value = new ShipData { pos = position, rot = rotation, t = Time.time, ok = true }; _shipData[owner] = value; return; } float num = Time.time - value.t; if (num > 0f) { value.vel = (position - value.pos) / num; } value.pos = position; value.rot = rotation; value.t = Time.time; value.ok = true; } [HarmonyPatch(typeof(Ship), "CustomFixedUpdate")] [HarmonyPostfix] public static void SmoothShip(Ship __instance) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0140: 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_0175: 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; Vector3 val2 = value.pos + value.vel * Time.deltaTime; float num = 0.25f; float num2 = 0.15f; Player localPlayer = Player.m_localPlayer; if (IsPlayerOnShip((localPlayer != null) ? localPlayer.GetPlayerID() : 0)) { num = 0.15f; num2 = 0.1f; } float num3 = Vector3.Distance(((Component)__instance).transform.position, val2); if (num3 > 2f) { transform.position = val2; transform.rotation = value.rot; return; } float num4 = Quaternion.Angle(((Component)__instance).transform.rotation, value.rot); if (num4 > 15f) { transform.rotation = value.rot; } else { transform.rotation = Quaternion.Slerp(transform.rotation, value.rot, num2); } transform.position = Vector3.Lerp(transform.position, val2, num); } [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_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: 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_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029c: 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_0286: 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; } bool flag = (Object)(object)val != (Object)(object)shipUnderPlayer; 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 (flag) { 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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.op_Implicit((Object)(object)value.ship) && !((Character)__instance).IsAttached()) { float num = 15f; 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.2.7")] [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")] public class VBNetTweaks : BaseUnityPlugin { private const string ModName = "VBNetTweaks"; private const string ModVersion = "0.2.7"; 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> ModuleCompression; public static ConfigEntry<bool> EnableClientCompression; public static ConfigEntry<bool> ModuleSteamOptimizations; public static ConfigEntry<bool> ModuleShipSync; public static ConfigEntry<CompressionAlgorithm> m_CompressionAlgorithm; public static ConfigEntry<int> CompressionLevel; public static ConfigEntry<int> SteamSendRateMinKB; public static ConfigEntry<int> SteamSendRateMaxKB; public static ConfigEntry<int> SteamSendBufferSize; 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"); ((MonoBehaviour)this).StartCoroutine(DelayedInit()); 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(StatusEffectVFXFix)); _harmony.PatchAll(typeof(NetworkSyncPatches)); _harmony.PatchAll(typeof(ZDONetworkOptimizer)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"VBNetTweaks загружен!"); if (DebugEnabled.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Режим отладки включен"); } } } private void Update() { if (Time.frameCount % 90 == 0) { StatusEffectVFXManager.Maintenance(); } } private IEnumerator DelayedInit() { yield return (object)new WaitForSeconds(2f); if (ModuleCompression.Value) { ZDONetworkOptimizer.Initialize(); ((MonoBehaviour)this).InvokeRepeating("CheckCompressionStatus", 5f, 30f); } } 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, "Включить подробное логирование"); string text2 = "02 - Modules"; EnableClientCompression = ((BaseUnityPlugin)this).Config.Bind<bool>(text2, "ClientCompression", true, "Сжимать данные на клиенте (может вызывать проблемы с визуальными эффектами)"); } 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); ModuleCompression = ConfigFileExtensions.BindConfig<bool>(_serverConfig, text, "Compression", true, "Сжатие сетевого трафика на сервере", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); string text2 = "03 - Compression Settings"; m_CompressionAlgorithm = ConfigFileExtensions.BindConfig<CompressionAlgorithm>(_serverConfig, text2, "Algorithm", CompressionAlgorithm.Vanilla, "Алгоритм сжатия: Deflate, Vanilla (встроенная компрессия игры)", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile serverConfig = _serverConfig; AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 9); CompressionLevel = ConfigFileExtensions.BindConfig<int>(serverConfig, text2, "Level", 3, "Уровень сжатия (1-9 для Deflate)", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); string text3 = "04 - Steam Settings"; SteamSendRateMinKB = ConfigFileExtensions.BindConfig<int>(_serverConfig, text3, "MinRateKB", 256, "Минимальная скорость Steam (vanilla = 150 Kb/s)", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SteamSendRateMaxKB = ConfigFileExtensions.BindConfig<int>(_serverConfig, text3, "MaxRateKB", 4096, "Максимальная скорость Steam (vanilla = 150 Kb/s)", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SteamSendBufferSize = ConfigFileExtensions.BindConfig<int>(_serverConfig, text3, "BufferSize", 100000000, "Размер буфера Steam (vanilla = 260000 B)", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); string text4 = "05 - Server Settings"; ConfigFile serverConfig2 = _serverConfig; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.5f); SendInterval = ConfigFileExtensions.BindConfig<float>(serverConfig2, text4, "SendInterval", 0.03f, "Интервал отправки данных (vanilla = 0.05)", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile serverConfig3 = _serverConfig; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 200); PeersPerUpdate = ConfigFileExtensions.BindConfig<int>(serverConfig3, text4, "PeersPerUpdate", 30, "Количество пиров за один апдейт (vanilla = 1)", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ZDOQueueLimit = ConfigFileExtensions.BindConfig<int>(_serverConfig, text4, "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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown ZPackage val = new ZPackage(); try { val.Write(ModEnabled.Value); val.Write(ModuleSteamOptimizations.Value); val.Write(ModuleShipSync.Value); val.Write(ModuleCompression.Value); val.Write(CompressionLevel.Value); val.Write(SendInterval.Value); val.Write(PeersPerUpdate.Value); val.Write(ZDOQueueLimit.Value); val.Write(EnableClientCompression.Value); val.Write((int)m_CompressionAlgorithm.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(); ModuleCompression.Value = pkg.ReadBool(); CompressionLevel.Value = pkg.ReadInt(); SendInterval.Value = pkg.ReadSingle(); PeersPerUpdate.Value = pkg.ReadInt(); ZDOQueueLimit.Value = pkg.ReadInt(); EnableClientCompression.Value = pkg.ReadBool(); m_CompressionAlgorithm.Value = (CompressionAlgorithm)pkg.ReadInt(); Debug.Log((object)$"[VBNetTweaks] Server config applied: Algorithm={m_CompressionAlgorithm.Value}, Level={CompressionLevel.Value}"); } 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(); ZDONetworkOptimizer.ReinitializeCompressor(); 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; } if (CompressionLevel.Value < 1 || CompressionLevel.Value > 9) { CompressionLevel.Value = 3; } ZDONetworkOptimizer.ReinitializeCompressor(); } 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 int BytesCompressed { get; private set; } public static int BytesOriginal { get; private set; } public static float AvgCompressionRatio => (BytesOriginal > 0) ? ((float)BytesCompressed / (float)BytesOriginal) : 1f; public static bool CompressionActive { get; private set; } public static void RecordZdoSent() { ZdosSent++; } public static void RecordZdoReceived() { ZdosReceived++; } public static void RecordCompression(int originalSize, int compressedSize) { BytesOriginal += originalSize; BytesCompressed += compressedSize; CompressionActive = true; } public static void Reset() { ZdosSent = 0; ZdosReceived = 0; BytesCompressed = 0; BytesOriginal = 0; CompressionActive = false; } public static string GetStats() { return $"ZDOs Sent/Recv: {ZdosSent}/{ZdosReceived}, Ratio: {AvgCompressionRatio:P1}"; } } private class PeerCompressionStatus { public int Version { get; set; } public bool PeerEnabled { get; set; } public bool SendingCompressed { get; set; } public bool ReceivingCompressed { get; set; } public bool IsCompatible => Version == COMPRESSION_VERSION; } private static readonly int COMPRESSION_VERSION = 1; private const string RPC_VERSION = "VBNT.CompressionVersion"; private const string RPC_ENABLED = "VBNT.CompressionEnabled"; private const string RPC_STARTED = "VBNT.CompressionStarted"; private static bool _firstTickLog = true; private static ICompressor _compressor; private static bool _serverMode; private static readonly Dictionary<ISocket, PeerCompressionStatus> _peerStatus = new Dictionary<ISocket, PeerCompressionStatus>(); private static float _lastPeerCheck = 0f; private const float PEER_CHECK_INTERVAL = 10f; private static readonly object _compressorLock = new object(); public static void CheckAndInitCompression() { if (!VBNetTweaks.ModuleCompression.Value) { return; } if (_compressor == null && VBNetTweaks.ModuleCompression.Value) { InitCompressor(); } if ((Object)(object)ZNet.instance == (Object)null) { return; } float time = Time.time; if (!(time - _lastPeerCheck > 10f)) { return; } _lastPeerCheck = time; int num = 0; int count = _peerStatus.Count; foreach (KeyValuePair<ISocket, PeerCompressionStatus> item in _peerStatus) { if (item.Value.IsCompatible && item.Value.ReceivingCompressed) { num++; } } if (count > 0 && num == 0 && _compressor != null) { Helper.LogVerbose($"[Compression] ⚠\ufe0f No compatible peers! Total={count}, Compressor={_compressor.GetType().Name}"); } else if (num > 0 && VBNetTweaks.DebugEnabled.Value) { Helper.LogDebug($"[Compression] Active: {num}/{count} peers using compression"); } } public static string GetCompressionStatus() { StringBuilder stringBuilder = new StringBuilder(); string text = ((_compressor != null) ? _compressor.GetType().Name.Replace("Compressor", "") : "NONE"); stringBuilder.AppendLine(" Active Compressor: " + text); string arg = VBNetTweaks.m_CompressionAlgorithm?.Value.ToString() ?? "N/A"; int num = VBNetTweaks.CompressionLevel?.Value ?? 0; stringBuilder.AppendLine($" Config Memory: {arg} (Lvl {num})"); int count = _peerStatus.Count; int num2 = 0; int num3 = 0; int num4 = 0; foreach (PeerCompressionStatus value in _peerStatus.Values) { if (value.IsCompatible) { num2++; } if (value.SendingCompressed) { num3++; } if (value.ReceivingCompressed) { num4++; } } stringBuilder.AppendLine($" Peers: {count} total | {num2} compatible | {num4} receiving"); float num5 = VBNetTweaks.SendInterval?.Value ?? 0.05f; int num6 = VBNetTweaks.PeersPerUpdate?.Value ?? 30; int num7 = VBNetTweaks.ZDOQueueLimit?.Value ?? 10240; stringBuilder.AppendLine($" ZDO Settings: Interval={num5:F3}s | Batch={num6} | Queue={num7}"); stringBuilder.AppendLine($" Metrics: {NetworkMetrics.ZdosSent} sent / {NetworkMetrics.ZdosReceived} recv"); stringBuilder.AppendLine($" Compression Ratio: {NetworkMetrics.AvgCompressionRatio:P1}"); return stringBuilder.ToString(); } private static void InitCompressor() { try { int value = VBNetTweaks.CompressionLevel.Value; switch (VBNetTweaks.m_CompressionAlgorithm.Value) { case CompressionAlgorithm.Deflate: _compressor = new DeflateCompressor(value); ZLog.LogWarning((object)$"Using Deflate compressor (level {value})"); break; case CompressionAlgorithm.Vanilla: _compressor = new VanillaCompressor(); ZLog.LogWarning((object)"Using Vanilla (native) compressor"); break; } } catch (Exception ex) { ZLog.LogError((object)("Compression init failed: " + ex.Message + ", falling back to NO compression")); _compressor = null; } } public static void Initialize() { if (VBNetTweaks.ModuleCompression.Value) { _serverMode = Helper.IsServer(); if (_serverMode) { InitCompressor(); ZLog.LogWarning((object)"Compression initialized in SERVER mode"); } else if (VBNetTweaks.EnableClientCompression.Value) { InitCompressor(); ZLog.LogWarning((object)"Compression initialized in CLIENT mode"); } else { ZLog.LogWarning((object)"Compression disabled on client"); } } } public static void ReinitializeCompressor() { lock (_compressorLock) { ZLog.LogWarning((object)"[Compression] ===== REINITIALIZING COMPRESSOR ====="); if (_compressor is IDisposable disposable) { try { disposable.Dispose(); } catch { } } _compressor = null; Dictionary<ISocket, PeerCompressionStatus> dictionary = new Dictionary<ISocket, PeerCompressionStatus>(_peerStatus); _peerStatus.Clear(); if (VBNetTweaks.ModuleCompression.Value) { InitCompressor(); foreach (KeyValuePair<ISocket, PeerCompressionStatus> kvp in dictionary) { PeerCompressionStatus value = new PeerCompressionStatus(); _peerStatus[kvp.Key] = value; if ((Object)(object)ZNet.instance != (Object)null) { ZNetPeer val = ZNet.instance.GetPeers().Find((ZNetPeer p) => p.m_socket == kvp.Key); if (val != null) { SendCompressionVersion(val); } } } ZLog.LogWarning((object)("[Compression] Compressor reinitialized to: " + (_compressor?.GetType().Name ?? "NONE"))); } else { ZLog.LogWarning((object)"[Compression] Compression disabled after reinitialization"); } } } public static string GetCurrentCompressorType() { if (_compressor == null) { return "NONE"; } string text = _compressor.GetType().Name.Replace("Compressor", ""); return text.ToLowerInvariant(); } public static bool ShouldCompressSend(ISocket socket) { if (_serverMode) { return _compressor != null; } if (!_peerStatus.TryGetValue(socket, out var value)) { return false; } return value.SendingCompressed && _compressor != null; } public static bool ShouldCompressReceive(ISocket socket) { if (!_peerStatus.TryGetValue(socket, out var value)) { return false; } if (!_serverMode && value.ReceivingCompressed) { return true; } return value.ReceivingCompressed && _compressor != null; } public static byte[] Compress(byte[] data) { if (_compressor == null) { return data; } try { byte[] array = _compressor.Compress(data); NetworkMetrics.RecordCompression(data.Length, array.Length); return array; } catch (Exception ex) { ZLog.LogError((object)("Compression failed: " + ex.Message)); return data; } } public static byte[] Decompress(byte[] data) { if (_compressor == null) { return data; } try { return _compressor.Decompress(data); } catch (Exception ex) { ZLog.LogError((object)("Decompression failed: " + ex.Message)); return data; } } 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; if (_firstTickLog) { _firstTickLog = false; ZLog.LogWarning((object)$"[VBNetTweaks] \ufe0f ZDO Tick Started -> Interval: {num:F3}s | Peers/Update: {num3} | ActivePeers: {count}"); } 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); } } private static void RegisterCompressionRPCs(ZNetPeer peer) { peer.m_rpc.Register<int>("VBNT.CompressionVersion", (Action<ZRpc, int>)delegate(ZRpc rpc, int version) { RPC_CompressionVersion(peer, version); }); peer.m_rpc.Register<bool>("VBNT.CompressionEnabled", (Action<ZRpc, bool>)delegate(ZRpc rpc, bool enabled) { RPC_CompressionEnabled(peer, enabled); }); peer.m_rpc.Register<bool>("VBNT.CompressionStarted", (Action<ZRpc, bool>)delegate(ZRpc rpc, bool started) { RPC_CompressionStarted(peer, started); }); } private static void SendCompressionVersion(ZNetPeer peer) { peer.m_rpc.Invoke("VBNT.CompressionVersion", new object[1] { COMPRESSION_VERSION }); } private static void RPC_CompressionVersion(ZNetPeer peer, int version) { if (_peerStatus.TryGetValue(peer.m_socket, out var value)) { value.Version = version; if (value.IsCompatible) { ZLog.LogWarning((object)("Compression compatible with " + GetPeerName(peer))); SendCompressionEnabledStatus(peer); } } } private static void SendCompressionEnabledStatus(ZNetPeer peer) { bool value = VBNetTweaks.ModuleCompression.Value; peer.m_rpc.Invoke("VBNT.CompressionEnabled", new object[1] { value }); } private static void RPC_CompressionEnabled(ZNetPeer peer, bool enabled) { if (_peerStatus.TryGetValue(peer.m_socket, out var value)) { value.PeerEnabled = enabled; bool flag = VBNetTweaks.ModuleCompression.Value; if (!Helper.IsServer()) { flag = flag && VBNetTweaks.EnableClientCompression.Value; } flag = flag && enabled && value.IsCompatible; SendCompressionStarted(peer, flag); } } private static void SendCompressionStarted(ZNetPeer peer, bool started) { if (!_peerStatus.TryGetValue(peer.m_socket, out var value) || value.SendingCompressed == started) { return; } peer.m_rpc.Invoke("VBNT.CompressionStarted", new object[1] { started }); Type type = ((object)peer.m_socket).GetType(); MethodInfo method = type.GetMethod("Flush", Type.EmptyTypes); if (method != null && method.DeclaringType != typeof(object)) { try { peer.m_socket.Flush(); } catch (Exception ex) { ZLog.LogError((object)("Error flushing socket: " + ex.Message)); } } value.SendingCompressed = started; ZLog.LogWarning((object)("Compression " + (started ? "started" : "stopped") + " with " + GetPeerName(peer))); } private static void RPC_CompressionStarted(ZNetPeer peer, bool started) { if (_peerStatus.TryGetValue(peer.m_socket, out var value)) { value.ReceivingCompressed = started; ZLog.LogWarning((object)("Receiving " + (started ? "compressed" : "uncompressed") + " from " + GetPeerName(peer))); } } private static string GetPeerName(ZNetPeer peer) { try { ISocket socket = peer.m_socket; return ((socket != null) ? socket.GetEndPointString() : null) ?? peer.m_uid.ToString(); } catch { return peer.m_uid.ToString(); } } [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) { try { PerformanceMonitor.Track("RemoveObjects", delegate { if (currentNearObjects != null && currentDistantObjects != null) { ZDORemoval.OptimizedRemoveObjects(__instance, currentNearObjects, currentDistantObjects); } }); return false; } catch { return true; } } [HarmonyPatch(typeof(ZNet), "Disconnect")] [HarmonyPostfix] private static void OnDisconnect(ZNet __instance, ZNetPeer peer) { _peerStatus.Remove(peer.m_socket); } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] [HarmonyPostfix] private static void OnNewConnection(ZNet __instance, ZNetPeer peer) { _peerStatus[peer.m_socket] = new PeerCompressionStatus(); RegisterCompressionRPCs(peer); SendCompressionVersion(peer); } } public class ZDORemoval { public static void OptimizedRemoveObjects(ZNetScene scene, List<ZDO> near, List<ZDO> distant) { byte b = (byte)((uint)Time.frameCount & 0xFFu); foreach (ZDO item in near) { if (item != null) { item.TempRemoveEarmark = b; } } 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(); List<ZDO> list = new List<ZDO>(instances.Keys); foreach (ZDO item3 in list) { if (item3 == null || !instances.TryGetValue(item3, out var value) || (Object)(object)value == (Object)null) { instances.Remove(item3); } else if (item3.TempRemoveEarmark != b) { tempRemoved.Add(value); } } foreach (ZNetView item4 in tempRemoved) { if (Object.op_Implicit((Object)(object)item4)) { ZDO zdo = item4.m_zdo; if (zdo != null) { zdo.Created = false; item4.m_zdo = null; } Object.Destroy((Object)(object)((Component)item4).gameObject); instances.Remove(zdo); } } } } } namespace VBNetTweaks.Utils { [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 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; } } 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)); } } public static void CheckCompressionStatus() { if (VBNetTweaks.ModuleCompression.Value && VBNetTweaks.DebugEnabled.Value) { ZLog.LogWarning((object)ZDONetworkOptimizer.GetCompressionStatus()); } } } } 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(ZDOMan), "SendZDOs")] [HarmonyPrefix] public static void BeforeSendZDOs(ZDOPeer peer) { if (VBNetTweaks.DebugEnabled.Value && peer?.m_peer?.m_socket != null && Time.frameCount % 600 == 0) { string compressionStatus = ZDONetworkOptimizer.GetCompressionStatus(); ZLog.LogWarning((object)("[Network] Compression status:\n" + compressionStatus)); } } [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(); } } } public static class StatusEffectVFXManager { private static readonly Dictionary<ZNetView, HashSet<GameObject>> _registry = new Dictionary<ZNetView, HashSet<GameObject>>(); public static void Register(ZNetView parent, GameObject vfx) { if (Object.op_Implicit((Object)(object)parent) && Object.op_Implicit((Object)(object)vfx)) { if (!_registry.TryGetValue(parent, out var value)) { value = new HashSet<GameObject>(); _registry[parent] = value; } value.Add(vfx); } } public static void Unregister(ZNetView parent, GameObject vfx) { if (Object.op_Implicit((Object)(object)parent) && _registry.TryGetValue(parent, out var value)) { value.Remove(vfx); if (value.Count == 0) { _registry.Remove(parent); } } } public static void CleanupByParent(ZNetView parent) { if (!_registry.TryGetValue(parent, out var value)) { return; } ZNetView val = default(ZNetView); foreach (GameObject item in value) { if (!Object.op_Implicit((Object)(object)item)) { continue; } if (item.TryGetComponent<ZNetView>(ref val)) { if (val.IsValid()) { val.ClaimOwnership(); } val.Destroy(); } else { Object.Destroy((Object)(object)item); } } _registry.Remove(parent); } public static void Maintenance() { List<ZNetView> list = new List<ZNetView>(); foreach (KeyValuePair<ZNetView, HashSet<GameObject>> item in _registry) { item.Value.RemoveWhere((GameObject g) => !Object.op_Implicit((Object)(object)g)); if (item.Value.Count == 0) { list.Add(item.Key); } } foreach (ZNetView item2 in list) { _registry.Remove(item2); } } } [HarmonyPatch] public static class StatusEffectVFXFix { [HarmonyPatch(typeof(StatusEffect), "TriggerStartEffects")] [HarmonyPostfix] public static void TrackVFX_Postfix(StatusEffect __instance) { if (!Object.op_Implicit((Object)(object)__instance?.m_character) || __instance.m_startEffectInstances == null) { return; } ZNetView component = ((Component)__instance.m_character).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component)) { return; } GameObject[] startEffectInstances = __instance.m_startEffectInstances; foreach (GameObject val in startEffectInstances) { if (Object.op_Implicit((Object)(object)val)) { StatusEffectVFXManager.Register(component, val); } } } [HarmonyPatch(typeof(StatusEffect), "RemoveStartEffects")] [HarmonyPrefix] public static bool RemoveVFX_Prefix(StatusEffect __instance) { if (__instance.m_startEffectInstances == null || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { return true; } Character character = __instance.m_character; ZNetView parent = ((character != null) ? ((Component)character).GetComponent<ZNetView>() : null); GameObject[] startEffectInstances = __instance.m_startEffectInstances; ZNetView val2 = default(ZNetView); foreach (GameObject val in startEffectInstances) { if (!Object.op_Implicit((Object)(object)val)) { continue; } StatusEffectVFXManager.Unregister(parent, val); if (val.TryGetComponent<ZNetView>(ref val2)) { if (val2.IsValid()) { val2.ClaimOwnership(); } val2.Destroy(); } else { Object.Destroy((Object)(object)val); } } __instance.m_startEffectInstances = null; return false; } [HarmonyPatch(typeof(ZNetView), "OnDestroy")] [HarmonyPostfix] public static void ZNetView_OnDestroy_Postfix(ZNetView __instance) { StatusEffectVFXManager.CleanupByParent(__instance); } } [HarmonyPatch] public static class ZSteamSocket_Patchs { private static bool _isPatched; [HarmonyTranspiler] [HarmonyPatch(typeof(ZSteamSocket), "RegisterGlobalCallbacks")] private static IEnumerable<CodeInstruction> ZSteamSocket_RegisterGlobalCallbacks_Transpiler(IEnumerable<CodeInstruction> instructions) { if (_isPatched) { return instructions; } ZLog.LogWarning((object)"[VBNetTweaks] Transpiler entered for ZSteamSocket.RegisterGlobalCallbacks"); 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 = 50000000; list[i].operand = num; flag = true; ZLog.LogWarning((object)$"[VBNetTweaks] Steam transfer rate patched: 153600 -> {num}"); break; } } if (!flag) { ZLog.LogWarning((object)"[VBNetTweaks] WARNING: Steam transfer rate constant 153600 NOT FOUND in IL!"); } _isPatched = true; return list; } [HarmonyPostfix] [HarmonyPatch(typeof(ZSteamSocket), "RegisterGlobalCallbacks")] private static void ZSteamSocket_RegisterGlobalCallbacks_Postfix() { try { ZLog.LogWarning((object)"[VBNetTweaks] Applying Steam Socket Settings via Postfix..."); Type typeFromHandle = typeof(SteamNetworkingUtils); if (typeFromHandle == null) { ZLog.LogError((object)"[VBNetTweaks] SteamNetworkingUtils type not found!"); return; } MethodInfo setCfg = typeFromHandle.GetMethod("SetConfigValue", new Type[5] { typeof(ESteamNetworkingConfigValue), typeof(ESteamNetworkingConfigScope), typeof(IntPtr), typeof(ESteamNetworkingConfigDataType), typeof(IntPtr) }); if (setCfg == null) { ZLog.LogError((object)"[VBNetTweaks] SetConfigValue method not found!"); return; } int num = Math.Max(64, VBNetTweaks.SteamSendRateMinKB.Value) * 1024; int num2 = Math.Max(num, VBNetTweaks.SteamSendRateMaxKB.Value) * 1024; int num3 = Math.Max(8388608, VBNetTweaks.SteamSendBufferSize.Value); SetInt((ESteamNetworkingConfigValue)10, num); SetInt((ESteamNetworkingConfigValue)11, num2); SetInt((ESteamNetworkingConfigValue)9, num3); ZLog.LogWarning((object)$"[VBNetTweaks] Steam send rates applied: min={num / 1024}KB/s, max={num2 / 1024}KB/s, buffer={num3 / 1024 / 1024}MB"); void SetInt(ESteamNetworkingConfigValue key, int value) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) GCHandle gCHandle = GCHandle.Alloc(value, GCHandleType.Pinned); try { setCfg.Invoke(null, new object[5] { key, (object)(ESteamNetworkingConfigScope)1, IntPtr.Zero, (object)(ESteamNetworkingConfigDataType)1, gCHandle.AddrOfPinnedObject() }); } finally { gCHandle.Free(); } } } catch (Exception ex) { ZLog.LogError((object)("[VBNetTweaks] Error applying Steam send rates: " + ex.Message + "\n" + ex.StackTrace)); } } } [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)) { if (VBNetTweaks.ModuleCompression.Value) { ZDONetworkOptimizer.CheckAndInitCompression(); } PerformanceMonitor.Track("ZNet.Update", delegate { }); } } } } namespace VBNetTweaks.CompressionUtills { public enum CompressionAlgorithm { Deflate, Vanilla } public interface ICompressor { byte[] Compress(byte[] data); byte[] Decompress(byte[] data); } public class VanillaCompressor : ICompressor { public byte[] Compress(byte[] data) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown if (data.Length < 32) { return data; } try { ZPackage val = new ZPackage(data); ZPackage val2 = new ZPackage(); val2.WriteCompressed(val); byte[] array = val2.GetArray(); if (array.Length > 4) { byte[] array2 = new byte[array.Length - 4]; Buffer.BlockCopy(array, 4, array2, 0, array2.Length); return (array2.Length < data.Length) ? array2 : data; } return data; } catch { return data; } } public byte[] Decompress(byte[] data) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown try { ZPackage val = new ZPackage(); byte[] array = new byte[data.Length + 4]; byte[] bytes = BitConverter.GetBytes(data.Length); Buffer.BlockCopy(bytes, 0, array, 0, 4); Buffer.BlockCopy(data, 0, array, 4, data.Length); val.Load(array); return val.ReadCompressedPackage().GetArray(); } catch { return data; } } } public class DeflateCompressor : ICompressor { private readonly int _level; private readonly object _lock = new object(); public DeflateCompressor(int level) { _level = Math.Max(1, Math.Min(9, level)); ZLog.LogWarning((object)$"[Deflate] Compressor created with level {_level}"); } public byte[] Compress(byte[] data) { if (data.Length < 32) { return data; } try { using MemoryStream memoryStream = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionLevel.Fastest)) { deflateStream.Write(data, 0, data.Length); } byte[] array = memoryStream.ToArray(); float num = (float)array.Length / (float)data.Length; if (array.Length < data.Length) { Helper.LogDebug($"[Deflate] Compressed {data.Length} -> {array.Length} bytes ({num:P1})"); return array; } return data; } catch (Exception ex) { ZLog.LogError((object)("[Deflate] Compression failed: " + ex.Message)); return data; } } public byte[] Decompress(byte[] data) { try { using MemoryStream stream = new MemoryStream(data); using DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); deflateStream.CopyTo(memoryStream); byte[] array = memoryStream.ToArray(); Helper.LogDebug($"[Deflate] Decompressed {data.Length} -> {array.Length} bytes"); return array; } catch (Exception ex) { ZLog.LogError((object)("[Deflate] Decompression failed: " + ex.Message)); return data; } } } }