using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dissonance;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RepoCore.Comps;
using RepoCore.Utils;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("zeeblo.RepoCore")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+589e4a90255f7642790b9e6c65a7c18d6d3ad98c")]
[assembly: AssemblyProduct("RepoCore")]
[assembly: AssemblyTitle("zeeblo.RepoCore")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.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 RepoCore
{
[BepInPlugin("RepoCore.zeeblo.dev", "RepoCore", "0.1.0")]
public class Plugin : BaseUnityPlugin
{
public const string modGUID = "RepoCore.zeeblo.dev";
public const string modName = "RepoCore";
public const string modVersion = "0.1.0";
private readonly Harmony _harmony = new Harmony("RepoCore.zeeblo.dev");
internal static ManualLogSource mls = Logger.CreateLogSource("RepoCore.zeeblo.dev");
public static string MainDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).Replace("file:\\", "");
private void Awake()
{
LConfig.AllConfigs(((BaseUnityPlugin)this).Config);
LMAssets.LoadAllAssets();
PatchAllStuff();
}
private void PatchAllStuff()
{
_harmony.PatchAll(Assembly.GetExecutingAssembly());
}
public static void SendLog(string msg)
{
if (LConfig.viewLogs.Value)
{
mls.LogInfo((object)msg);
}
}
public static string GetAssetPath(string file, string parent = "Assetbundles")
{
string text = MainDir + "\\Assets\\" + parent + "\\" + file;
string result = MainDir + "/" + file;
if (File.Exists(text))
{
return text;
}
return result;
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "zeeblo.RepoCore";
public const string PLUGIN_NAME = "RepoCore";
public const string PLUGIN_VERSION = "0.1.0";
}
}
namespace RepoCore.Utils
{
internal class LMAssets
{
public static GameObject ScavHead;
public static void LoadAllAssets()
{
LoadStuff();
}
private static void LoadStuff()
{
string assetPath = Plugin.GetAssetPath("repo_core");
AssetBundle val = AssetBundle.LoadFromFile(assetPath);
ScavHead = val.LoadAsset<GameObject>("lc_head.prefab");
}
}
public class LConfig
{
public static ConfigEntry<float> defaultAmpMulti;
public static ConfigEntry<bool> viewLogs;
public static void AllConfigs(ConfigFile cfg)
{
defaultAmpMulti = cfg.Bind<float>("General", "Head Bob Multiplier", 3.85f, "How much the heads will rotate back");
viewLogs = cfg.Bind<bool>("General", "Show developer debug logs", true, "If you have a console open it'll show more details");
}
}
}
namespace RepoCore.Scripts
{
internal class ChatTalk
{
private static void TextToSpeech(HUDManager __instance, ref string chatMessage, int playerWhoSent)
{
if (playerWhoSent >= 0)
{
Plugin.SendLog($" Message Sent by {playerWhoSent}: {chatMessage}");
}
}
}
[HarmonyPatch]
internal class Speaking
{
[CompilerGenerated]
private sealed class <AddSpeakComp>d__8 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
private Dictionary<ulong, int>.Enumerator <>s__1;
private KeyValuePair<ulong, int> <plr>5__2;
private PlayerControllerB <player>5__3;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <AddSpeakComp>d__8(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>s__1 = default(Dictionary<ulong, int>.Enumerator);
<player>5__3 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
RemoveVoiceForAll();
<>2__current = (object)new WaitForSeconds(10f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
Plugin.SendLog(">>> Adding Events!");
<>s__1 = StartOfRound.Instance.ClientPlayerList.GetEnumerator();
try
{
while (<>s__1.MoveNext())
{
<plr>5__2 = <>s__1.Current;
<player>5__3 = StartOfRound.Instance.allPlayerScripts[<plr>5__2.Value];
if (StartOfRound.Instance.allPlayerScripts[<plr>5__2.Value].voicePlayerState == null)
{
Plugin.SendLog($"VoiceState is null: {StartOfRound.Instance.allPlayerScripts[<plr>5__2.Value].voicePlayerState}");
continue;
}
if ((Object)(object)((Component)<player>5__3).gameObject.GetComponent<VoiceSpeak>() == (Object)null)
{
((Component)<player>5__3).gameObject.AddComponent<VoiceSpeak>().PlayerID = <plr>5__2.Value;
}
Plugin.SendLog($">>> Ulong: {<plr>5__2.Key} | int: {<plr>5__2.Value}");
<player>5__3 = null;
}
}
finally
{
((IDisposable)<>s__1).Dispose();
}
<>s__1 = default(Dictionary<ulong, int>.Enumerator);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static Coroutine speakComponent;
[HarmonyPatch(typeof(StartOfRound), "OnPlayerConnectedClientRpc")]
[HarmonyPostfix]
private static void addVoiceOnJoin()
{
StartSpeakComp();
}
[HarmonyPatch(typeof(StartOfRound), "RefreshPlayerVoicePlaybackObjects")]
[HarmonyPrefix]
private static bool RefreshVoicesAgain()
{
Plugin.SendLog("Refreshing Voices for all players");
StartSpeakComp();
return true;
}
[HarmonyPatch(typeof(StartOfRound), "OnDisable")]
[HarmonyPostfix]
private static void OnDisable()
{
((MonoBehaviour)StartOfRound.Instance).StopCoroutine(speakComponent);
speakComponent = null;
Plugin.mls.LogInfo((object)"StartOfRound.OnDisable()");
}
[HarmonyPatch(typeof(StartOfRound), "OnClientDisconnect")]
[HarmonyPrefix]
private static bool OnClientDisconnectPatch()
{
Plugin.SendLog(">>> OnClientDisconnect() | Host maybe left?");
RemoveVoiceForAll();
return true;
}
[HarmonyPatch(typeof(StartOfRound), "OnPlayerDC")]
[HarmonyPostfix]
private static void CheckClientsConnected()
{
Plugin.SendLog(">>> Player Disconnected");
StartSpeakComp();
}
[HarmonyPatch(typeof(HUDManager), "AddTextToChatOnServer")]
[HarmonyPrefix]
private static bool PlayerKickedPatch(string chatMessage, int playerId)
{
if (chatMessage.Contains("was kicked") && playerId == -1)
{
Plugin.SendLog(">>> Player Kicked");
RemoveVoiceForAll();
}
return true;
}
private static void StartSpeakComp()
{
if (speakComponent != null)
{
((MonoBehaviour)StartOfRound.Instance).StopCoroutine(speakComponent);
}
speakComponent = ((MonoBehaviour)StartOfRound.Instance).StartCoroutine(AddSpeakComp());
}
[IteratorStateMachine(typeof(<AddSpeakComp>d__8))]
private static IEnumerator AddSpeakComp()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <AddSpeakComp>d__8(0);
}
private static void RemoveVoiceForAll()
{
foreach (KeyValuePair<ulong, int> clientPlayer in StartOfRound.Instance.ClientPlayerList)
{
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[clientPlayer.Value];
if ((Object)(object)((Component)val).gameObject.GetComponent<VoiceSpeak>() != (Object)null)
{
((Component)val).gameObject.GetComponent<VoiceSpeak>().RemoveThisClass();
Plugin.SendLog("RemoveVoiceForAll() Executed");
}
}
}
}
}
namespace RepoCore.Comps
{
public class VoiceSpeak : MonoBehaviour
{
[CompilerGenerated]
private sealed class <RotateDelay>d__22 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public float amp;
public bool rotateUp;
public VoiceSpeak <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <RotateDelay>d__22(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForEndOfFrame();
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<>4__this.RotateHead(amp, rotateUp: false);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public int PlayerID;
public PlayerControllerB thisPlayer;
public VoicePlayerState speakState;
public GameObject head;
public GameObject upperHead;
public GameObject lowerHead;
public MeshRenderer upperHeadMaterial;
public MeshRenderer lowerHeadMaterial;
public Transform ogHead;
public Vector3 ogHeadScale;
public Quaternion defaultRotation;
public bool isTalking;
private void Start()
{
speakState = StartOfRound.Instance.allPlayerScripts[PlayerID].voicePlayerState;
Plugin.SendLog($">>> VoiceSpeak ID: {PlayerID}");
Plugin.SendLog($">>> speakstate: {speakState}");
PositionHead();
speakState.OnStoppedSpeaking += PlayerNotTalking;
isTalking = false;
}
private void PositionHead()
{
//IL_0052: 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)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: 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_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: 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)
thisPlayer = StartOfRound.Instance.allPlayerScripts[PlayerID];
ogHead = thisPlayer.thisPlayerBody.Find("ScavengerModel/metarig/spine/spine.001/spine.002/spine.003/spine.004");
if ((Object)(object)ogHead != (Object)null)
{
GameObject val = Object.Instantiate<GameObject>(LMAssets.ScavHead, ogHead.position, ogHead.rotation);
val.transform.SetParent(((Component)ogHead).transform);
head = val;
upperHead = ((Component)head.transform.Find("upper head")).gameObject;
lowerHead = ((Component)head.transform.Find("lower head")).gameObject;
head.transform.localScale = new Vector3(14f, 14f, 14f);
head.transform.localPosition = new Vector3(0f, 10f, -14f);
ogHeadScale = ((Component)ogHead).transform.localScale;
defaultRotation = upperHead.transform.localRotation;
upperHeadMaterial = upperHead.GetComponent<MeshRenderer>();
lowerHeadMaterial = lowerHead.GetComponent<MeshRenderer>();
((Renderer)upperHeadMaterial).material = ((Renderer)thisPlayer.thisPlayerModel).material;
((Renderer)lowerHeadMaterial).material = ((Renderer)thisPlayer.thisPlayerModel).material;
head.SetActive(false);
}
}
public void RemoveThisClass()
{
Plugin.SendLog($"Destroyed VoiceSpeak.cs: {PlayerID}");
if (speakState != null)
{
speakState.OnStoppedSpeaking -= PlayerNotTalking;
speakState = null;
Plugin.SendLog($"{PlayerID} VoiceSpeak: unsubbed from PlayerNotTalking");
}
if ((Object)(object)head != (Object)null)
{
Object.Destroy((Object)(object)head);
}
Object.Destroy((Object)(object)this);
}
private void OnDestroy()
{
RemoveThisClass();
Plugin.SendLog("Executed OnDestroy() to prevent memory leak from OnStoppedSpeaking event");
}
private void Update()
{
if (StartOfRound.Instance.allPlayerScripts[PlayerID].isPlayerDead)
{
RemoveThisClass();
}
else if (speakState != null && speakState.IsSpeaking && speakState.Amplitude >= 0.005f)
{
PlayerIsTalking(speakState);
}
}
private void LateUpdate()
{
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
if (!StartOfRound.Instance.allPlayerScripts[PlayerID].isPlayerDead)
{
if ((Object)(object)ogHead != (Object)null && isTalking)
{
head.SetActive(true);
ogHead.localScale = new Vector3(0.01f, 0.01f, 0.01f);
}
else
{
head.SetActive(false);
ogHead.localScale = ogHeadScale;
}
}
}
private void PlayerIsTalking(VoicePlayerState state)
{
if (!StartOfRound.Instance.allPlayerScripts[PlayerID].isPlayerDead)
{
((Renderer)upperHeadMaterial).material = ((Renderer)thisPlayer.thisPlayerModel).material;
((Renderer)lowerHeadMaterial).material = ((Renderer)thisPlayer.thisPlayerModel).material;
if (state.Amplitude < 0.0003f)
{
RotateHead(state.Amplitude, rotateUp: false);
return;
}
RotateHead(state.Amplitude);
((MonoBehaviour)StartOfRound.Instance).StartCoroutine(RotateDelay(state.Amplitude, rotateUp: false));
isTalking = true;
}
}
private void PlayerNotTalking(VoicePlayerState state)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
if (!StartOfRound.Instance.allPlayerScripts[PlayerID].isPlayerDead)
{
upperHead.transform.localRotation = defaultRotation;
isTalking = false;
}
}
private void RotateHead(float amp, bool rotateUp = true)
{
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)head == (Object)null))
{
upperHead = ((Component)head.transform.Find("upper head")).gameObject;
float num = (rotateUp ? 120 : 320);
float lookPos = (rotateUp ? (-22f) : (-90f));
float num2 = CalculateXPos(amp, lookPos);
num += Math.Abs(num2);
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(num2, 0f, 0f);
Quaternion val2 = Quaternion.Euler(val);
upperHead.transform.localRotation = Quaternion.RotateTowards(upperHead.transform.localRotation, val2, num * Time.deltaTime);
}
}
private static float CalculateXPos(float amp, float lookPos)
{
if (lookPos == -90f)
{
return lookPos;
}
int num = -165;
int num2 = -90;
float num3 = amp * lookPos;
float num4 = lookPos * num3 * LConfig.defaultAmpMulti.Value;
return Mathf.Clamp(num4, (float)num2, (float)num);
}
[IteratorStateMachine(typeof(<RotateDelay>d__22))]
private IEnumerator RotateDelay(float amp, bool rotateUp)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <RotateDelay>d__22(0)
{
<>4__this = this,
amp = amp,
rotateUp = rotateUp
};
}
}
}