Decompiled source of PrisonerBlood v1.0.1

PrisonerBlood.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using PrisonerBlood.Models;
using PrisonerBlood.Services;
using ProjectM;
using ProjectM.Behaviours;
using ProjectM.Network;
using ProjectM.Scripting;
using ProjectM.Shared;
using Stunlock.Core;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;
using VampireCommandFramework;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("PrisonerBlood")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Server-side V Rising mod that lets players buy 100% blood quality prisoners and potions, and sell existing prisoners based on their blood quality.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("PrisonerBlood")]
[assembly: AssemblyTitle("PrisonerBlood")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PrisonerBlood
{
	internal static class Core
	{
		private static bool _hasInitialized;

		private static World _server;

		private static EntityManager _entityManager;

		private static ServerScriptMapper _serverScriptMapper;

		private static DebugEventsSystem _debugEventsSystem;

		public static World Server
		{
			get
			{
				object obj = _server;
				if (obj == null)
				{
					obj = GetWorld("Server") ?? throw new Exception("There is no Server world (yet). Did you install a server mod on the client?");
					_server = (World)obj;
				}
				return (World)obj;
			}
		}

		public static EntityManager EntityManager => (!(_entityManager == default(EntityManager))) ? _entityManager : (_entityManager = Server.EntityManager);

		public static ServerScriptMapper ServerScriptMapper => _serverScriptMapper ?? (_serverScriptMapper = Server.GetExistingSystemManaged<ServerScriptMapper>());

		public static ServerGameManager ServerGameManager => ServerScriptMapper.GetServerGameManager();

		public static DebugEventsSystem DebugEventsSystem => _debugEventsSystem ?? (_debugEventsSystem = Server.GetExistingSystemManaged<DebugEventsSystem>());

		public static ManualLogSource Log => Plugin.PluginLog;

		public static UnitSpawnerService UnitSpawner { get; private set; }

		public static void LogException(Exception e, [CallerMemberName] string caller = null)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(51, 5, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failure in ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(caller);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\nMessage: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.Message);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Inner:");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.InnerException?.Message);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\n\nStack: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.StackTrace);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\nInner Stack: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.InnerException?.StackTrace);
			}
			log.LogError(val);
		}

		internal static void InitializeAfterLoaded()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_008e: Expected O, but got Unknown
			if (!_hasInitialized)
			{
				_server = GetWorld("Server") ?? throw new Exception("There is no Server world (yet). Did you install a server mod on the client?");
				_entityManager = _server.EntityManager;
				_serverScriptMapper = _server.GetExistingSystemManaged<ServerScriptMapper>();
				_debugEventsSystem = _server.GetExistingSystemManaged<DebugEventsSystem>();
				UnitSpawner = new UnitSpawnerService();
				BuyPrisonerService.Initialize();
				BuyBloodPotionService.Initialize();
				SellPrisonerService.Initialize();
				_hasInitialized = true;
				ManualLogSource log = Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(10, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("InitializeAfterLoaded");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" completed");
				}
				log.LogInfo(val);
			}
		}

		internal static World GetWorld(string name)
		{
			Enumerator<World> enumerator = World.s_AllWorlds.GetEnumerator();
			while (enumerator.MoveNext())
			{
				World current = enumerator.Current;
				if (current != null && current.Name == name)
				{
					return current;
				}
			}
			return null;
		}
	}
	public static class ECSExtensions
	{
		public unsafe static void Write<T>(this Entity entity, T componentData) where T : struct
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			byte[] array = StructureToByteArray(componentData);
			int num = Marshal.SizeOf<T>();
			fixed (byte* ptr = array)
			{
				EntityManager entityManager = Core.EntityManager;
				((EntityManager)(ref entityManager)).SetComponentDataRaw(entity, val.TypeIndex, (void*)ptr, num);
			}
		}

		public unsafe static T Read<T>(this Entity entity) where T : struct
		{
			//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_0016: 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)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			EntityManager entityManager = Core.EntityManager;
			void* componentDataRawRO = ((EntityManager)(ref entityManager)).GetComponentDataRawRO(entity, val.TypeIndex);
			return Marshal.PtrToStructure<T>(new IntPtr(componentDataRawRO));
		}

		public unsafe static T ReadRW<T>(this Entity entity) where T : struct
		{
			//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_0016: 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)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			EntityManager entityManager = Core.EntityManager;
			void* componentDataRawRW = ((EntityManager)(ref entityManager)).GetComponentDataRawRW(entity, val.TypeIndex);
			return Marshal.PtrToStructure<T>(new IntPtr(componentDataRawRW));
		}

		public static bool Has<T>(this Entity entity)
		{
			//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_0016: 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)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			EntityManager entityManager = Core.EntityManager;
			return ((EntityManager)(ref entityManager)).HasComponent(entity, val);
		}

		public static void Add<T>(this Entity entity)
		{
			//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_0016: 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)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			EntityManager entityManager = Core.EntityManager;
			((EntityManager)(ref entityManager)).AddComponent(entity, val);
		}

		public static void Remove<T>(this Entity entity)
		{
			//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_0016: 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)
			ComponentType val = default(ComponentType);
			((ComponentType)(ref val))..ctor(Il2CppType.Of<T>(), (AccessMode)0);
			EntityManager entityManager = Core.EntityManager;
			((EntityManager)(ref entityManager)).RemoveComponent(entity, val);
		}

		private static byte[] StructureToByteArray<T>(T structure) where T : struct
		{
			int num = Marshal.SizeOf(structure);
			byte[] array = new byte[num];
			IntPtr intPtr = Marshal.AllocHGlobal(num);
			Marshal.StructureToPtr(structure, intPtr, fDeleteOld: true);
			Marshal.Copy(intPtr, array, 0, num);
			Marshal.FreeHGlobal(intPtr);
			return array;
		}
	}
	internal static class Helper
	{
		public static readonly HashSet<BloodType> AllowedBloodTypes = new HashSet<BloodType>
		{
			BloodType.Worker,
			BloodType.Warrior,
			BloodType.Rogue,
			BloodType.Brute,
			BloodType.Scholar,
			BloodType.Draculin,
			BloodType.Creature,
			BloodType.Mutant,
			BloodType.Corrupted
		};

		private static readonly HashSet<int> CombatBuffs = new HashSet<int> { 581443919, 697095869, 698151145 };

		public static NativeArray<Entity> GetEntitiesByComponentTypes<T1, T2>(bool includeAll = false, bool includeDisabled = false, bool includeSpawn = false, bool includePrefab = false, bool includeDestroyed = false)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			EntityQueryOptions val = (EntityQueryOptions)0;
			if (includeAll)
			{
				val = (EntityQueryOptions)(val | 0xC3);
			}
			if (includeDisabled)
			{
				val = (EntityQueryOptions)(val | 2);
			}
			if (includeSpawn)
			{
				val = (EntityQueryOptions)(val | 0x40);
			}
			if (includePrefab)
			{
				val = (EntityQueryOptions)(val | 1);
			}
			if (includeDestroyed)
			{
				val = (EntityQueryOptions)(val | 0x80);
			}
			EntityQueryBuilder val2 = new EntityQueryBuilder(AllocatorHandle.op_Implicit((Allocator)2));
			val2 = ((EntityQueryBuilder)(ref val2)).AddAll(new ComponentType(Il2CppType.Of<T1>(), (AccessMode)0));
			val2 = ((EntityQueryBuilder)(ref val2)).AddAll(new ComponentType(Il2CppType.Of<T2>(), (AccessMode)0));
			EntityQueryBuilder val3 = ((EntityQueryBuilder)(ref val2)).WithOptions(val);
			EntityManager entityManager = Core.EntityManager;
			EntityQuery val4 = ((EntityManager)(ref entityManager)).CreateEntityQuery(ref val3);
			return ((EntityQuery)(ref val4)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
		}

		public static bool TryGetInventoryEntity(Entity characterEntity, out Entity inventoryEntity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return InventoryUtilities.TryGetInventoryEntity<EntityManager>(Core.EntityManager, characterEntity, ref inventoryEntity, 0);
		}

		public static int GetItemCountInInventory(Entity characterEntity, PrefabGUID itemPrefab)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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)
			EntityManager entityManager = Core.EntityManager;
			if (!TryGetInventoryEntity(characterEntity, out var inventoryEntity))
			{
				return 0;
			}
			if (((EntityManager)(ref entityManager)).HasComponent<InventoryBuffer>(inventoryEntity))
			{
				DynamicBuffer<InventoryBuffer> buffer = ((EntityManager)(ref entityManager)).GetBuffer<InventoryBuffer>(inventoryEntity, false);
				int num = 0;
				for (int i = 0; i < buffer.Length; i++)
				{
					InventoryBuffer val = buffer[i];
					if (((PrefabGUID)(ref val.ItemType)).GuidHash == ((PrefabGUID)(ref itemPrefab)).GuidHash)
					{
						num += val.Amount;
					}
				}
				return num;
			}
			int num2 = 0;
			InventoryBuffer val2 = default(InventoryBuffer);
			for (int j = 0; j < 36; j++)
			{
				if (InventoryUtilities.TryGetItemAtSlot<EntityManager>(entityManager, characterEntity, j, ref val2) && ((PrefabGUID)(ref val2.ItemType)).GuidHash == ((PrefabGUID)(ref itemPrefab)).GuidHash)
				{
					num2 += val2.Amount;
				}
			}
			return num2;
		}

		public static int GetEmptyInventorySlotsCount(Entity characterEntity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = Core.EntityManager;
			if (!TryGetInventoryEntity(characterEntity, out var inventoryEntity))
			{
				return 0;
			}
			if (!((EntityManager)(ref entityManager)).HasComponent<InventoryBuffer>(inventoryEntity))
			{
				return 0;
			}
			DynamicBuffer<InventoryBuffer> buffer = ((EntityManager)(ref entityManager)).GetBuffer<InventoryBuffer>(inventoryEntity, false);
			int num = 0;
			for (int i = 0; i < buffer.Length; i++)
			{
				InventoryBuffer val = buffer[i];
				if (((PrefabGUID)(ref val.ItemType)).GuidHash == 0)
				{
					num++;
				}
			}
			return num;
		}

		public static Entity AddItemToInventory(Entity recipient, PrefabGUID guid, int amount)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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)
			try
			{
				ServerGameManager serverGameManager = Core.ServerGameManager;
				AddItemResponse val = ((ServerGameManager)(ref serverGameManager)).TryAddInventoryItem(recipient, guid, amount);
				return val.NewEntity;
			}
			catch (Exception e)
			{
				Core.LogException(e, "AddItemToInventory");
			}
			return Entity.Null;
		}

		public static bool TryRemoveItemsFromInventory(Entity characterEntity, PrefabGUID itemPrefab, int amount)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//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)
			EntityManager entityManager = Core.EntityManager;
			if (!TryGetInventoryEntity(characterEntity, out var inventoryEntity))
			{
				return false;
			}
			if (!((EntityManager)(ref entityManager)).HasComponent<InventoryBuffer>(inventoryEntity))
			{
				return false;
			}
			DynamicBuffer<InventoryBuffer> buffer = ((EntityManager)(ref entityManager)).GetBuffer<InventoryBuffer>(inventoryEntity, false);
			int num = amount;
			int num2 = buffer.Length - 1;
			while (num2 >= 0 && num > 0)
			{
				InventoryBuffer val = buffer[num2];
				if (((PrefabGUID)(ref val.ItemType)).GuidHash == ((PrefabGUID)(ref itemPrefab)).GuidHash && val.Amount > 0)
				{
					int num3 = math.min(val.Amount, num);
					val.Amount -= num3;
					num -= num3;
					if (val.Amount <= 0)
					{
						val.ItemType = new PrefabGUID(0);
						val.Amount = 0;
					}
					buffer[num2] = val;
				}
				num2--;
			}
			return num == 0;
		}

		public static void BroadcastSystemMessage(string message)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				FixedString512Bytes val = default(FixedString512Bytes);
				((FixedString512Bytes)(ref val))..ctor(message ?? string.Empty);
				ServerChatUtils.SendSystemMessageToAllClients(Core.EntityManager, ref val);
			}
			catch (Exception e)
			{
				Core.LogException(e, "BroadcastSystemMessage");
			}
		}

		public static void NotifyUser(Entity userEntity, string message)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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)
			//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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!(userEntity == Entity.Null))
				{
					EntityManager entityManager = Core.EntityManager;
					if (((EntityManager)(ref entityManager)).Exists(userEntity))
					{
						entityManager = Core.EntityManager;
						User componentData = ((EntityManager)(ref entityManager)).GetComponentData<User>(userEntity);
						FixedString512Bytes val = default(FixedString512Bytes);
						((FixedString512Bytes)(ref val))..ctor(message ?? string.Empty);
						ServerChatUtils.SendSystemMessageToClient(Core.EntityManager, componentData, ref val);
					}
				}
			}
			catch (Exception e)
			{
				Core.LogException(e, "NotifyUser");
			}
		}

		public static bool IsInCombat(Entity characterEntity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = Core.EntityManager;
			foreach (int combatBuff in CombatBuffs)
			{
				if (BuffUtility.HasBuff<EntityManager>(entityManager, characterEntity, PrefabIdentifier.op_Implicit(new PrefabGUID(combatBuff))))
				{
					return true;
				}
			}
			return false;
		}
	}
	[BepInPlugin("PrisonerBlood", "PrisonerBlood", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		internal static Harmony Harmony;

		internal static ManualLogSource PluginLog;

		public override void Load()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			if (!(Application.productName != "VRisingServer"))
			{
				PluginLog = ((BasePlugin)this).Log;
				ManualLogSource log = ((BasePlugin)this).Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(27, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("PrisonerBlood");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" version ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.1");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
				}
				log.LogInfo(val);
				Harmony = new Harmony("PrisonerBlood");
				Harmony.PatchAll(Assembly.GetExecutingAssembly());
				ConfigService.Initialize();
				CommandRegistry.RegisterAll();
			}
		}

		public override bool Unload()
		{
			CommandRegistry.UnregisterAssembly();
			Harmony harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			return true;
		}

		internal static bool HasLoaded()
		{
			World world = Core.GetWorld("Server");
			if (world == null)
			{
				return false;
			}
			PrefabCollectionSystem existingSystemManaged = world.GetExistingSystemManaged<PrefabCollectionSystem>();
			return existingSystemManaged != null && existingSystemManaged.SpawnableNameToPrefabGuidDictionary.Count > 0;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "PrisonerBlood";

		public const string PLUGIN_NAME = "PrisonerBlood";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace PrisonerBlood.Services
{
	internal static class BuffService
	{
		public static bool AddBuff(Entity userEntity, Entity targetEntity, PrefabGUID buffPrefab, int duration = -1, bool immortal = true)
		{
			//IL_0009: 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_0012: 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)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: 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_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			DebugEventsSystem debugEventsSystem = Core.DebugEventsSystem;
			ApplyBuffDebugEvent val = default(ApplyBuffDebugEvent);
			val.BuffPrefabGUID = buffPrefab;
			ApplyBuffDebugEvent val2 = val;
			FromCharacter val3 = default(FromCharacter);
			val3.User = userEntity;
			val3.Character = targetEntity;
			FromCharacter val4 = val3;
			Entity val5 = default(Entity);
			if (BuffUtility.TryGetBuff<EntityManager>(Core.EntityManager, targetEntity, PrefabIdentifier.op_Implicit(buffPrefab), ref val5))
			{
				return false;
			}
			debugEventsSystem.ApplyBuff(val4, val2);
			Entity entity = default(Entity);
			if (!BuffUtility.TryGetBuff<EntityManager>(Core.EntityManager, targetEntity, PrefabIdentifier.op_Implicit(buffPrefab), ref entity))
			{
				return false;
			}
			if (entity.Has<CreateGameplayEventsOnSpawn>())
			{
				entity.Remove<CreateGameplayEventsOnSpawn>();
			}
			if (entity.Has<GameplayEventListeners>())
			{
				entity.Remove<GameplayEventListeners>();
			}
			if (immortal)
			{
				if (!entity.Has<Buff_Persists_Through_Death>())
				{
					entity.Add<Buff_Persists_Through_Death>();
				}
				if (entity.Has<RemoveBuffOnGameplayEvent>())
				{
					entity.Remove<RemoveBuffOnGameplayEvent>();
				}
				if (entity.Has<RemoveBuffOnGameplayEventEntry>())
				{
					entity.Remove<RemoveBuffOnGameplayEventEntry>();
				}
			}
			if (duration > -1 && duration != 0)
			{
				if (!entity.Has<LifeTime>())
				{
					entity.Add<LifeTime>();
					entity.Write<LifeTime>(new LifeTime
					{
						EndAction = (LifeTimeEndAction)2
					});
				}
				LifeTime componentData = entity.Read<LifeTime>();
				componentData.Duration = duration;
				entity.Write<LifeTime>(componentData);
			}
			else if (duration == -1)
			{
				if (entity.Has<LifeTime>())
				{
					LifeTime componentData2 = entity.Read<LifeTime>();
					componentData2.EndAction = (LifeTimeEndAction)0;
					entity.Write<LifeTime>(componentData2);
				}
				if (entity.Has<RemoveBuffOnGameplayEvent>())
				{
					entity.Remove<RemoveBuffOnGameplayEvent>();
				}
				if (entity.Has<RemoveBuffOnGameplayEventEntry>())
				{
					entity.Remove<RemoveBuffOnGameplayEventEntry>();
				}
			}
			return true;
		}

		public static void RemoveBuff(Entity Character, PrefabGUID buffPrefab)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Entity val = default(Entity);
			if (BuffUtility.TryGetBuff<EntityManager>(Core.EntityManager, Character, PrefabIdentifier.op_Implicit(buffPrefab), ref val))
			{
				DestroyUtility.Destroy(Core.EntityManager, val, (DestroyDebugReason)13, (string)null, 0);
			}
		}
	}
	internal static class BuyBloodPotionService
	{
		private static readonly string CONFIG_DIR = Path.Combine(Paths.ConfigPath, "PrisonerBlood");

		private static readonly string LOG_FILE = Path.Combine(CONFIG_DIR, "buybloodpotion_log.csv");

		private static readonly object LOG_LOCK = new object();

		private static readonly PrefabGUID BloodPotionPrefab = new PrefabGUID(1223264867);

		public static string CurrencyName => GetCurrency().Name;

		public static void Initialize()
		{
			ConfigService.Initialize();
			CheckAndMigrateLogFile();
			InitializeLogFile();
		}

		public static void Reload()
		{
			ConfigService.Reload();
		}

		public static bool IsEnabled()
		{
			return GetConfig().Enabled;
		}

		public static (PrefabGUID Prefab, string Name) GetCurrency()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			BuySection config = GetConfig();
			return (new PrefabGUID(config.CurrencyPrefab), config.CurrencyName);
		}

		public static (int DefaultCost, Dictionary<string, int> Prices) GetPriceSnapshot()
		{
			BuySection config = GetConfig();
			return (config.DefaultCost, new Dictionary<string, int>(config.BloodCosts, StringComparer.OrdinalIgnoreCase));
		}

		public static bool TryParseBloodTypeStrict(string input, out BloodType type)
		{
			type = (BloodType)0;
			if (string.IsNullOrWhiteSpace(input))
			{
				return false;
			}
			input = input.Trim();
			if (int.TryParse(input, out var _))
			{
				return false;
			}
			if (!Enum.TryParse<BloodType>(input, ignoreCase: true, out type))
			{
				return false;
			}
			return Helper.AllowedBloodTypes.Contains(type);
		}

		public static void ReplyHelp(Action<string> reply, string warningLine = null)
		{
			var (defaultCost, prices) = GetPriceSnapshot();
			if (!string.IsNullOrWhiteSpace(warningLine))
			{
				reply(warningLine);
			}
			reply("<color=yellow>Command:</color> <color=green>.buy bloodpotion <BloodType> (Amount)</color>");
			reply("<color=yellow>Example:</color> <color=green>.buy bloodpotion rogue 1</color> or <color=green>.buy bp rogue</color>");
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(89, 1, stringBuilder2);
			handler.AppendLiteral("<color=yellow>Blood types</color> : <color=yellow>Costs</color> <color=#87CEFA>(");
			handler.AppendFormatted(CurrencyName);
			handler.AppendLiteral(")</color>");
			stringBuilder2.AppendLine(ref handler);
			var source = (from x in Helper.AllowedBloodTypes.Select(delegate(BloodType bt)
				{
					string text = bt.ToString();
					int value;
					bool flag = prices.TryGetValue(text, out value);
					int cost = (flag ? value : defaultCost);
					return new
					{
						Name = text,
						Cost = cost,
						IsDefault = !flag
					};
				})
				orderby x.Cost
				select x).ThenBy(x => x.Name, StringComparer.OrdinalIgnoreCase).ToList();
			List<string> source2 = source.Select(x => $"{x.Name} : {x.Cost}").ToList();
			foreach (string[] item in source2.Chunk(3))
			{
				stringBuilder.AppendLine(string.Join(" <color=white>|</color> ", item));
			}
			reply(stringBuilder.ToString().TrimEnd());
			reply("<color=yellow>Blood Merlot with <color=green>100%</color> blood quality will be added to your inventory.</color>");
		}

		public static void BuyBloodPotion(Entity senderCharacterEntity, ulong steamId, string playerName, BloodType type, int quantity, Action<string> reply)
		{
			//IL_0030: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: 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)
			if (!IsEnabled())
			{
				reply("<color=yellow>Buy Blood Potion:</color> <color=red>Disabled.</color>");
				return;
			}
			if (quantity < 1)
			{
				quantity = 1;
			}
			EntityManager entityManager = Core.EntityManager;
			if (senderCharacterEntity == Entity.Null || !((EntityManager)(ref entityManager)).Exists(senderCharacterEntity))
			{
				reply("<color=red>Character not ready.</color>");
				return;
			}
			if (Helper.IsInCombat(senderCharacterEntity))
			{
				reply("<color=red>You cannot buy a blood potion while in combat.</color>");
				return;
			}
			int emptyInventorySlotsCount = Helper.GetEmptyInventorySlotsCount(senderCharacterEntity);
			if (emptyInventorySlotsCount < quantity)
			{
				LogPurchase(steamId, playerName, type.ToString(), quantity, 0, success: false, $"not_enough_inventory_slots_{emptyInventorySlotsCount}/{quantity}");
				reply($"<color=yellow>Failed!</color> Not enough inventory slots ({emptyInventorySlotsCount}/{quantity}).");
				return;
			}
			int cost = GetCost(type.ToString());
			int num = cost * quantity;
			if (!TrySpendCurrency(senderCharacterEntity, num, out var spendLogReason, out var spendReplyMessage))
			{
				LogPurchase(steamId, playerName, type.ToString(), quantity, num, success: false, spendLogReason);
				reply(spendReplyMessage);
				return;
			}
			int num2 = 0;
			for (int i = 0; i < quantity; i++)
			{
				Entity val = Helper.AddItemToInventory(senderCharacterEntity, BloodPotionPrefab, 1);
				if (val != Entity.Null && ((EntityManager)(ref entityManager)).Exists(val))
				{
					try
					{
						StoredBlood val2 = default(StoredBlood);
						val2.BloodQuality = 100f;
						val2.PrimaryBloodType = new PrefabGUID((int)type);
						StoredBlood val3 = val2;
						((EntityManager)(ref entityManager)).SetComponentData<StoredBlood>(val, val3);
						num2++;
					}
					catch (Exception e)
					{
						Core.LogException(e, "BuyBloodPotion");
					}
				}
			}
			LogPurchase(steamId, playerName, type.ToString(), num2, num, success: true, "successful");
			string value = ((num2 > 1) ? "s were" : " was");
			reply($"<color=green>Success!</color> {num2} blood potion{value} added to your inventory.");
		}

		private static bool TrySpendCurrency(Entity characterEntity, int amount, out string spendLogReason, out string spendReplyMessage)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			spendLogReason = string.Empty;
			spendReplyMessage = string.Empty;
			try
			{
				if (amount <= 0)
				{
					spendLogReason = "invalid_cost";
					spendReplyMessage = "<color=yellow>Failed!</color> Invalid cost";
					return false;
				}
				(PrefabGUID Prefab, string Name) currency = GetCurrency();
				PrefabGUID item = currency.Prefab;
				string item2 = currency.Name;
				int itemCountInInventory = Helper.GetItemCountInInventory(characterEntity, item);
				if (itemCountInInventory < amount)
				{
					spendLogReason = $"not_enough_currency_{itemCountInInventory}/{amount}";
					spendReplyMessage = $"<color=yellow>Failed!</color> Not enough {item2} ({itemCountInInventory}/{amount})";
					return false;
				}
				if (!Helper.TryRemoveItemsFromInventory(characterEntity, item, amount))
				{
					spendLogReason = "remove_items_failed";
					spendReplyMessage = "<color=red>Failed!</color> Remove items failed";
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				spendLogReason = "exception: " + ex.Message;
				spendReplyMessage = "<color=red>Error!</color> An unexpected error occurred while spending currency.";
				return false;
			}
		}

		private static int GetCost(string bloodTypeName)
		{
			BuySection config = GetConfig();
			foreach (KeyValuePair<string, int> bloodCost in config.BloodCosts)
			{
				if (string.Equals(bloodCost.Key, bloodTypeName, StringComparison.OrdinalIgnoreCase))
				{
					return (bloodCost.Value > 0) ? bloodCost.Value : config.DefaultCost;
				}
			}
			return config.DefaultCost;
		}

		private static BuySection GetConfig()
		{
			return ConfigService.GetBuyBloodPotionConfig();
		}

		private static void CheckAndMigrateLogFile()
		{
			try
			{
				lock (LOG_LOCK)
				{
					Directory.CreateDirectory(CONFIG_DIR);
					if (!File.Exists(LOG_FILE))
					{
						return;
					}
					string text = null;
					using (FileStream stream = new FileStream(LOG_FILE, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
					{
						using StreamReader streamReader = new StreamReader(stream);
						text = streamReader.ReadLine();
					}
					if (!string.IsNullOrEmpty(text) && !text.Contains("quantity"))
					{
						string text2 = DateTime.Now.ToString("yyyyMMdd_HHmmss");
						string destFileName = Path.Combine(CONFIG_DIR, "buybloodpotion_log_old_" + text2 + ".csv");
						File.Move(LOG_FILE, destFileName);
					}
				}
			}
			catch (Exception e)
			{
				Core.LogException(e, "CheckAndMigrateLogFile");
			}
		}

		private static void InitializeLogFile()
		{
			try
			{
				lock (LOG_LOCK)
				{
					Directory.CreateDirectory(CONFIG_DIR);
					if (File.Exists(LOG_FILE))
					{
						return;
					}
					using FileStream stream = new FileStream(LOG_FILE, FileMode.Create, FileAccess.Write, FileShare.Read);
					using StreamWriter streamWriter = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
					streamWriter.WriteLine("server_time,steam_id,player_name,blood_type,quantity,cost,success,reason");
				}
			}
			catch (Exception e)
			{
				Core.LogException(e, "InitializeLogFile");
			}
		}

		private static void LogPurchase(ulong steamId, string playerName, string bloodType, int quantity, int cost, bool success, string reason)
		{
			try
			{
				lock (LOG_LOCK)
				{
					using FileStream stream = new FileStream(LOG_FILE, FileMode.Append, FileAccess.Write, FileShare.Read);
					using StreamWriter streamWriter = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
					streamWriter.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss},{steamId},{Csv(playerName)},{Csv(bloodType)},{quantity},{cost},{(success ? "true" : "false")},{Csv(reason)}");
				}
			}
			catch (Exception e)
			{
				Core.LogException(e, "LogPurchase");
			}
		}

		private static string Csv(string s)
		{
			if (s == null)
			{
				return "\"\"";
			}
			return "\"" + s.Replace("\"", "\"\"") + "\"";
		}
	}
	internal static class BuyPrisonerService
	{
		private static readonly string CONFIG_DIR = Path.Combine(Paths.ConfigPath, "PrisonerBlood");

		private static readonly string LOG_FILE = Path.Combine(CONFIG_DIR, "buyprisoner_log.csv");

		private static readonly object LOG_LOCK = new object();

		private static readonly PrefabGUID PrisonerPrefab = new PrefabGUID(593505050);

		private static readonly PrefabGUID ImprisonedBuffPrefab = new PrefabGUID(1603329680);

		private const float PrisonCellSearchRadius = 3f;

		public static string CurrencyName => GetCurrency().Name;

		public static void Initialize()
		{
			ConfigService.Initialize();
			InitializeLogFile();
		}

		public static void Reload()
		{
			ConfigService.Reload();
		}

		public static bool IsEnabled()
		{
			return GetConfig().Enabled;
		}

		public static (PrefabGUID Prefab, string Name) GetCurrency()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			BuySection config = GetConfig();
			return (new PrefabGUID(config.CurrencyPrefab), config.CurrencyName);
		}

		public static (int DefaultCost, Dictionary<string, int> Prices) GetPriceSnapshot()
		{
			BuySection config = GetConfig();
			return (config.DefaultCost, new Dictionary<string, int>(config.BloodCosts, StringComparer.OrdinalIgnoreCase));
		}

		public static bool TryParseBloodTypeStrict(string input, out BloodType type)
		{
			type = (BloodType)0;
			if (string.IsNullOrWhiteSpace(input))
			{
				return false;
			}
			input = input.Trim();
			if (int.TryParse(input, out var _))
			{
				return false;
			}
			if (!Enum.TryParse<BloodType>(input, ignoreCase: true, out type))
			{
				return false;
			}
			return Helper.AllowedBloodTypes.Contains(type);
		}

		public static void ReplyHelp(Action<string> reply, string warningLine = null)
		{
			var (defaultCost, prices) = GetPriceSnapshot();
			if (!string.IsNullOrWhiteSpace(warningLine))
			{
				reply(warningLine);
			}
			reply("<color=yellow>Command:</color> <color=green>.buy prisoner <BloodType></color>");
			reply("<color=yellow>Example:</color> <color=green>.buy prisoner rogue</color> or <color=green>.buy ps rogue</color>");
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(89, 1, stringBuilder2);
			handler.AppendLiteral("<color=yellow>Blood types</color> : <color=yellow>Costs</color> <color=#87CEFA>(");
			handler.AppendFormatted(CurrencyName);
			handler.AppendLiteral(")</color>");
			stringBuilder2.AppendLine(ref handler);
			var source = (from x in Helper.AllowedBloodTypes.Select(delegate(BloodType bt)
				{
					string text = bt.ToString();
					int value;
					bool flag = prices.TryGetValue(text, out value);
					int cost = (flag ? value : defaultCost);
					return new
					{
						Name = text,
						Cost = cost,
						IsDefault = !flag
					};
				})
				orderby x.Cost
				select x).ThenBy(x => x.Name, StringComparer.OrdinalIgnoreCase).ToList();
			List<string> source2 = source.Select(x => $"{x.Name} : {x.Cost}").ToList();
			foreach (string[] item in source2.Chunk(3))
			{
				stringBuilder.AppendLine(string.Join(" <color=white>|</color> ", item));
			}
			reply(stringBuilder.ToString().TrimEnd());
			reply($"<color=yellow>A prisoner with <color=green>100%</color> blood quality will spawn in your nearest empty prison cell within {3f:0.0}m.</color>");
		}

		public static void BuyPrisoner(Entity senderUserEntity, Entity senderCharacterEntity, ulong steamId, string playerName, BloodType type, Action<string> reply)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled())
			{
				reply("<color=yellow>Buy Prisoner:</color> <color=red>Disabled.</color>");
				return;
			}
			EntityManager em = Core.EntityManager;
			if (senderCharacterEntity == Entity.Null || !((EntityManager)(ref em)).Exists(senderCharacterEntity))
			{
				reply("<color=red>Character not ready.</color>");
				return;
			}
			if (Helper.IsInCombat(senderCharacterEntity))
			{
				reply("<color=red>You cannot buy a prisoner while in combat.</color>");
				return;
			}
			if (!TryFindClosestEmptyOwnedPrisonCell(senderCharacterEntity, 3f, out var prisonCellEntity, out var prisonCellPosition, out var cellLogReason, out var cellReplyMessage))
			{
				LogPurchase(steamId, playerName, type.ToString(), 0, success: false, cellLogReason);
				reply(cellReplyMessage);
				return;
			}
			int cost = GetCost(type.ToString());
			if (!TrySpendCurrency(senderCharacterEntity, cost, out var spendLogReason, out var spendReplyMessage))
			{
				LogPurchase(steamId, playerName, type.ToString(), 0, success: false, spendLogReason);
				reply(spendReplyMessage);
				return;
			}
			Core.UnitSpawner.SpawnWithCallback(senderUserEntity, PrisonerPrefab, new float2(prisonCellPosition.x, prisonCellPosition.z), -1f, delegate(Entity e)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (!(e == Entity.Null) && ((EntityManager)(ref em)).Exists(e))
					{
						SetupPurchasedPrisoner(senderUserEntity, e, prisonCellEntity, type);
						LogPurchase(steamId, playerName, type.ToString(), cost, success: true, "successful");
						reply("<color=green>Success!</color> A prisoner was placed in your prison cell.");
						string message = $"<color=white>{playerName}</color> just spent <color=#87CEFA>{cost} {CurrencyName}</color> to buy a prisoner with <color=green>100%</color> <color=yellow>{type}</color> blood. Learn more, type <color=green>.buy prisoner help</color>";
						Helper.BroadcastSystemMessage(message);
					}
				}
				catch (Exception ex)
				{
					LogPurchase(steamId, playerName, type.ToString(), 0, success: false, "spawn_callback_error: " + ex.Message);
					reply("<color=red>Prisoner spawned but setup failed.</color>");
					Core.LogException(ex, "BuyPrisoner");
				}
			}, prisonCellPosition.y);
		}

		private static void SetupPurchasedPrisoner(Entity senderUserEntity, Entity prisonerEntity, Entity prisonCellEntity, BloodType type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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)
			//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_00d1: 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)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_0116: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = Core.EntityManager;
			if (prisonerEntity.Has<BloodConsumeSource>())
			{
				BloodConsumeSource componentData = ((EntityManager)(ref entityManager)).GetComponentData<BloodConsumeSource>(prisonerEntity);
				componentData.UnitBloodType._Value = new PrefabGUID((int)type);
				componentData.BloodQuality = 100f;
				componentData.CanBeConsumed = true;
				((EntityManager)(ref entityManager)).SetComponentData<BloodConsumeSource>(prisonerEntity, componentData);
			}
			if (prisonerEntity.Has<BehaviourTreeState>())
			{
				BehaviourTreeState componentData2 = prisonerEntity.Read<BehaviourTreeState>();
				componentData2.Value = (GenericEnemyState)2048;
				prisonerEntity.Write<BehaviourTreeState>(componentData2);
			}
			if (prisonerEntity.Has<BehaviourTreeStateMetadata>())
			{
				BehaviourTreeStateMetadata componentData3 = prisonerEntity.Read<BehaviourTreeStateMetadata>();
				componentData3.PreviousState = (GenericEnemyState)2048;
				prisonerEntity.Write<BehaviourTreeStateMetadata>(componentData3);
			}
			if (!prisonerEntity.Has<Imprisoned>())
			{
				prisonerEntity.Add<Imprisoned>();
			}
			prisonerEntity.Write<Imprisoned>(new Imprisoned
			{
				PrisonCellEntity = prisonCellEntity
			});
			PrisonCell componentData4 = prisonCellEntity.Read<PrisonCell>();
			componentData4.ImprisonedEntity = NetworkedEntity.op_Implicit(prisonerEntity);
			prisonCellEntity.Write<PrisonCell>(componentData4);
			if (prisonCellEntity.Has<Prisonstation>())
			{
				Prisonstation componentData5 = prisonCellEntity.Read<Prisonstation>();
				componentData5.HasPrisoner = true;
				prisonCellEntity.Write<Prisonstation>(componentData5);
			}
			BuffService.AddBuff(senderUserEntity, prisonerEntity, ImprisonedBuffPrefab);
		}

		private static bool TryFindClosestEmptyOwnedPrisonCell(Entity senderCharacterEntity, float radius, out Entity prisonCellEntity, out float3 prisonCellPosition, out string cellLogReason, out string cellReplyMessage)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			//IL_0060: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00c6: 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_00ca: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: 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)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: 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_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			prisonCellEntity = Entity.Null;
			prisonCellPosition = default(float3);
			cellLogReason = "no_empty_owned_prison_cell_found";
			cellReplyMessage = $"<color=yellow>Failed!</color> No empty owned prison cell found within {3f:0.0}m.";
			EntityManager entityManager = Core.EntityManager;
			if (!((EntityManager)(ref entityManager)).HasComponent<LocalToWorld>(senderCharacterEntity))
			{
				cellLogReason = "cannot_find_player_position";
				cellReplyMessage = "<color=yellow>Failed!</color> Cannot find player position.";
				return false;
			}
			if (!((EntityManager)(ref entityManager)).HasComponent<Team>(senderCharacterEntity))
			{
				cellLogReason = "cannot_read_player_team";
				cellReplyMessage = "<color=yellow>Failed!</color> Cannot read player team.";
				return false;
			}
			LocalToWorld componentData = ((EntityManager)(ref entityManager)).GetComponentData<LocalToWorld>(senderCharacterEntity);
			float3 position = ((LocalToWorld)(ref componentData)).Position;
			int value = ((EntityManager)(ref entityManager)).GetComponentData<Team>(senderCharacterEntity).Value;
			float num = radius * radius;
			NativeArray<Entity> entitiesByComponentTypes = Helper.GetEntitiesByComponentTypes<PrisonCell, LocalToWorld>();
			try
			{
				Enumerator<Entity> enumerator = entitiesByComponentTypes.GetEnumerator();
				while (enumerator.MoveNext())
				{
					Entity current = enumerator.Current;
					if (!((EntityManager)(ref entityManager)).Exists(current) || !((EntityManager)(ref entityManager)).HasComponent<Team>(current) || ((EntityManager)(ref entityManager)).GetComponentData<Team>(current).Value != value)
					{
						continue;
					}
					PrisonCell componentData2 = ((EntityManager)(ref entityManager)).GetComponentData<PrisonCell>(current);
					Entity entity = componentData2.ImprisonedEntity._Entity;
					if (!(entity != Entity.Null) || !((EntityManager)(ref entityManager)).Exists(entity))
					{
						componentData = ((EntityManager)(ref entityManager)).GetComponentData<LocalToWorld>(current);
						float3 position2 = ((LocalToWorld)(ref componentData)).Position;
						float num2 = math.distancesq(position, position2);
						if (!(num2 > num))
						{
							num = num2;
							prisonCellEntity = current;
							prisonCellPosition = position2;
						}
					}
				}
			}
			finally
			{
				entitiesByComponentTypes.Dispose();
			}
			bool flag = prisonCellEntity != Entity.Null;
			if (flag)
			{
				cellLogReason = string.Empty;
				cellReplyMessage = string.Empty;
			}
			return flag;
		}

		private static bool TrySpendCurrency(Entity characterEntity, int amount, out string spendLogReason, out string spendReplyMessage)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			spendLogReason = string.Empty;
			spendReplyMessage = string.Empty;
			try
			{
				if (amount <= 0)
				{
					spendLogReason = "invalid_cost";
					spendReplyMessage = "<color=yellow>Failed!</color> Invalid cost";
					return false;
				}
				(PrefabGUID Prefab, string Name) currency = GetCurrency();
				PrefabGUID item = currency.Prefab;
				string item2 = currency.Name;
				int itemCountInInventory = Helper.GetItemCountInInventory(characterEntity, item);
				if (itemCountInInventory < amount)
				{
					spendLogReason = $"not_enough_currency_{itemCountInInventory}/{amount}";
					spendReplyMessage = $"<color=yellow>Failed!</color> Not enough {item2} ({itemCountInInventory}/{amount})";
					return false;
				}
				if (!Helper.TryRemoveItemsFromInventory(characterEntity, item, amount))
				{
					spendLogReason = "remove_items_failed";
					spendReplyMessage = "<color=red>Failed!</color> Remove items failed";
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				spendLogReason = "exception: " + ex.Message;
				spendReplyMessage = "<color=red>Error!</color> An unexpected error occurred while spending currency.";
				return false;
			}
		}

		private static int GetCost(string bloodTypeName)
		{
			BuySection config = GetConfig();
			foreach (KeyValuePair<string, int> bloodCost in config.BloodCosts)
			{
				if (string.Equals(bloodCost.Key, bloodTypeName, StringComparison.OrdinalIgnoreCase))
				{
					return (bloodCost.Value > 0) ? bloodCost.Value : config.DefaultCost;
				}
			}
			return config.DefaultCost;
		}

		private static BuySection GetConfig()
		{
			return ConfigService.GetBuyPrisonerConfig();
		}

		private static void InitializeLogFile()
		{
			try
			{
				lock (LOG_LOCK)
				{
					Directory.CreateDirectory(CONFIG_DIR);
					if (File.Exists(LOG_FILE))
					{
						return;
					}
					using FileStream stream = new FileStream(LOG_FILE, FileMode.Create, FileAccess.Write, FileShare.Read);
					using StreamWriter streamWriter = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
					streamWriter.WriteLine("server_time,steam_id,player_name,blood_type,cost,success,reason");
				}
			}
			catch (Exception e)
			{
				Core.LogException(e, "InitializeLogFile");
			}
		}

		private static void LogPurchase(ulong steamId, string playerName, string bloodType, int cost, bool success, string reason)
		{
			try
			{
				lock (LOG_LOCK)
				{
					using FileStream stream = new FileStream(LOG_FILE, FileMode.Append, FileAccess.Write, FileShare.Read);
					using StreamWriter streamWriter = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
					streamWriter.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss},{steamId},{Csv(playerName)},{Csv(bloodType)},{cost},{(success ? "true" : "false")},{Csv(reason)}");
				}
			}
			catch (Exception e)
			{
				Core.LogException(e, "LogPurchase");
			}
		}

		private static string Csv(string s)
		{
			if (s == null)
			{
				return "\"\"";
			}
			return "\"" + s.Replace("\"", "\"\"") + "\"";
		}
	}
	internal static class ConfigService
	{
		private static readonly string CONFIG_DIR = Path.Combine(Paths.ConfigPath, "PrisonerBlood");

		private static readonly string BUY_CONFIG_FILE = Path.Combine(CONFIG_DIR, "buyconfig.json");

		private static readonly string SELL_CONFIG_FILE = Path.Combine(CONFIG_DIR, "sellconfig.json");

		public const string BUY_CONFIG_FILE_NAME = "buyconfig.json";

		public const string SELL_CONFIG_FILE_NAME = "sellconfig.json";

		private static readonly object IO_LOCK = new object();

		private static readonly BuyConfigRoot _defaultBuyRoot = CreateDefaultBuyRoot();

		private static readonly SellConfigRoot _defaultSellRoot = CreateDefaultSellRoot();

		private static DateTime _buylastWrite = DateTime.MinValue;

		private static BuyConfigRoot _buyroot = new BuyConfigRoot();

		private static DateTime _sellLastWrite = DateTime.MinValue;

		private static SellConfigRoot _sellRoot = new SellConfigRoot();

		private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
		{
			AllowTrailingCommas = true,
			PropertyNameCaseInsensitive = true,
			ReadCommentHandling = JsonCommentHandling.Skip,
			WriteIndented = true
		};

		public static void Initialize()
		{
			LoadBuy(force: true);
			LoadSell(force: true);
		}

		public static void Reload()
		{
			LoadBuy(force: true);
			LoadSell(force: true);
		}

		public static BuySection GetBuyPrisonerConfig()
		{
			LoadBuy(force: false);
			lock (IO_LOCK)
			{
				return NormalizeBuy(_buyroot.Prisoner, _defaultBuyRoot.Prisoner);
			}
		}

		public static BuySection GetBuyBloodPotionConfig()
		{
			LoadBuy(force: false);
			lock (IO_LOCK)
			{
				return NormalizeBuy(_buyroot.BloodPotion, _defaultBuyRoot.BloodPotion);
			}
		}

		public static SellSection GetSellPrisonerConfig()
		{
			LoadSell(force: false);
			lock (IO_LOCK)
			{
				return NormalizeSell(_sellRoot.Prisoner, _defaultSellRoot.Prisoner);
			}
		}

		private static void LoadBuy(bool force)
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			lock (IO_LOCK)
			{
				try
				{
					Directory.CreateDirectory(CONFIG_DIR);
					if (!File.Exists(BUY_CONFIG_FILE))
					{
						_buyroot = _defaultBuyRoot;
						File.WriteAllText(BUY_CONFIG_FILE, JsonSerializer.Serialize(_buyroot, JsonOptions));
						_buylastWrite = File.GetLastWriteTime(BUY_CONFIG_FILE);
						return;
					}
					DateTime lastWriteTime = File.GetLastWriteTime(BUY_CONFIG_FILE);
					if (force || !(lastWriteTime <= _buylastWrite))
					{
						string json = File.ReadAllText(BUY_CONFIG_FILE);
						_buyroot = JsonSerializer.Deserialize<BuyConfigRoot>(json, JsonOptions) ?? _defaultBuyRoot;
						_buylastWrite = lastWriteTime;
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Core.Log;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[ConfigService] Failed to load ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("buyconfig.json");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
					_buyroot = _defaultBuyRoot;
				}
			}
		}

		private static void LoadSell(bool force)
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			lock (IO_LOCK)
			{
				try
				{
					Directory.CreateDirectory(CONFIG_DIR);
					if (!File.Exists(SELL_CONFIG_FILE))
					{
						_sellRoot = _defaultSellRoot;
						File.WriteAllText(SELL_CONFIG_FILE, JsonSerializer.Serialize(_sellRoot, JsonOptions));
						_sellLastWrite = File.GetLastWriteTime(SELL_CONFIG_FILE);
						return;
					}
					DateTime lastWriteTime = File.GetLastWriteTime(SELL_CONFIG_FILE);
					if (force || !(lastWriteTime <= _sellLastWrite))
					{
						string json = File.ReadAllText(SELL_CONFIG_FILE);
						_sellRoot = JsonSerializer.Deserialize<SellConfigRoot>(json, JsonOptions) ?? _defaultSellRoot;
						_sellLastWrite = lastWriteTime;
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Core.Log;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[ConfigService] Failed to load ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("sellconfig.json");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
					_sellRoot = _defaultSellRoot;
				}
			}
		}

		private static BuySection NormalizeBuy(BuySection config, BuySection defaults)
		{
			if (config == null)
			{
				config = new BuySection();
			}
			bool flag = config.BloodCosts != null;
			Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
			if (flag)
			{
				foreach (KeyValuePair<string, int> bloodCost in config.BloodCosts)
				{
					if (bloodCost.Value > 0)
					{
						dictionary[bloodCost.Key.Trim()] = bloodCost.Value;
					}
				}
			}
			return new BuySection
			{
				Enabled = config.Enabled,
				CurrencyPrefab = ((config.CurrencyPrefab != 0) ? config.CurrencyPrefab : defaults.CurrencyPrefab),
				CurrencyName = (string.IsNullOrWhiteSpace(config.CurrencyName) ? defaults.CurrencyName : config.CurrencyName.Trim()),
				DefaultCost = ((config.DefaultCost > 0) ? config.DefaultCost : defaults.DefaultCost),
				BloodCosts = (flag ? dictionary : new Dictionary<string, int>(defaults.BloodCosts, StringComparer.OrdinalIgnoreCase))
			};
		}

		private static SellSection NormalizeSell(SellSection config, SellSection defaults)
		{
			if (config == null)
			{
				config = new SellSection();
			}
			bool flag = config.BloodPrices != null;
			Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
			if (flag)
			{
				foreach (KeyValuePair<string, int> bloodPrice in config.BloodPrices)
				{
					if (bloodPrice.Value > 0)
					{
						dictionary[bloodPrice.Key.Trim()] = bloodPrice.Value;
					}
				}
			}
			return new SellSection
			{
				Enabled = config.Enabled,
				MinSellableQuality = ((config.MinSellableQuality > 0f) ? config.MinSellableQuality : defaults.MinSellableQuality),
				CurrencyPrefab = ((config.CurrencyPrefab != 0) ? config.CurrencyPrefab : defaults.CurrencyPrefab),
				CurrencyName = (string.IsNullOrWhiteSpace(config.CurrencyName) ? defaults.CurrencyName : config.CurrencyName.Trim()),
				DefaultPrice = ((config.DefaultPrice > 0) ? config.DefaultPrice : defaults.DefaultPrice),
				BloodPrices = (flag ? dictionary : new Dictionary<string, int>(defaults.BloodPrices, StringComparer.OrdinalIgnoreCase))
			};
		}

		private static BuyConfigRoot CreateDefaultBuyRoot()
		{
			return new BuyConfigRoot
			{
				Prisoner = new BuySection
				{
					Enabled = true,
					CurrencyPrefab = 576389135,
					CurrencyName = "Greater Stygian Shards",
					DefaultCost = 5000,
					BloodCosts = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
					{
						{ "Worker", 4000 },
						{ "Creature", 4200 },
						{ "Mutant", 4500 },
						{ "Corrupted", 4800 },
						{ "Draculin", 5000 },
						{ "Warrior", 5200 },
						{ "Rogue", 5500 },
						{ "Brute", 5700 },
						{ "Scholar", 6000 }
					}
				},
				BloodPotion = new BuySection
				{
					Enabled = true,
					CurrencyPrefab = 576389135,
					CurrencyName = "Greater Stygian Shards",
					DefaultCost = 500,
					BloodCosts = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
					{
						{ "Worker", 300 },
						{ "Creature", 350 },
						{ "Mutant", 400 },
						{ "Corrupted", 450 },
						{ "Draculin", 500 },
						{ "Warrior", 550 },
						{ "Rogue", 600 },
						{ "Brute", 650 },
						{ "Scholar", 700 }
					}
				}
			};
		}

		private static SellConfigRoot CreateDefaultSellRoot()
		{
			return new SellConfigRoot
			{
				Prisoner = new SellSection
				{
					Enabled = true,
					MinSellableQuality = 80f,
					CurrencyPrefab = 576389135,
					CurrencyName = "Greater Stygian Shards",
					DefaultPrice = 2500,
					BloodPrices = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
					{
						{ "Worker", 2000 },
						{ "Creature", 2100 },
						{ "Mutant", 2250 },
						{ "Corrupted", 2400 },
						{ "Draculin", 2500 },
						{ "Warrior", 2600 },
						{ "Rogue", 2750 },
						{ "Brute", 2850 },
						{ "Scholar", 3000 }
					}
				}
			};
		}
	}
	internal static class SellPrisonerService
	{
		private static readonly string CONFIG_DIR = Path.Combine(Paths.ConfigPath, "PrisonerBlood");

		private static readonly string LOG_FILE = Path.Combine(CONFIG_DIR, "sellprisoner_log.csv");

		private static readonly object LOG_LOCK = new object();

		private const float PrisonCellSearchRadius = 2f;

		public static string CurrencyName => GetCurrency().Name;

		public static void Initialize()
		{
			ConfigService.Initialize();
			InitializeLogFile();
		}

		public static bool IsEnabled()
		{
			return GetConfig().Enabled;
		}

		public static (PrefabGUID Prefab, string Name) GetCurrency()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			SellSection config = GetConfig();
			return (new PrefabGUID(config.CurrencyPrefab), config.CurrencyName);
		}

		public static (int defaultPrice, Dictionary<string, int> prices) GetPriceSnapshot()
		{
			SellSection config = GetConfig();
			return (config.DefaultPrice, new Dictionary<string, int>(config.BloodPrices, StringComparer.OrdinalIgnoreCase));
		}

		public static void ReplyHelp(Action<string> reply, string warningLine = null)
		{
			(int, Dictionary<string, int>) priceSnapshot = GetPriceSnapshot();
			int defaultPrice = priceSnapshot.Item1;
			Dictionary<string, int> prices = priceSnapshot.Item2;
			SellSection config = GetConfig();
			if (!string.IsNullOrWhiteSpace(warningLine))
			{
				reply(warningLine);
			}
			if (!prices.TryGetValue("Rogue", out var value))
			{
				value = defaultPrice;
			}
			int value2 = (int)((float)value * 0.86f);
			reply("<color=yellow>Command:</color> <color=green>.sell prisoner</color> or <color=green>.sell ps</color>");
			reply($"<color=yellow>Quality:</color> {config.MinSellableQuality:0}-100%.");
			reply("<color=yellow>Price:</color> Scales with the prisoner's blood quality.");
			reply($"<color=yellow>Example:</color> rogue <color=white>86%</color> blood quality = <color=white>86%</color> of {value} = <color=green>{value2}</color>");
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(89, 1, stringBuilder2);
			handler.AppendLiteral("<color=yellow>Blood types</color> : <color=yellow>Price</color> <color=#87CEFA>(");
			handler.AppendFormatted(CurrencyName);
			handler.AppendLiteral(")</color>");
			stringBuilder2.AppendLine(ref handler);
			var source = (from x in Helper.AllowedBloodTypes.Select(delegate(BloodType bt)
				{
					string text = bt.ToString();
					int value3;
					bool flag = prices.TryGetValue(text, out value3);
					int price = (flag ? value3 : defaultPrice);
					return new
					{
						Name = text,
						Price = price,
						IsDefault = !flag
					};
				})
				orderby x.Price
				select x).ThenBy(x => x.Name, StringComparer.OrdinalIgnoreCase).ToList();
			List<string> source2 = source.Select(x => $"{x.Name} : {x.Price}").ToList();
			foreach (string[] item in source2.Chunk(3))
			{
				stringBuilder.AppendLine(string.Join(" <color=white>|</color> ", item));
			}
			reply(stringBuilder.ToString().TrimEnd());
			reply($"<color=yellow>Stand within {2f:0.0}m of the prisoner you want to sell.</color>");
		}

		public static void SellPrisoner(Entity senderCharacterEntity, ulong steamId, string playerName, Action<string> reply)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: 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_017c: 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_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled())
			{
				reply("<color=yellow>Sell Prisoner:</color> <color=red>Disabled.</color>");
				return;
			}
			EntityManager entityManager = Core.EntityManager;
			if (senderCharacterEntity == Entity.Null || !((EntityManager)(ref entityManager)).Exists(senderCharacterEntity))
			{
				reply("<color=red>Character not ready.</color>");
				return;
			}
			if (Helper.IsInCombat(senderCharacterEntity))
			{
				reply("<color=red>You cannot sell a prisoner while in combat.</color>");
				return;
			}
			if (!TryFindClosestOccupiedOwnedPrisonCell(senderCharacterEntity, 2f, out var _, out var prisonerEntity, out var cellLogReason, out var cellReplyMessage))
			{
				LogSale(steamId, playerName, "unknown", 0f, 0, success: false, cellLogReason);
				reply(cellReplyMessage);
				return;
			}
			SellSection config = GetConfig();
			if (!TryGetValidBloodData(prisonerEntity, config.MinSellableQuality, out var bloodTypeName, out var bloodQuality, out var bloodLogReason, out var bloodReplyMessage))
			{
				LogSale(steamId, playerName, "unknown", bloodQuality, 0, success: false, bloodLogReason);
				reply(bloodReplyMessage);
				return;
			}
			int emptyInventorySlotsCount = Helper.GetEmptyInventorySlotsCount(senderCharacterEntity);
			if (emptyInventorySlotsCount < 2)
			{
				LogSale(steamId, playerName, bloodTypeName, bloodQuality, 0, success: false, "not_enough_inventory_slots");
				reply("<color=yellow>Failed!</color> Not enough inventory slots.");
				return;
			}
			(PrefabGUID Prefab, string Name) currency = GetCurrency();
			PrefabGUID item = currency.Prefab;
			string item2 = currency.Name;
			int sellPrice = GetSellPrice(bloodTypeName, bloodQuality);
			try
			{
				if (((EntityManager)(ref entityManager)).HasComponent<DropTable>(prisonerEntity))
				{
					((EntityManager)(ref entityManager)).RemoveComponent<DropTable>(prisonerEntity);
				}
				DestroyUtility.Destroy(entityManager, prisonerEntity, (DestroyDebugReason)13, (string)null, 0);
				Helper.AddItemToInventory(senderCharacterEntity, item, sellPrice);
				LogSale(steamId, playerName, bloodTypeName, bloodQuality, sellPrice, success: true, "successful");
				reply($"<color=green>Success!</color> You received <color=#87CEFA>{sellPrice} {item2}</color> for selling a <color=green>{bloodQuality:0}%</color> <color=yellow>{bloodTypeName}</color> prisoner.");
			}
			catch (Exception ex)
			{
				LogSale(steamId, playerName, bloodTypeName, bloodQuality, 0, success: false, "error_during_deletion: " + ex.Message);
				reply("<color=red>Error occurred while trying to sell the prisoner.</color>");
				Core.LogException(ex, "SellPrisoner");
			}
		}

		private static bool TryFindClosestOccupiedOwnedPrisonCell(Entity senderCharacterEntity, float radius, out Entity prisonCellEntity, out Entity prisonerEntity, out string cellLogReason, out string cellReplyMessage)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			//IL_005f: 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)
			//IL_0067: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: 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_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			prisonCellEntity = Entity.Null;
			prisonerEntity = Entity.Null;
			cellLogReason = "no_occupied_owned_prison_cell_found";
			cellReplyMessage = $"<color=yellow>Failed!</color> No occupied prison cell you own found within {2f:0.0}m.";
			EntityManager entityManager = Core.EntityManager;
			if (!((EntityManager)(ref entityManager)).HasComponent<LocalToWorld>(senderCharacterEntity))
			{
				cellLogReason = "cannot_find_player_position";
				cellReplyMessage = "<color=yellow>Failed!</color> Cannot find player position.";
				return false;
			}
			if (!((EntityManager)(ref entityManager)).HasComponent<Team>(senderCharacterEntity))
			{
				cellLogReason = "cannot_read_player_team";
				cellReplyMessage = "<color=yellow>Failed!</color> Cannot read player team.";
				return false;
			}
			LocalToWorld componentData = ((EntityManager)(ref entityManager)).GetComponentData<LocalToWorld>(senderCharacterEntity);
			float3 position = ((LocalToWorld)(ref componentData)).Position;
			int value = ((EntityManager)(ref entityManager)).GetComponentData<Team>(senderCharacterEntity).Value;
			float num = radius * radius;
			NativeArray<Entity> entitiesByComponentTypes = Helper.GetEntitiesByComponentTypes<PrisonCell, LocalToWorld>();
			try
			{
				Enumerator<Entity> enumerator = entitiesByComponentTypes.GetEnumerator();
				while (enumerator.MoveNext())
				{
					Entity current = enumerator.Current;
					if (!((EntityManager)(ref entityManager)).Exists(current) || !((EntityManager)(ref entityManager)).HasComponent<Team>(current) || ((EntityManager)(ref entityManager)).GetComponentData<Team>(current).Value != value)
					{
						continue;
					}
					PrisonCell componentData2 = ((EntityManager)(ref entityManager)).GetComponentData<PrisonCell>(current);
					Entity entity = componentData2.ImprisonedEntity._Entity;
					if (!(entity == Entity.Null) && ((EntityManager)(ref entityManager)).Exists(entity))
					{
						componentData = ((EntityManager)(ref entityManager)).GetComponentData<LocalToWorld>(current);
						float3 position2 = ((LocalToWorld)(ref componentData)).Position;
						float num2 = math.distancesq(position, position2);
						if (!(num2 > num))
						{
							num = num2;
							prisonCellEntity = current;
							prisonerEntity = entity;
						}
					}
				}
			}
			finally
			{
				entitiesByComponentTypes.Dispose();
			}
			bool flag = prisonCellEntity != Entity.Null;
			if (flag)
			{
				cellLogReason = string.Empty;
				cellReplyMessage = string.Empty;
			}
			return flag;
		}

		private static bool TryGetValidBloodData(Entity prisonerEntity, float minQuality, out string bloodTypeName, out float bloodQuality, out string bloodLogReason, out string bloodReplyMessage)
		{
			//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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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)
			bloodTypeName = "unknown";
			bloodQuality = 0f;
			bloodLogReason = string.Empty;
			bloodReplyMessage = string.Empty;
			EntityManager entityManager = Core.EntityManager;
			if (!((EntityManager)(ref entityManager)).HasComponent<BloodConsumeSource>(prisonerEntity))
			{
				bloodLogReason = "cannot_read_prisoner_data";
				bloodReplyMessage = "<color=red>Failed!</color> Cannot read prisoner data.";
				return false;
			}
			BloodConsumeSource componentData = ((EntityManager)(ref entityManager)).GetComponentData<BloodConsumeSource>(prisonerEntity);
			bloodQuality = math.floor(componentData.BloodQuality);
			if (bloodQuality < minQuality)
			{
				bloodLogReason = $"blood_quality_too_low_{bloodQuality:0}%";
				bloodReplyMessage = $"<color=yellow>Failed!</color> Cannot sell <color=red>{bloodQuality:0}%</color> blood quality. Minimum quality is <color=green>{minQuality:0}%</color>.";
				return false;
			}
			int guidHash = ((PrefabGUID)(ref componentData.UnitBloodType._Value)).GuidHash;
			foreach (BloodType value in Enum.GetValues(typeof(BloodType)))
			{
				PrefabGUID val = new PrefabGUID((int)value);
				if (((PrefabGUID)(ref val)).GuidHash == guidHash)
				{
					bloodTypeName = value.ToString();
					break;
				}
			}
			return true;
		}

		private static int GetSellPrice(string bloodTypeName, float bloodQuality)
		{
			SellSection config = GetConfig();
			int num = config.DefaultPrice;
			foreach (KeyValuePair<string, int> bloodPrice in config.BloodPrices)
			{
				if (string.Equals(bloodPrice.Key, bloodTypeName, StringComparison.OrdinalIgnoreCase))
				{
					num = ((bloodPrice.Value > 0) ? bloodPrice.Value : config.DefaultPrice);
					break;
				}
			}
			return math.max(1, (int)((float)num * (bloodQuality / 100f)));
		}

		private static SellSection GetConfig()
		{
			return ConfigService.GetSellPrisonerConfig();
		}

		private static void InitializeLogFile()
		{
			try
			{
				lock (LOG_LOCK)
				{
					Directory.CreateDirectory(CONFIG_DIR);
					if (File.Exists(LOG_FILE))
					{
						return;
					}
					using FileStream stream = new FileStream(LOG_FILE, FileMode.Create, FileAccess.Write, FileShare.Read);
					using StreamWriter streamWriter = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
					streamWriter.WriteLine("server_time,steam_id,player_name,blood_type,blood_quality,sell_price,success,reason");
				}
			}
			catch (Exception e)
			{
				Core.LogException(e, "InitializeLogFile");
			}
		}

		private static void LogSale(ulong steamId, string playerName, string bloodType, float bloodQuality, int sellPrice, bool success, string reason)
		{
			try
			{
				lock (LOG_LOCK)
				{
					using FileStream stream = new FileStream(LOG_FILE, FileMode.Append, FileAccess.Write, FileShare.Read);
					using StreamWriter streamWriter = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
					streamWriter.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss},{steamId},{Csv(playerName)},{Csv(bloodType)},{bloodQuality:0},{sellPrice},{(success ? "true" : "false")},{Csv(reason)}");
				}
			}
			catch (Exception e)
			{
				Core.LogException(e, "LogSale");
			}
		}

		private static string Csv(string s)
		{
			if (s == null)
			{
				return "\"\"";
			}
			return "\"" + s.Replace("\"", "\"\"") + "\"";
		}
	}
	internal class UnitSpawnerService
	{
		[HarmonyPatch(typeof(UnitSpawnerReactSystem), "OnUpdate")]
		public static class UnitSpawnerReactSystemPatch
		{
			public static bool Enabled { get; set; }

			public static void Prefix(UnitSpawnerReactSystem __instance)
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: 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_0026: 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)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to inv