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 System.Security;
using System.Security.Permissions;
using BepInEx;
using Microsoft.CodeAnalysis;
using PEAKLib.Core;
using Photon.Pun;
using UnityEngine;
using Zorro.Core;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.ChristopherJordanLamb.Rule0_ensurance")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1+97bb5545f9223fa04b26a0852c3c1e7d36d8ca9c")]
[assembly: AssemblyProduct("com.github.ChristopherJordanLamb.Rule0_ensurance")]
[assembly: AssemblyTitle("LoveAtFirstBite")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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;
}
}
}
[BepInPlugin("com.github.ChristopherJordanLamb.Rule0_ensurance", "Rule0_ensurance", "1.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Rule0_ensurance : BaseUnityPlugin
{
[CompilerGenerated]
private sealed class <SetTargetAfterDelay>d__27 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public float delay;
public Scoutmaster sm;
public Character target;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <SetTargetAfterDelay>d__27(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(delay);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
sm.SetCurrentTarget(target, 120f);
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 Dictionary<Character, int> playerToTeam = new Dictionary<Character, int>();
private Dictionary<int, HashSet<Character>> teamMembers = new Dictionary<int, HashSet<Character>>();
private int nextTeamID;
private HashSet<string> completedFeeds = new HashSet<string>();
private Dictionary<string, float> activeFeedStartTimes = new Dictionary<string, float>();
private Dictionary<string, int> feedToItemID = new Dictionary<string, int>();
private float isolationDistance = 60f;
private float checkInterval = 5f;
private float timeSinceLastCheck;
private float healingRange = 3f;
private float healingRate = 0.1f;
private float healingCheckInterval = 1f;
private float timeSinceLastHealCheck;
private void Awake()
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Rule0_ensurance is loaded!");
GlobalEvents.OnItemConsumed = (Action<Item, Character>)Delegate.Combine(GlobalEvents.OnItemConsumed, new Action<Item, Character>(OnItemConsumed));
LoadChocolateBundle();
}
private void OnDestroy()
{
GlobalEvents.OnItemConsumed = (Action<Item, Character>)Delegate.Remove(GlobalEvents.OnItemConsumed, new Action<Item, Character>(OnItemConsumed));
}
private void OnItemConsumed(Item item, Character consumer)
{
Character val = default(Character);
if (!item.TryGetFeeder(ref val) && IsChocolateItem(item.itemID))
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Player " + ((Object)consumer).name + " ate chocolate themselves! Spawning scoutmaster!"));
SpawnScoutmasterForPlayer(consumer);
}
}
private void LoadChocolateBundle()
{
try
{
BundleLoader.LoadBundleWithName((BaseUnityPlugin)(object)this, "valentineschocolate.autoload_peakbundle", (Action<PeakBundle>)delegate(PeakBundle peakBundle)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Valentine's chocolate bundle loaded successfully!");
peakBundle.Mod.RegisterContent();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Valentine's chocolate item content registered!");
});
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Error loading valentine's chocolate bundle: " + ex.Message));
((BaseUnityPlugin)this).Logger.LogError((object)("Stack trace: " + ex.StackTrace));
}
}
private void Update()
{
MonitorFeeds();
timeSinceLastCheck += Time.deltaTime;
if (timeSinceLastCheck >= checkInterval)
{
timeSinceLastCheck = 0f;
if (PhotonNetwork.InRoom)
{
CheckAllPlayersIsolation();
}
}
timeSinceLastHealCheck += Time.deltaTime;
if (timeSinceLastHealCheck >= healingCheckInterval)
{
timeSinceLastHealCheck = 0f;
if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
{
HealNearbyTeammates();
}
}
if (Input.GetKeyDown((KeyCode)286))
{
CheckAllPlayersIsolation();
}
if (Input.GetKeyDown((KeyCode)287))
{
LogTeamInfo();
}
if (Input.GetKeyDown((KeyCode)288))
{
SpawnTestItem();
}
}
private void SpawnTestItem()
{
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: 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_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: 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_0096: 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)
Item val = ((IEnumerable<Item>)((DatabaseAsset<ItemDatabase, Item>)(object)SingletonAsset<ItemDatabase>.Instance).Objects).FirstOrDefault((Func<Item, bool>)((Item item) => (Object)(object)item != (Object)null && ((Object)item).name != null && ((Object)item).name.Contains("Chocolate")));
if ((Object)(object)val == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"Chocolate item not found in ItemDatabase! Make sure the bundle was loaded and registered.");
return;
}
Character localCharacter = Character.localCharacter;
if ((Object)(object)localCharacter == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Local character not found!");
return;
}
Vector3 val2 = localCharacter.Center + ((Component)localCharacter).transform.forward * 2f;
Item component = PhotonNetwork.InstantiateItemRoom(((Object)((Component)val).gameObject).name, val2, Quaternion.identity).GetComponent<Item>();
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Spawned chocolate item '{((Object)((Component)val).gameObject).name}' (ID: {val.itemID}) at {val2}");
}
private void MonitorFeeds()
{
if ((Object)(object)GameUtils.instance == (Object)null)
{
return;
}
FieldInfo field = typeof(GameUtils).GetField("feedData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field == null || !(field.GetValue(GameUtils.instance) is List<FeedData> list))
{
return;
}
HashSet<string> hashSet = new HashSet<string>();
foreach (FeedData item in list)
{
string text = $"{item.giverID}_{item.receiverID}";
hashSet.Add(text);
if (!activeFeedStartTimes.ContainsKey(text))
{
activeFeedStartTimes[text] = Time.time;
feedToItemID[text] = item.itemID;
((BaseUnityPlugin)this).Logger.LogInfo((object)("Feed started: " + text));
}
}
List<string> list2 = new List<string>();
Character val = default(Character);
Character val2 = default(Character);
foreach (KeyValuePair<string, float> activeFeedStartTime in activeFeedStartTimes)
{
string key = activeFeedStartTime.Key;
if (hashSet.Contains(key) || completedFeeds.Contains(key))
{
continue;
}
completedFeeds.Add(key);
list2.Add(key);
string[] array = key.Split('_');
int num = int.Parse(array[0]);
int num2 = int.Parse(array[1]);
if (Character.GetCharacterWithPhotonID(num, ref val) && Character.GetCharacterWithPhotonID(num2, ref val2))
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Feed completed: " + ((Object)val).name + " fed " + ((Object)val2).name));
if (num == num2 && feedToItemID.ContainsKey(key) && IsChocolateItem(feedToItemID[key]))
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Player " + ((Object)val).name + " fed themselves chocolate! Spawning scoutmaster!"));
SpawnScoutmasterForPlayer(val);
}
else
{
MergeTeams(val, val2);
}
}
}
foreach (string item2 in list2)
{
activeFeedStartTimes.Remove(item2);
}
if (completedFeeds.Count > 100)
{
completedFeeds.Clear();
}
}
private bool IsChocolateItem(int itemID)
{
Item val = ((IEnumerable<Item>)((DatabaseAsset<ItemDatabase, Item>)(object)SingletonAsset<ItemDatabase>.Instance).Objects).FirstOrDefault((Func<Item, bool>)((Item item) => (Object)(object)item != (Object)null && item.itemID == itemID));
if ((Object)(object)val != (Object)null && ((Object)val).name != null)
{
return ((Object)val).name.Contains("Chocolate");
}
return false;
}
private void HealNearbyTeammates()
{
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
CleanupTeams();
foreach (KeyValuePair<int, HashSet<Character>> teamMember in teamMembers)
{
int key = teamMember.Key;
HashSet<Character> value = teamMember.Value;
if (value.Count <= 1)
{
continue;
}
List<Character> list = value.Where((Character c) => (Object)(object)c != (Object)null && !c.data.dead).ToList();
foreach (Character item in list)
{
float currentStatus = item.refs.afflictions.GetCurrentStatus((STATUSTYPE)0);
if (currentStatus <= 0f)
{
continue;
}
foreach (Character item2 in list)
{
if (!((Object)(object)item2 == (Object)(object)item))
{
float num = Vector3.Distance(item.Center, item2.Center);
if (num <= healingRange)
{
float num2 = healingRate * healingCheckInterval;
item.refs.afflictions.SubtractStatus((STATUSTYPE)0, num2, false, false);
break;
}
}
}
}
}
}
private void MergeTeams(Character player1, Character player2)
{
int orCreateTeam = GetOrCreateTeam(player1);
int orCreateTeam2 = GetOrCreateTeam(player2);
if (orCreateTeam == orCreateTeam2)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Already teammates!");
return;
}
HashSet<Character> hashSet = new HashSet<Character>(teamMembers[orCreateTeam2]);
foreach (Character item in hashSet)
{
playerToTeam[item] = orCreateTeam;
teamMembers[orCreateTeam].Add(item);
}
teamMembers.Remove(orCreateTeam2);
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Teams merged! Team {orCreateTeam} now has {teamMembers[orCreateTeam].Count} members");
LogTeamMembers(orCreateTeam);
}
private int GetOrCreateTeam(Character player)
{
if (playerToTeam.ContainsKey(player))
{
return playerToTeam[player];
}
int num = nextTeamID++;
playerToTeam[player] = num;
teamMembers[num] = new HashSet<Character> { player };
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Created team {num} for {((Object)player).name}");
return num;
}
private void CheckAllPlayersIsolation()
{
if (!PhotonNetwork.IsMasterClient)
{
return;
}
CleanupTeams();
foreach (KeyValuePair<Character, int> item in playerToTeam.ToList())
{
Character key = item.Key;
int value = item.Value;
if (!((Object)(object)key == (Object)null) && !key.data.dead && IsIsolatedFromTeam(key, value))
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"WARNING: {((Object)key).name} is ISOLATED from team {value}!");
SpawnScoutmasterForPlayer(key);
}
}
}
private bool IsIsolatedFromTeam(Character player, int teamID)
{
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
if (!teamMembers.ContainsKey(teamID))
{
return false;
}
HashSet<Character> hashSet = teamMembers[teamID];
if (hashSet.Count <= 1)
{
return false;
}
foreach (Character item in hashSet)
{
if (!((Object)(object)item == (Object)(object)player) && !((Object)(object)item == (Object)null) && !item.data.dead)
{
float num = Vector3.Distance(player.Center, item.Center);
if (num > isolationDistance)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$" {((Object)player).name} is {num:F1}m from {((Object)item).name} (max: {isolationDistance}m)");
return true;
}
}
}
return false;
}
private void SpawnScoutmasterForPlayer(Character player)
{
//IL_0058: 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_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
if (!PhotonNetwork.IsMasterClient)
{
return;
}
foreach (Scoutmaster allScoutmaster in Scoutmaster.AllScoutmasters)
{
if ((Object)(object)allScoutmaster.currentTarget == (Object)(object)player)
{
return;
}
}
Vector3 spawnPositionNearPlayer = GetSpawnPositionNearPlayer(player, 30f, 50f);
GameObject val = PhotonNetwork.InstantiateRoomObject("Character_Scoutmaster", spawnPositionNearPlayer, Quaternion.identity, (byte)0, (object[])null);
Character component = val.GetComponent<Character>();
component.data.spawnPoint = null;
Scoutmaster component2 = val.GetComponent<Scoutmaster>();
if ((Object)(object)component2 != (Object)null)
{
((MonoBehaviour)this).StartCoroutine(SetTargetAfterDelay(component2, player, 0.5f));
}
((BaseUnityPlugin)this).Logger.LogInfo((object)("Spawned Scoutmaster for " + ((Object)player).name));
}
[IteratorStateMachine(typeof(<SetTargetAfterDelay>d__27))]
private IEnumerator SetTargetAfterDelay(Scoutmaster sm, Character target, float delay)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <SetTargetAfterDelay>d__27(0)
{
sm = sm,
target = target,
delay = delay
};
}
private Vector3 GetSpawnPositionNearPlayer(Character player, float minDistance, float maxDistance)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: 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)
//IL_0027: 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)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
Vector3 insideUnitSphere = Random.insideUnitSphere;
insideUnitSphere.y = 0f;
((Vector3)(ref insideUnitSphere)).Normalize();
float num = Random.Range(minDistance, maxDistance);
Vector3 val = player.Center + insideUnitSphere * num;
RaycastHit val2 = default(RaycastHit);
if (Physics.Raycast(val + Vector3.up * 100f, Vector3.down, ref val2, 200f))
{
val = ((RaycastHit)(ref val2)).point + Vector3.up * 2f;
}
return val;
}
private void CleanupTeams()
{
List<Character> list = new List<Character>();
foreach (KeyValuePair<Character, int> item in playerToTeam)
{
if ((Object)(object)item.Key == (Object)null || item.Key.data.dead)
{
list.Add(item.Key);
}
}
foreach (Character item2 in list)
{
int key = playerToTeam[item2];
teamMembers[key].Remove(item2);
playerToTeam.Remove(item2);
if (teamMembers[key].Count == 0)
{
teamMembers.Remove(key);
}
}
}
private void LogTeamInfo()
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"=== TEAMS ({teamMembers.Count} teams) ===");
if (teamMembers.Count == 0)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"No teams formed yet. Feed items to other players to create teams!");
return;
}
foreach (KeyValuePair<int, HashSet<Character>> teamMember in teamMembers)
{
LogTeamMembers(teamMember.Key);
}
}
private void LogTeamMembers(int teamID)
{
if (teamMembers.ContainsKey(teamID))
{
string arg = string.Join(", ", teamMembers[teamID].Select((Character c) => (!((Object)(object)c != (Object)null)) ? "null" : ((Object)c).name));
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Team {teamID} ({teamMembers[teamID].Count} members): {arg}");
}
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}