using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LeanNet;
[BepInPlugin("CacoFFF.valheim.LeanNet", "Lean Networking", "1.0.0")]
public class LeanNet : BaseUnityPlugin
{
public class ZDOUpdateLogger
{
private static uint DataRevision;
public static void ZDOPreUpdate(ZDO zDO)
{
if (zDO != null)
{
DataRevision = zDO.DataRevision;
}
}
public static void ZDOPostUpdate(ZDO zDO, string ObjectName)
{
if (zDO != null && zDO.IsOwner() && zDO.DataRevision != DataRevision)
{
ZLog.Log((object)("Net update: " + ObjectName));
}
}
}
[HarmonyPatch(typeof(MonoUpdaters), "FixedUpdate")]
public class GetWorldDeltaTimeFixed
{
private static void Prefix()
{
DeltaTimeFixedPhysics = Time.fixedDeltaTime;
ZDORevisionFreeze.Reset();
UpdateState(0f);
}
}
[HarmonyPatch(typeof(MonoUpdaters), "LateUpdate")]
public class GetWorldDeltaTimeLate
{
private static void Prefix()
{
float deltaTime = (DeltaTimePhysics = Time.deltaTime);
ZDORevisionFreeze.Reset();
UpdateState(deltaTime);
}
}
[HarmonyPatch(typeof(ZDO), "IncreaseDataRevision")]
public class ZDORevisionFreeze
{
public static int Freeze;
public static int Force;
public static uint DataRevision;
public static void Reset()
{
Freeze = 0;
Force = 0;
DataRevision = 0u;
}
public static bool IsFreezing()
{
if (Freeze > 0)
{
return Force <= 0;
}
return false;
}
public static bool IsForcing()
{
return Force > 0;
}
private static bool Prefix()
{
return !IsFreezing();
}
}
[HarmonyPatch(typeof(ZDO), "Set", new Type[]
{
typeof(int),
typeof(Vector3)
})]
public class ZDOUpdateDiscard_Vec3
{
private static bool Prefix(ref ZDO __instance, int hash, Vector3 value)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: 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)
if (!Enabled.Value)
{
return true;
}
if (ZDORevisionFreeze.IsForcing())
{
return true;
}
Vector3 val = default(Vector3);
if (__instance.GetVec3(hash, ref val))
{
Vector3 val2 = val - value;
if (((Vector3)(ref val2)).sqrMagnitude < Vec3CullSizeSq)
{
return false;
}
}
return true;
}
}
[HarmonyPatch(typeof(ZDO), "Set", new Type[]
{
typeof(int),
typeof(Quaternion)
})]
public class ZDOUpdateDiscard_Quat
{
private static bool Prefix(ref ZDO __instance, int hash, Quaternion value)
{
//IL_001a: 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)
if (!Enabled.Value)
{
return true;
}
if (ZDORevisionFreeze.IsForcing())
{
return true;
}
if (Quaternion.Dot(__instance.GetQuaternion(hash, value), value) > 0.98f)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(ZSyncTransform), "CustomLateUpdate")]
public class PhysicsSyncReducer
{
private static bool Freezing;
private static bool Forcing;
private static void Prefix(ref ZSyncTransform __instance, ref ZNetView ___m_nview)
{
if (!Enabled.Value)
{
return;
}
ZDO zDO = ___m_nview.GetZDO();
float num = default(float);
if (!zDO.GetFloat(ZDOVars.s_rudder, ref num))
{
float num2 = NetRatePhysics.Value;
if (!__instance.m_syncPosition)
{
num2 *= 2f;
}
Forcing = ShouldUpdateZDO(zDO, 0.5f, DeltaTimePhysics);
Freezing = !Forcing && !ShouldUpdateZDO(zDO, num2, DeltaTimePhysics);
if (Forcing)
{
ZDORevisionFreeze.Force++;
}
if (Freezing)
{
ZDORevisionFreeze.Freeze++;
}
}
}
private static void Postfix(ref ZSyncTransform __instance, ref ZNetView ___m_nview)
{
if (Freezing)
{
Freezing = false;
ZDORevisionFreeze.Freeze--;
}
if (Forcing)
{
Forcing = false;
ZDORevisionFreeze.Force--;
}
}
}
[HarmonyPatch]
[HarmonyPatch(typeof(Character), "CustomFixedUpdate")]
public class CharacterNetOptimizator
{
public static bool Freezing;
public static bool Forcing;
[HarmonyPrefix]
private static void CustomFixedUpdatePrefix(ref Character __instance, float dt, ref ZNetView ___m_nview)
{
if (Enabled.Value && !__instance.IsPlayer())
{
ZDO zDO = ___m_nview.GetZDO();
Forcing = ShouldUpdateZDO(zDO, 0.5f, DeltaTimePhysics);
Freezing = !Forcing && !ShouldUpdateZDO(zDO, NetRateNPC.Value, DeltaTimePhysics);
if (Forcing)
{
ZDORevisionFreeze.Force++;
}
if (Freezing)
{
ZDORevisionFreeze.Freeze++;
}
}
}
[HarmonyPostfix]
private static void CustomFixedUpdatePostfix(ref Character __instance, ref ZNetView ___m_nview)
{
if (Freezing)
{
Freezing = false;
ZDORevisionFreeze.Freeze--;
}
if (Forcing)
{
Forcing = false;
ZDORevisionFreeze.Force--;
}
}
[HarmonyPrefix]
[HarmonyPatch("UpdateGroundTilt")]
private static void UpdateGroundTiltPrefix(float dt)
{
if (Enabled.Value)
{
ZDORevisionFreeze.Freeze++;
}
}
[HarmonyPostfix]
[HarmonyPatch("UpdateGroundTilt")]
private static void UpdateGroundTiltPostfix(ref Character __instance)
{
if (Enabled.Value)
{
ZDORevisionFreeze.Freeze--;
}
}
[HarmonyPrefix]
[HarmonyPatch("SyncVelocity")]
private static bool SyncVelocityPrefix(ref Rigidbody ___m_body, ref Vector3 ___m_bodyVelocityCached)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
if (!Enabled.Value)
{
return true;
}
if (ZDORevisionFreeze.IsForcing())
{
return true;
}
Vector3 val = ___m_body.velocity - ___m_bodyVelocityCached;
if (((Vector3)(ref val)).sqrMagnitude <= Vec3CullSizeSq)
{
return false;
}
return true;
}
}
public static ConfigEntry<bool> Enabled;
public static ConfigEntry<float> NetRatePhysics;
public static ConfigEntry<float> NetRateNPC;
public static ConfigEntry<float> Vec3CullSize;
private Harmony _harmony;
public static double NetTime = 0.0;
public static float DeltaTimeFixedPhysics = 0.02f;
public static float DeltaTimePhysics = 0.01f;
public static float Vec3CullSizeSq = 0.00025f;
private void Awake()
{
Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Global", "Enabled", true, "Global toggle, this option does not require a game restart.");
NetRatePhysics = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "NetRatePhysics", 8f, "Update frequency for physics objects, such as dropped items and projectiles.");
NetRateNPC = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "NetRateNPC", 8f, "Update frequency for NPC's.");
Vec3CullSize = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "Vec3CullSize", 0.05f, "Cull Vector3 updates if the magnitude of the offset is smaller than this.");
_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
}
public static void UpdateState(float DeltaTime)
{
if (NetRatePhysics.Value < 4f)
{
NetRatePhysics.Value = 4f;
}
if (NetRateNPC.Value < 4f)
{
NetRateNPC.Value = 4f;
}
if (Vec3CullSize.Value > 0.2f)
{
Vec3CullSize.Value = 0.2f;
}
Vec3CullSizeSq = Vec3CullSize.Value * Vec3CullSize.Value;
NetTime += DeltaTime;
if (DeltaTime > 100f)
{
NetTime -= DeltaTime;
}
ZDORevisionFreeze.Freeze = 0;
ZDORevisionFreeze.Force = 0;
}
public static double GetZDOTime(ZDO zDO)
{
return NetTime + 0.023 * (double)(((ZDOID)(ref zDO.m_uid)).ID & 0xFFFu);
}
public static bool ShouldUpdateZDO(ZDO zDO, float NetRate, float DeltaTime)
{
double zDOTime = GetZDOTime(zDO);
double num = zDOTime + (double)DeltaTime;
return Mathf.RoundToInt((float)(zDOTime * (double)NetRate)) != Mathf.RoundToInt((float)(num * (double)NetRate));
}
}