Decompiled source of FloodFix v1.0.0

HTFVoiceFix.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using FishNet.Object.Synchronizing;
using HarmonyLib;
using MetaVoiceChat;
using MetaVoiceChat.NetProviders.FishNet;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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;
		}
	}
}
[BepInPlugin("com.dan.htf.voicefix", "HTF Voice Fix", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
	private static ConfigEntry<int> Complexity;

	private static ConfigEntry<int> TrailingSilence;

	private static ConfigEntry<int> FishBudget;

	private static ConfigEntry<int> MaxKillQueue;

	private static ConfigEntry<float> BudgetWindow;

	private static ConfigEntry<float> MaxCodecMs;

	private static readonly FieldRef<ExplosionInfo, Vector2Int> FishRange = AccessTools.FieldRefAccess<ExplosionInfo, Vector2Int>("_underwaterFishMinMax");

	private static float windowStart;

	private static int used;

	private static readonly List<Creature> spawned = new List<Creature>();

	private static float scale;

	private static int silent;

	private void Awake()
	{
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Expected O, but got Unknown
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Expected O, but got Unknown
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Expected O, but got Unknown
		//IL_0188: Expected O, but got Unknown
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Expected O, but got Unknown
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Expected O, but got Unknown
		Complexity = ((BaseUnityPlugin)this).Config.Bind<int>("Voice", "OpusComplexity", 3, "Opus encoder complexity 0-10 (game default 6). Lower = less CPU.");
		MaxCodecMs = ((BaseUnityPlugin)this).Config.Bind<float>("Voice", "MaxCodecMs", 100f, "Codec time per frame before the game logs a warning (game default 50).");
		TrailingSilence = ((BaseUnityPlugin)this).Config.Bind<int>("Network", "TrailingSilenceFrames", 5, "Empty frames sent after speech stops so peers see you stop talking. Silence is otherwise not sent (game sends 50/s forever).");
		FishBudget = ((BaseUnityPlugin)this).Config.Bind<int>("TNT", "FishPerWindow", 30, "Soft cap on fish spawned by underwater explosions per window. Beyond it each explosion spawns 1 fish carrying the value of all the fish it would have spawned.");
		BudgetWindow = ((BaseUnityPlugin)this).Config.Bind<float>("TNT", "WindowSeconds", 5f, "Length of the fish budget window.");
		MaxKillQueue = ((BaseUnityPlugin)this).Config.Bind<int>("TNT", "MaxKillQueue", 2, "Pending kill-score popups; extra kills are merged into the last one instead of queuing.");
		Harmony val = new Harmony("com.dan.htf.voicefix");
		val.Patch((MethodBase)AccessTools.Method(typeof(FishNetNetProvider), "MetaVoiceChat.NetProviders.INetProvider.RelayFrame", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "SkipSilence", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(MetaVc), "StartClient", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "Tune", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(ExplosionManager), "ServerExplode", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "CapFish", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "RestoreFish", (Type[])null), (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(Creature), "ServerKillOnSpawn", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "CountSpawn", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		val.Patch((MethodBase)AccessTools.Method(typeof(PlayerKillScore), "AddKillScore", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "MergeKills", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static void CapFish(ExplosionInfo info, out Vector2Int __state)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		ref Vector2Int reference = ref FishRange.Invoke(info);
		__state = reference;
		spawned.Clear();
		if (Time.time - windowStart > BudgetWindow.Value)
		{
			windowStart = Time.time;
			used = 0;
		}
		float num = (float)(((Vector2Int)(ref reference)).x + ((Vector2Int)(ref reference)).y - 1) / 2f;
		int num2 = Math.Max(1, Math.Min(((Vector2Int)(ref reference)).y - 1, Math.Max(0, FishBudget.Value - used)));
		used += num2;
		scale = Math.Max(1f, num / (float)num2);
		reference = new Vector2Int(num2, num2 + 1);
	}

	private static void CountSpawn(Creature __instance)
	{
		spawned.Add(__instance);
	}

	private static void RestoreFish(ExplosionInfo info, Vector2Int __state)
	{
		//IL_000b: 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)
		FishRange.Invoke(info) = __state;
		if (scale > 1f)
		{
			foreach (Creature item in spawned)
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					SyncVar<float> killScoreMultiplier = ((Item)item)._killScoreMultiplier;
					killScoreMultiplier.Value *= scale;
				}
			}
		}
		spawned.Clear();
	}

	private static bool MergeKills(PlayerKillScore __instance, int worth)
	{
		List<object> list = ((IEnumerable)Traverse.Create((object)__instance).Field("_killScoreQueue").GetValue()).Cast<object>().ToList();
		if (list.Count < MaxKillQueue.Value)
		{
			return true;
		}
		Traverse val = Traverse.Create(list.Last());
		val.Field("Worth").SetValue((object)(val.Field("Worth").GetValue<int>() + worth));
		val.Field("Killed").SetValue((object)"many");
		return false;
	}

	private static bool SkipSilence(ReadOnlySpan<byte> data)
	{
		if (data.Length > 0)
		{
			silent = 0;
			return true;
		}
		return silent++ < TrailingSilence.Value;
	}

	private static void Tune(MetaVc __instance)
	{
		__instance.config.complexity = Complexity.Value;
		__instance.maxCodecMilliseconds = MaxCodecMs.Value;
	}
}