Decompiled source of Vikings ActivityLog v1.0.0

plugins/Vikings_ActivityLog.dll

Decompiled 18 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using Splatform;
using TMPro;
using UnityEngine;

[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: Guid("3B8F2C61-7A4D-4E58-9C1F-2D6A8B0E5F47")]
[assembly: ComVisible(false)]
[assembly: AssemblyCopyright("Copyright © 2026 Radamanto")]
[assembly: AssemblyProduct("Vikings_ActivityLog")]
[assembly: AssemblyCompany("Radamanto")]
[assembly: AssemblyDescription("Records player activity into a SQLite database per world.")]
[assembly: AssemblyTitle("Vikings_ActivityLog")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: <87611a2b-a57f-444c-8f98-ca57a449cbb6>RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<cc1bcdce-8989-4e7a-b6c3-20e573012ad3>Embedded]
	internal sealed class <cc1bcdce-8989-4e7a-b6c3-20e573012ad3>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[<cc1bcdce-8989-4e7a-b6c3-20e573012ad3>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <e8d1da4e-51b0-4742-9b18-4ef846081fed>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <e8d1da4e-51b0-4742-9b18-4ef846081fed>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <e8d1da4e-51b0-4742-9b18-4ef846081fed>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[<cc1bcdce-8989-4e7a-b6c3-20e573012ad3>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	internal sealed class <40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[<cc1bcdce-8989-4e7a-b6c3-20e573012ad3>Embedded]
	[CompilerGenerated]
	internal sealed class <87611a2b-a57f-444c-8f98-ca57a449cbb6>RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public <87611a2b-a57f-444c-8f98-ca57a449cbb6>RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Vikings_ActivityLog
{
	internal static class ActivityClock
	{
		internal static long ToUtcMs(double serverWorldTime, double eventWorldTime, DateTime utcNow)
		{
			double num = Math.Max(0.0, serverWorldTime - eventWorldTime);
			long num2 = new DateTimeOffset(utcNow).ToUnixTimeMilliseconds();
			return num2 - (long)Math.Round(num * 1000.0);
		}

		internal static long RetentionCutoff(DateTime utcNow, int days)
		{
			return new DateTimeOffset(utcNow).ToUnixTimeMilliseconds() - (long)days * 86400000L;
		}
	}
	internal enum ActivityEventType : byte
	{
		Spawned = 1,
		Inventory,
		Equip,
		Unequip,
		Consume,
		Craft,
		RepairItem,
		Dodge,
		Teleport,
		Damage,
		Damaged,
		Dead,
		Pickup,
		Drop,
		Place,
		Remove,
		RepairBuilding,
		Interact,
		Use,
		Text,
		StackAll,
		MoveAll,
		Move,
		Grave,
		Ping,
		TrinketActivated,
		Connected,
		Disconnected,
		Command,
		CommandRemote
	}
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	internal static class ActivityEventNames
	{
		internal static readonly ActivityEventType[] All = new ActivityEventType[30]
		{
			ActivityEventType.Spawned,
			ActivityEventType.Inventory,
			ActivityEventType.Equip,
			ActivityEventType.Unequip,
			ActivityEventType.Consume,
			ActivityEventType.Craft,
			ActivityEventType.RepairItem,
			ActivityEventType.Dodge,
			ActivityEventType.Teleport,
			ActivityEventType.Damage,
			ActivityEventType.Damaged,
			ActivityEventType.Dead,
			ActivityEventType.Pickup,
			ActivityEventType.Drop,
			ActivityEventType.Place,
			ActivityEventType.Remove,
			ActivityEventType.RepairBuilding,
			ActivityEventType.Interact,
			ActivityEventType.Use,
			ActivityEventType.Text,
			ActivityEventType.StackAll,
			ActivityEventType.MoveAll,
			ActivityEventType.Move,
			ActivityEventType.Grave,
			ActivityEventType.Ping,
			ActivityEventType.TrinketActivated,
			ActivityEventType.Connected,
			ActivityEventType.Disconnected,
			ActivityEventType.Command,
			ActivityEventType.CommandRemote
		};

		internal static string Name(ActivityEventType type)
		{
			return type switch
			{
				ActivityEventType.RepairItem => "Repair item", 
				ActivityEventType.RepairBuilding => "Repair building", 
				ActivityEventType.CommandRemote => "Command remote", 
				_ => type.ToString(), 
			};
		}
	}
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	internal static class ActivityPaths
	{
		internal const string FolderName = "Vikings_ActivityLog";

		internal static string DatabaseFileName(string worldName)
		{
			string text = (worldName ?? "").Trim();
			if (text.Length == 0)
			{
				return "world.db";
			}
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			StringBuilder stringBuilder = new StringBuilder(text.Length);
			string text2 = text;
			foreach (char c in text2)
			{
				stringBuilder.Append((c == '/' || c == '\\' || c == ':' || c == '*' || c == '?' || c == '"' || c == '<' || c == '>' || c == '|' || Array.IndexOf(invalidFileNameChars, c) >= 0) ? '_' : c);
			}
			return stringBuilder?.ToString() + ".db";
		}
	}
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	internal sealed class ActivityItem
	{
		public string Source = "";

		public string Prefab = "";

		public int Count;

		public int Quality;

		public long CrafterId;

		public string CrafterName = "";

		public string CustomData = "";
	}
	internal sealed class ActivityDamage
	{
		public float Damage;

		public float Blunt;

		public float Slash;

		public float Pierce;

		public float Fire;

		public float Frost;

		public float Lightning;

		public float Poison;

		public float Spirit;

		public float Chop;

		public float Pickaxe;

		public float Total;

		public float HealthAfter = float.NaN;
	}
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	internal sealed class ActivityRecord
	{
		public ActivityEventType Type;

		public double WorldTime;

		public long TimeUtcMs;

		public string PlatformId = "";

		public string PlayerName = "";

		public long PlayerId;

		public float X;

		public float Y;

		public float Z;

		public string Target = "";

		public int Amount;

		public string Details = "";

		public List<ActivityItem> Items = new List<ActivityItem>();

		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(2)]
		public ActivityDamage Damage;
	}
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	internal sealed class ActivityStore : IDisposable
	{
		private const string InsertEventSql = "INSERT INTO events (time_utc, platform_id, player_name, player_id, event, x, y, z, target, amount, details) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11);";

		private const string InsertItemSql = "INSERT INTO event_items (event_id, source, prefab, count, quality, crafter_id, crafter_name, custom_data) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8);";

		private const string InsertDamageSql = "INSERT INTO event_damage (event_id, damage, blunt, slash, pierce, fire, frost, lightning, poison, spirit, chop, pickaxe, total, health_after) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14);";

		private const string UpsertPlayerSql = "INSERT INTO players (platform_id, player_id, last_name, first_seen_utc, last_seen_utc) VALUES (?1, ?2, ?3, ?4, ?4) ON CONFLICT(platform_id) DO UPDATE SET player_id = CASE WHEN excluded.player_id <> 0 THEN excluded.player_id ELSE players.player_id END, last_name = CASE WHEN excluded.last_name <> '' THEN excluded.last_name ELSE players.last_name END, last_seen_utc = MAX(players.last_seen_utc, excluded.last_seen_utc);";

		private readonly SqliteStatement _insertEvent;

		private readonly SqliteStatement _insertItem;

		private readonly SqliteStatement _insertDamage;

		private readonly SqliteStatement _upsertPlayer;

		internal SqliteDatabase Database { get; }

		internal ActivityStore(string path)
		{
			string directoryName = Path.GetDirectoryName(path);
			if (!string.IsNullOrEmpty(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			Database = new SqliteDatabase(path);
			ActivitySchema.Apply(Database);
			_insertEvent = Database.Prepare("INSERT INTO events (time_utc, platform_id, player_name, player_id, event, x, y, z, target, amount, details) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11);");
			_insertItem = Database.Prepare("INSERT INTO event_items (event_id, source, prefab, count, quality, crafter_id, crafter_name, custom_data) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8);");
			_insertDamage = Database.Prepare("INSERT INTO event_damage (event_id, damage, blunt, slash, pierce, fire, frost, lightning, poison, spirit, chop, pickaxe, total, health_after) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14);");
			_upsertPlayer = Database.Prepare("INSERT INTO players (platform_id, player_id, last_name, first_seen_utc, last_seen_utc) VALUES (?1, ?2, ?3, ?4, ?4) ON CONFLICT(platform_id) DO UPDATE SET player_id = CASE WHEN excluded.player_id <> 0 THEN excluded.player_id ELSE players.player_id END, last_name = CASE WHEN excluded.last_name <> '' THEN excluded.last_name ELSE players.last_name END, last_seen_utc = MAX(players.last_seen_utc, excluded.last_seen_utc);");
		}

		internal void WriteBatch(IReadOnlyList<ActivityRecord> records)
		{
			if (records.Count == 0)
			{
				return;
			}
			Database.Execute("BEGIN IMMEDIATE;");
			try
			{
				foreach (ActivityRecord record in records)
				{
					long eventId = InsertEvent(record);
					foreach (ActivityItem item in record.Items)
					{
						InsertItem(eventId, item);
					}
					if (record.Damage != null)
					{
						InsertDamage(eventId, record.Damage);
					}
					UpsertPlayer(record);
				}
				Database.Execute("COMMIT;");
			}
			catch
			{
				ResetStatements();
				Database.Execute("ROLLBACK;");
				throw;
			}
		}

		internal int DeleteOlderThan(long cutoffUtcMs)
		{
			Database.Execute("BEGIN IMMEDIATE;");
			try
			{
				RunDelete("DELETE FROM event_items WHERE event_id IN (SELECT id FROM events WHERE time_utc < ?1);", cutoffUtcMs);
				RunDelete("DELETE FROM event_damage WHERE event_id IN (SELECT id FROM events WHERE time_utc < ?1);", cutoffUtcMs);
				int result = RunDelete("DELETE FROM events WHERE time_utc < ?1;", cutoffUtcMs);
				Database.Execute("COMMIT;");
				return result;
			}
			catch
			{
				Database.Execute("ROLLBACK;");
				throw;
			}
		}

		public void Dispose()
		{
			_insertEvent.Dispose();
			_insertItem.Dispose();
			_insertDamage.Dispose();
			_upsertPlayer.Dispose();
			Database.Dispose();
		}

		private long InsertEvent(ActivityRecord record)
		{
			_insertEvent.Bind(1, record.TimeUtcMs);
			_insertEvent.Bind(2, record.PlatformId);
			_insertEvent.Bind(3, record.PlayerName);
			_insertEvent.Bind(4, record.PlayerId);
			_insertEvent.Bind(5, ActivityEventNames.Name(record.Type));
			_insertEvent.Bind(6, record.X);
			_insertEvent.Bind(7, record.Y);
			_insertEvent.Bind(8, record.Z);
			_insertEvent.Bind(9, record.Target);
			_insertEvent.Bind(10, record.Amount);
			_insertEvent.Bind(11, record.Details);
			_insertEvent.Step();
			_insertEvent.Reset();
			return Database.LastInsertRowId;
		}

		private void InsertItem(long eventId, ActivityItem item)
		{
			_insertItem.Bind(1, eventId);
			_insertItem.Bind(2, item.Source);
			_insertItem.Bind(3, item.Prefab);
			_insertItem.Bind(4, item.Count);
			_insertItem.Bind(5, item.Quality);
			_insertItem.Bind(6, item.CrafterId);
			_insertItem.Bind(7, item.CrafterName);
			_insertItem.Bind(8, item.CustomData);
			_insertItem.Step();
			_insertItem.Reset();
		}

		private void InsertDamage(long eventId, ActivityDamage damage)
		{
			_insertDamage.Bind(1, eventId);
			_insertDamage.Bind(2, damage.Damage);
			_insertDamage.Bind(3, damage.Blunt);
			_insertDamage.Bind(4, damage.Slash);
			_insertDamage.Bind(5, damage.Pierce);
			_insertDamage.Bind(6, damage.Fire);
			_insertDamage.Bind(7, damage.Frost);
			_insertDamage.Bind(8, damage.Lightning);
			_insertDamage.Bind(9, damage.Poison);
			_insertDamage.Bind(10, damage.Spirit);
			_insertDamage.Bind(11, damage.Chop);
			_insertDamage.Bind(12, damage.Pickaxe);
			_insertDamage.Bind(13, damage.Total);
			if (float.IsNaN(damage.HealthAfter))
			{
				_insertDamage.Bind(14, null);
			}
			else
			{
				_insertDamage.Bind(14, damage.HealthAfter);
			}
			_insertDamage.Step();
			_insertDamage.Reset();
		}

		private void UpsertPlayer(ActivityRecord record)
		{
			_upsertPlayer.Bind(1, record.PlatformId);
			_upsertPlayer.Bind(2, record.PlayerId);
			_upsertPlayer.Bind(3, record.PlayerName);
			_upsertPlayer.Bind(4, record.TimeUtcMs);
			_upsertPlayer.Step();
			_upsertPlayer.Reset();
		}

		private int RunDelete(string sql, long cutoffUtcMs)
		{
			using SqliteStatement sqliteStatement = Database.Prepare(sql);
			sqliteStatement.Bind(1, cutoffUtcMs);
			sqliteStatement.Step();
			return Database.Changes;
		}

		private void ResetStatements()
		{
			_insertEvent.Reset();
			_insertItem.Reset();
			_insertDamage.Reset();
			_upsertPlayer.Reset();
		}
	}
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	internal sealed class ActivityWriter : IDisposable
	{
		private const int FlushIntervalMs = 500;

		private const int StopTimeoutMs = 15000;

		private readonly ConcurrentQueue<ActivityRecord> _queue = new ConcurrentQueue<ActivityRecord>();

		private readonly AutoResetEvent _signal = new AutoResetEvent(initialState: false);

		private readonly Func<ActivityStore> _storeFactory;

		private readonly Action<string> _logInfo;

		private readonly Action<string> _logError;

		private readonly Thread _thread;

		private long _retentionCutoff = -1L;

		private volatile bool _stopping;

		private volatile bool _failed;

		internal bool Failed => _failed;

		internal ActivityWriter(Func<ActivityStore> storeFactory, Action<string> logInfo, Action<string> logError)
		{
			_storeFactory = storeFactory;
			_logInfo = logInfo;
			_logError = logError;
			_thread = new Thread(Run)
			{
				IsBackground = true,
				Name = "Vikings_ActivityLog writer"
			};
			_thread.Start();
		}

		internal void Enqueue(ActivityRecord record)
		{
			if (!_failed && !_stopping)
			{
				_queue.Enqueue(record);
			}
		}

		internal void RequestRetention(long cutoffUtcMs)
		{
			Interlocked.Exchange(ref _retentionCutoff, cutoffUtcMs);
			_signal.Set();
		}

		public void Dispose()
		{
			_stopping = true;
			_signal.Set();
			if (!_thread.Join(15000))
			{
				_logError("Activity writer did not stop in time; queued records may be lost.");
			}
		}

		private void Run()
		{
			ActivityStore activityStore;
			try
			{
				activityStore = _storeFactory();
			}
			catch (Exception ex)
			{
				_failed = true;
				_logError("Activity database could not be opened; activity will not be recorded: " + ex.Message);
				ActivityRecord result;
				while (_queue.TryDequeue(out result))
				{
				}
				return;
			}
			List<ActivityRecord> batch = new List<ActivityRecord>(512);
			try
			{
				bool stopping;
				do
				{
					_signal.WaitOne(500);
					stopping = _stopping;
					Flush(activityStore, batch);
					ApplyRetention(activityStore);
				}
				while (!stopping);
			}
			finally
			{
				activityStore.Dispose();
			}
		}

		private void Flush(ActivityStore store, List<ActivityRecord> batch)
		{
			batch.Clear();
			ActivityRecord result;
			while (_queue.TryDequeue(out result))
			{
				batch.Add(result);
			}
			if (batch.Count == 0)
			{
				return;
			}
			try
			{
				store.WriteBatch(batch);
			}
			catch (Exception ex)
			{
				_logError("Activity batch of " + batch.Count + " records could not be written: " + ex.Message);
			}
		}

		private void ApplyRetention(ActivityStore store)
		{
			long num = Interlocked.Exchange(ref _retentionCutoff, -1L);
			if (num < 0)
			{
				return;
			}
			try
			{
				int num2 = store.DeleteOlderThan(num);
				_logInfo("Activity retention removed " + num2 + " old events.");
			}
			catch (Exception ex)
			{
				_logError("Activity retention failed: " + ex.Message);
			}
		}
	}
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	internal static class NativeLoader
	{
		private const int RtldNow = 2;

		private const int RtldGlobal = 256;

		internal static bool IsWindows => Environment.OSVersion.Platform == PlatformID.Win32NT;

		internal static string SqliteFileName => IsWindows ? "e_sqlite3.dll" : "libe_sqlite3.so";

		[DllImport("kernel32", CharSet = CharSet.Unicode, EntryPoint = "LoadLibraryW", SetLastError = true)]
		private static extern IntPtr WindowsLoad(string path);

		[DllImport("kernel32", CharSet = CharSet.Ansi, EntryPoint = "GetProcAddress", SetLastError = true)]
		private static extern IntPtr WindowsSymbol(IntPtr module, string name);

		[DllImport("libdl.so.2", EntryPoint = "dlopen")]
		private static extern IntPtr LinuxLoad(string path, int flags);

		[DllImport("libdl.so.2", EntryPoint = "dlsym")]
		private static extern IntPtr LinuxSymbol(IntPtr handle, string name);

		[DllImport("libdl.so.2", EntryPoint = "dlerror")]
		private static extern IntPtr LinuxError();

		internal static IntPtr Load(string directory)
		{
			string text = Path.Combine(directory, SqliteFileName);
			if (!File.Exists(text))
			{
				throw new FileNotFoundException("Native SQLite library not found.", text);
			}
			IntPtr intPtr = (IsWindows ? WindowsLoad(text) : LinuxLoad(text, 258));
			if (intPtr == IntPtr.Zero)
			{
				throw new DllNotFoundException("Could not load " + text + ": " + LastError());
			}
			return intPtr;
		}

		internal static IntPtr Symbol(IntPtr handle, string name)
		{
			IntPtr intPtr = (IsWindows ? WindowsSymbol(handle, name) : LinuxSymbol(handle, name));
			if (intPtr == IntPtr.Zero)
			{
				throw new EntryPointNotFoundException("SQLite function not found: " + name);
			}
			return intPtr;
		}

		private static string LastError()
		{
			if (IsWindows)
			{
				return "Win32 error " + Marshal.GetLastWin32Error();
			}
			IntPtr intPtr = LinuxError();
			return (intPtr == IntPtr.Zero) ? "unknown error" : (Marshal.PtrToStringAnsi(intPtr) ?? "unknown error");
		}
	}
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	internal static class ActivitySchema
	{
		internal const int Version = 1;

		internal const int WalCheckpointPages = 256;

		internal const long WalSizeLimitBytes = 1048576L;

		private const string CreateSql = "CREATE TABLE IF NOT EXISTS schema_info (version INTEGER NOT NULL);INSERT INTO schema_info (version) SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM schema_info);CREATE TABLE IF NOT EXISTS players (platform_id TEXT PRIMARY KEY, player_id INTEGER NOT NULL DEFAULT 0, last_name TEXT NOT NULL DEFAULT '',first_seen_utc INTEGER NOT NULL, last_seen_utc INTEGER NOT NULL);CREATE TABLE IF NOT EXISTS events (id INTEGER PRIMARY KEY, time_utc INTEGER NOT NULL, platform_id TEXT NOT NULL,player_name TEXT NOT NULL DEFAULT '', player_id INTEGER NOT NULL DEFAULT 0, event TEXT NOT NULL,x REAL NOT NULL DEFAULT 0, y REAL NOT NULL DEFAULT 0, z REAL NOT NULL DEFAULT 0,target TEXT NOT NULL DEFAULT '', amount INTEGER NOT NULL DEFAULT 0, details TEXT NOT NULL DEFAULT '');CREATE INDEX IF NOT EXISTS ix_events_time ON events (time_utc);CREATE INDEX IF NOT EXISTS ix_events_player_time ON events (platform_id, time_utc);CREATE INDEX IF NOT EXISTS ix_events_event_time ON events (event, time_utc);CREATE INDEX IF NOT EXISTS ix_events_position ON events (x, z);CREATE TABLE IF NOT EXISTS event_items (event_id INTEGER NOT NULL, source TEXT NOT NULL DEFAULT '', prefab TEXT NOT NULL,count INTEGER NOT NULL, quality INTEGER NOT NULL, crafter_id INTEGER NOT NULL DEFAULT 0,crafter_name TEXT NOT NULL DEFAULT '', custom_data TEXT NOT NULL DEFAULT '');CREATE INDEX IF NOT EXISTS ix_event_items_event ON event_items (event_id);CREATE INDEX IF NOT EXISTS ix_event_items_prefab ON event_items (prefab);CREATE TABLE IF NOT EXISTS event_damage (event_id INTEGER PRIMARY KEY, damage REAL NOT NULL, blunt REAL NOT NULL, slash REAL NOT NULL,pierce REAL NOT NULL, fire REAL NOT NULL, frost REAL NOT NULL, lightning REAL NOT NULL,poison REAL NOT NULL, spirit REAL NOT NULL, chop REAL NOT NULL, pickaxe REAL NOT NULL,total REAL NOT NULL, health_after REAL);";

		internal static void Apply(SqliteDatabase database)
		{
			database.Execute("PRAGMA journal_mode=WAL;");
			database.Execute("PRAGMA synchronous=NORMAL;");
			database.Execute("PRAGMA wal_autocheckpoint=" + 256 + ";");
			database.Execute("PRAGMA journal_size_limit=" + 1048576L + ";");
			database.Execute("CREATE TABLE IF NOT EXISTS schema_info (version INTEGER NOT NULL);INSERT INTO schema_info (version) SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM schema_info);CREATE TABLE IF NOT EXISTS players (platform_id TEXT PRIMARY KEY, player_id INTEGER NOT NULL DEFAULT 0, last_name TEXT NOT NULL DEFAULT '',first_seen_utc INTEGER NOT NULL, last_seen_utc INTEGER NOT NULL);CREATE TABLE IF NOT EXISTS events (id INTEGER PRIMARY KEY, time_utc INTEGER NOT NULL, platform_id TEXT NOT NULL,player_name TEXT NOT NULL DEFAULT '', player_id INTEGER NOT NULL DEFAULT 0, event TEXT NOT NULL,x REAL NOT NULL DEFAULT 0, y REAL NOT NULL DEFAULT 0, z REAL NOT NULL DEFAULT 0,target TEXT NOT NULL DEFAULT '', amount INTEGER NOT NULL DEFAULT 0, details TEXT NOT NULL DEFAULT '');CREATE INDEX IF NOT EXISTS ix_events_time ON events (time_utc);CREATE INDEX IF NOT EXISTS ix_events_player_time ON events (platform_id, time_utc);CREATE INDEX IF NOT EXISTS ix_events_event_time ON events (event, time_utc);CREATE INDEX IF NOT EXISTS ix_events_position ON events (x, z);CREATE TABLE IF NOT EXISTS event_items (event_id INTEGER NOT NULL, source TEXT NOT NULL DEFAULT '', prefab TEXT NOT NULL,count INTEGER NOT NULL, quality INTEGER NOT NULL, crafter_id INTEGER NOT NULL DEFAULT 0,crafter_name TEXT NOT NULL DEFAULT '', custom_data TEXT NOT NULL DEFAULT '');CREATE INDEX IF NOT EXISTS ix_event_items_event ON event_items (event_id);CREATE INDEX IF NOT EXISTS ix_event_items_prefab ON event_items (prefab);CREATE TABLE IF NOT EXISTS event_damage (event_id INTEGER PRIMARY KEY, damage REAL NOT NULL, blunt REAL NOT NULL, slash REAL NOT NULL,pierce REAL NOT NULL, fire REAL NOT NULL, frost REAL NOT NULL, lightning REAL NOT NULL,poison REAL NOT NULL, spirit REAL NOT NULL, chop REAL NOT NULL, pickaxe REAL NOT NULL,total REAL NOT NULL, health_after REAL);");
		}
	}
	internal sealed class SqliteException : Exception
	{
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		internal SqliteException(string message)
			: base(message)
		{
		}
	}
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	internal sealed class SqliteDatabase : IDisposable
	{
		private IntPtr _handle;

		internal IntPtr Handle => _handle;

		internal long LastInsertRowId => SqliteNative.LastInsertRowId(_handle);

		internal int Changes => SqliteNative.Changes(_handle);

		internal SqliteDatabase(string path)
		{
			int flags = 65542;
			if (SqliteNative.OpenV2(ToUtf8Z(path), out _handle, flags, IntPtr.Zero) != 0)
			{
				string text = ErrorMessage();
				SqliteNative.CloseV2(_handle);
				_handle = IntPtr.Zero;
				throw new SqliteException("Could not open " + path + ": " + text);
			}
			SqliteNative.BusyTimeout(_handle, 5000);
		}

		internal void Execute(string sql)
		{
			if (SqliteNative.Exec(_handle, ToUtf8Z(sql), IntPtr.Zero, IntPtr.Zero, out var errorMessage) == 0)
			{
				return;
			}
			string message = ((errorMessage != IntPtr.Zero) ? FromUtf8Z(errorMessage) : ErrorMessage());
			if (errorMessage != IntPtr.Zero)
			{
				SqliteNative.Free(errorMessage);
			}
			throw new SqliteException(message);
		}

		internal SqliteStatement Prepare(string sql)
		{
			byte[] array = ToUtf8Z(sql);
			if (SqliteNative.PrepareV2(_handle, array, array.Length, out var statement, IntPtr.Zero) != 0)
			{
				throw new SqliteException(ErrorMessage());
			}
			return new SqliteStatement(this, statement);
		}

		internal long ScalarInt64(string sql)
		{
			using SqliteStatement sqliteStatement = Prepare(sql);
			return sqliteStatement.Step() ? sqliteStatement.ColumnInt64(0) : 0;
		}

		internal string ScalarText(string sql)
		{
			using SqliteStatement sqliteStatement = Prepare(sql);
			return sqliteStatement.Step() ? sqliteStatement.ColumnText(0) : "";
		}

		internal string ErrorMessage()
		{
			return FromUtf8Z(SqliteNative.ErrMsg(_handle));
		}

		public void Dispose()
		{
			if (!(_handle == IntPtr.Zero))
			{
				SqliteNative.CloseV2(_handle);
				_handle = IntPtr.Zero;
			}
		}

		internal static byte[] ToUtf8Z(string value)
		{
			byte[] bytes = Encoding.UTF8.GetBytes(value);
			byte[] array = new byte[bytes.Length + 1];
			Buffer.BlockCopy(bytes, 0, array, 0, bytes.Length);
			return array;
		}

		internal static string FromUtf8Z(IntPtr pointer)
		{
			if (pointer == IntPtr.Zero)
			{
				return "";
			}
			int i;
			for (i = 0; Marshal.ReadByte(pointer, i) != 0; i++)
			{
			}
			byte[] array = new byte[i];
			Marshal.Copy(pointer, array, 0, i);
			return Encoding.UTF8.GetString(array);
		}
	}
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	internal sealed class SqliteStatement : IDisposable
	{
		private static readonly byte[] EmptyText = new byte[1];

		private readonly SqliteDatabase _database;

		private IntPtr _handle;

		internal SqliteStatement(SqliteDatabase database, IntPtr handle)
		{
			_database = database;
			_handle = handle;
		}

		internal void Bind(int index, long value)
		{
			Check(SqliteNative.BindInt64(_handle, index, value));
		}

		internal void Bind(int index, double value)
		{
			Check(SqliteNative.BindDouble(_handle, index, value));
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(2)]
		internal void Bind(int index, string value)
		{
			if (value == null)
			{
				Check(SqliteNative.BindNull(_handle, index));
				return;
			}
			byte[] array = ((value.Length == 0) ? EmptyText : Encoding.UTF8.GetBytes(value));
			int bytes = ((value.Length != 0) ? array.Length : 0);
			Check(SqliteNative.BindText(_handle, index, array, bytes, SqliteNative.Transient));
		}

		internal bool Step()
		{
			return SqliteNative.Step(_handle) switch
			{
				100 => true, 
				101 => false, 
				_ => throw new SqliteException(_database.ErrorMessage()), 
			};
		}

		internal void Reset()
		{
			SqliteNative.Reset(_handle);
			SqliteNative.ClearBindings(_handle);
		}

		internal long ColumnInt64(int column)
		{
			return SqliteNative.ColumnInt64(_handle, column);
		}

		internal string ColumnText(int column)
		{
			IntPtr intPtr = SqliteNative.ColumnText(_handle, column);
			int num = SqliteNative.ColumnBytes(_handle, column);
			if (intPtr == IntPtr.Zero || num == 0)
			{
				return "";
			}
			byte[] array = new byte[num];
			Marshal.Copy(intPtr, array, 0, num);
			return Encoding.UTF8.GetString(array);
		}

		public void Dispose()
		{
			if (!(_handle == IntPtr.Zero))
			{
				SqliteNative.FinalizeStatement(_handle);
				_handle = IntPtr.Zero;
			}
		}

		private void Check(int result)
		{
			if (result != 0)
			{
				throw new SqliteException(_database.ErrorMessage());
			}
		}
	}
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	internal static class SqliteNative
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate int OpenV2Fn(byte[] filename, out IntPtr db, int flags, IntPtr vfs);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate int CloseV2Fn(IntPtr db);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate int ExecFn(IntPtr db, byte[] sql, IntPtr callback, IntPtr arg, out IntPtr errorMessage);

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void FreeFn(IntPtr pointer);

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr ErrMsgFn(IntPtr db);

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int PrepareV2Fn(IntPtr db, byte[] sql, int bytes, out IntPtr statement, IntPtr tail);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate int BindInt64Fn(IntPtr statement, int index, long value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate int BindDoubleFn(IntPtr statement, int index, double value);

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int BindTextFn(IntPtr statement, int index, byte[] value, int bytes, IntPtr destructor);

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int BindNullFn(IntPtr statement, int index);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate int StepFn(IntPtr statement);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate int ResetFn(IntPtr statement);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate int ClearBindingsFn(IntPtr statement);

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int FinalizeFn(IntPtr statement);

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate long LastInsertRowIdFn(IntPtr db);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate int ChangesFn(IntPtr db);

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate long ColumnInt64Fn(IntPtr statement, int column);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate IntPtr ColumnTextFn(IntPtr statement, int column);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate int ColumnBytesFn(IntPtr statement, int column);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		internal delegate int BusyTimeoutFn(IntPtr db, int milliseconds);

		internal const int Ok = 0;

		internal const int Row = 100;

		internal const int Done = 101;

		internal const int OpenReadWrite = 2;

		internal const int OpenCreate = 4;

		internal const int OpenFullMutex = 65536;

		internal static readonly IntPtr Transient = new IntPtr(-1);

		internal static OpenV2Fn OpenV2 = null;

		internal static CloseV2Fn CloseV2 = null;

		internal static ExecFn Exec = null;

		internal static FreeFn Free = null;

		internal static ErrMsgFn ErrMsg = null;

		internal static PrepareV2Fn PrepareV2 = null;

		internal static BindInt64Fn BindInt64 = null;

		internal static BindDoubleFn BindDouble = null;

		internal static BindTextFn BindText = null;

		internal static BindNullFn BindNull = null;

		internal static StepFn Step = null;

		internal static ResetFn Reset = null;

		internal static ClearBindingsFn ClearBindings = null;

		internal static FinalizeFn FinalizeStatement = null;

		internal static LastInsertRowIdFn LastInsertRowId = null;

		internal static ChangesFn Changes = null;

		internal static ColumnInt64Fn ColumnInt64 = null;

		internal static ColumnTextFn ColumnText = null;

		internal static ColumnBytesFn ColumnBytes = null;

		internal static BusyTimeoutFn BusyTimeout = null;

		private static readonly object LoadLock = new object();

		internal static bool IsLoaded { get; private set; }

		internal static void Load(string directory)
		{
			lock (LoadLock)
			{
				if (!IsLoaded)
				{
					IntPtr library = NativeLoader.Load(directory);
					OpenV2 = Get<OpenV2Fn>(library, "sqlite3_open_v2");
					CloseV2 = Get<CloseV2Fn>(library, "sqlite3_close_v2");
					Exec = Get<ExecFn>(library, "sqlite3_exec");
					Free = Get<FreeFn>(library, "sqlite3_free");
					ErrMsg = Get<ErrMsgFn>(library, "sqlite3_errmsg");
					PrepareV2 = Get<PrepareV2Fn>(library, "sqlite3_prepare_v2");
					BindInt64 = Get<BindInt64Fn>(library, "sqlite3_bind_int64");
					BindDouble = Get<BindDoubleFn>(library, "sqlite3_bind_double");
					BindText = Get<BindTextFn>(library, "sqlite3_bind_text");
					BindNull = Get<BindNullFn>(library, "sqlite3_bind_null");
					Step = Get<StepFn>(library, "sqlite3_step");
					Reset = Get<ResetFn>(library, "sqlite3_reset");
					ClearBindings = Get<ClearBindingsFn>(library, "sqlite3_clear_bindings");
					FinalizeStatement = Get<FinalizeFn>(library, "sqlite3_finalize");
					LastInsertRowId = Get<LastInsertRowIdFn>(library, "sqlite3_last_insert_rowid");
					Changes = Get<ChangesFn>(library, "sqlite3_changes");
					ColumnInt64 = Get<ColumnInt64Fn>(library, "sqlite3_column_int64");
					ColumnText = Get<ColumnTextFn>(library, "sqlite3_column_text");
					ColumnBytes = Get<ColumnBytesFn>(library, "sqlite3_column_bytes");
					BusyTimeout = Get<BusyTimeoutFn>(library, "sqlite3_busy_timeout");
					IsLoaded = true;
				}
			}
		}

		private static T Get<[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)] T>(IntPtr library, string name) where T : Delegate
		{
			return (T)Marshal.GetDelegateForFunctionPointer(NativeLoader.Symbol(library, name), typeof(T));
		}
	}
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	internal static class ActivityPacket
	{
		internal const string Rpc = "VAL_RecordActivity";

		private const byte PacketVersion = 1;

		internal static ZPackage Write(ActivityRecord record)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write((byte)1);
			val.Write((byte)record.Type);
			val.Write(record.WorldTime);
			val.Write(new Vector3(record.X, record.Y, record.Z));
			val.Write(record.PlayerName);
			val.Write(record.PlayerId);
			val.Write(record.Target);
			val.Write(record.Amount);
			val.Write(record.Details);
			val.Write(record.Items.Count);
			foreach (ActivityItem item in record.Items)
			{
				val.Write(item.Source);
				val.Write(item.Prefab);
				val.Write(item.Count);
				val.Write(item.Quality);
				val.Write(item.CrafterId);
				val.Write(item.CrafterName);
				val.Write(item.CustomData);
			}
			val.Write(record.Damage != null);
			if (record.Damage != null)
			{
				ActivityDamage damage = record.Damage;
				val.Write(damage.Damage);
				val.Write(damage.Blunt);
				val.Write(damage.Slash);
				val.Write(damage.Pierce);
				val.Write(damage.Fire);
				val.Write(damage.Frost);
				val.Write(damage.Lightning);
				val.Write(damage.Poison);
				val.Write(damage.Spirit);
				val.Write(damage.Chop);
				val.Write(damage.Pickaxe);
				val.Write(damage.Total);
				val.Write(damage.HealthAfter);
			}
			return val;
		}

		[return: <e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(2)]
		internal static ActivityRecord Read(ZPackage package)
		{
			//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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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)
			if (package.ReadByte() != 1)
			{
				return null;
			}
			ActivityRecord activityRecord = new ActivityRecord
			{
				Type = (ActivityEventType)package.ReadByte(),
				WorldTime = package.ReadDouble()
			};
			Vector3 val = package.ReadVector3();
			activityRecord.X = val.x;
			activityRecord.Y = val.y;
			activityRecord.Z = val.z;
			activityRecord.PlayerName = package.ReadString();
			activityRecord.PlayerId = package.ReadLong();
			activityRecord.Target = package.ReadString();
			activityRecord.Amount = package.ReadInt();
			activityRecord.Details = package.ReadString();
			int num = package.ReadInt();
			for (int i = 0; i < num; i++)
			{
				activityRecord.Items.Add(new ActivityItem
				{
					Source = package.ReadString(),
					Prefab = package.ReadString(),
					Count = package.ReadInt(),
					Quality = package.ReadInt(),
					CrafterId = package.ReadLong(),
					CrafterName = package.ReadString(),
					CustomData = package.ReadString()
				});
			}
			if (package.ReadBool())
			{
				activityRecord.Damage = new ActivityDamage
				{
					Damage = package.ReadSingle(),
					Blunt = package.ReadSingle(),
					Slash = package.ReadSingle(),
					Pierce = package.ReadSingle(),
					Fire = package.ReadSingle(),
					Frost = package.ReadSingle(),
					Lightning = package.ReadSingle(),
					Poison = package.ReadSingle(),
					Spirit = package.ReadSingle(),
					Chop = package.ReadSingle(),
					Pickaxe = package.ReadSingle(),
					Total = package.ReadSingle(),
					HealthAfter = package.ReadSingle()
				};
			}
			return activityRecord;
		}
	}
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(2)]
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	internal sealed class ActivityServer : MonoBehaviour
	{
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		[HarmonyPatch(typeof(Game), "Start")]
		private static class Game_Start_StartActivityServer
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Game __instance)
			{
				if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && (Object)(object)((Component)__instance).GetComponent<ActivityServer>() == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<ActivityServer>();
				}
			}
		}

		private const float RetentionIntervalSeconds = 86400f;

		private ActivityWriter _writer;

		internal static ActivityServer Instance { get; private set; }

		private void Start()
		{
			Instance = this;
			string path = DatabasePath();
			_writer = new ActivityWriter([<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)] () =>
			{
				SqliteNative.Load(Vikings_ActivityLogPlugin.PluginDirectory);
				return new ActivityStore(path);
			}, [<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)] (string message) =>
			{
				Vikings_ActivityLogPlugin.Log.LogInfo((object)message);
			}, [<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)] (string message) =>
			{
				Vikings_ActivityLogPlugin.Log.LogError((object)message);
			});
			ZRoutedRpc.instance.Register<ZPackage>("VAL_RecordActivity", (Action<long, ZPackage>)OnRecordReceived);
			RequestRetention();
			((MonoBehaviour)this).InvokeRepeating("RequestRetention", 86400f, 86400f);
			Vikings_ActivityLogPlugin.Log.LogInfo((object)("Activity database: " + path));
		}

		private void OnDestroy()
		{
			((MonoBehaviour)this).CancelInvoke();
			_writer?.Dispose();
			_writer = null;
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		internal void RecordServerEvent(ActivityEventType type, string platformId, string playerName, Vector3 position)
		{
			//IL_0058: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			if (_writer != null && Vikings_ActivityLogPlugin.IsEventEnabled(type))
			{
				_writer.Enqueue(new ActivityRecord
				{
					Type = type,
					TimeUtcMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
					PlatformId = platformId,
					PlayerName = (playerName ?? ""),
					X = position.x,
					Y = position.y,
					Z = position.z
				});
			}
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private void OnRecordReceived(long sender, ZPackage package)
		{
			if (_writer != null && !((Object)(object)ZNet.instance == (Object)null))
			{
				ActivityRecord activityRecord;
				try
				{
					activityRecord = ActivityPacket.Read(package);
				}
				catch (Exception ex)
				{
					Vikings_ActivityLogPlugin.Log.LogWarning((object)("Ignored malformed activity packet: " + ex.Message));
					return;
				}
				if (activityRecord != null && Vikings_ActivityLogPlugin.IsEventEnabled(activityRecord.Type))
				{
					ZNetPeer peer = ZNet.instance.GetPeer(sender);
					activityRecord.PlatformId = ((peer != null) ? peer.m_socket.GetHostName() : LocalPlatformId());
					activityRecord.TimeUtcMs = ActivityClock.ToUtcMs(ZNet.instance.GetTimeSeconds(), activityRecord.WorldTime, DateTime.UtcNow);
					_writer.Enqueue(activityRecord);
				}
			}
		}

		private void RequestRetention()
		{
			if (_writer != null && Vikings_ActivityLogPlugin.CE_Retention_Enabled.Value)
			{
				_writer.RequestRetention(ActivityClock.RetentionCutoff(DateTime.UtcNow, Vikings_ActivityLogPlugin.CE_Retention_Days.Value));
			}
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static string DatabasePath()
		{
			string saveDataPath = Utils.GetSaveDataPath((FileSource)2);
			return Path.Combine(Path.Combine(saveDataPath, "Vikings_ActivityLog"), ActivityPaths.DatabaseFileName(ZNet.instance.GetWorldName()));
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static string LocalPlatformId()
		{
			try
			{
				return ((object)Unsafe.As<PlatformUserID, PlatformUserID>(ref UserInfo.GetLocalUser().UserId)/*cast due to .constrained prefix*/).ToString();
			}
			catch
			{
				return "local";
			}
		}
	}
	internal static class ConnectionEvents
	{
		[HarmonyPatch(typeof(ZNet), "SendPeerInfo")]
		private static class ZNet_SendPeerInfo_RecordConnected
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(ZNet __instance, ZRpc rpc)
			{
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				if (__instance.IsServer() && rpc != null && !((Object)(object)ActivityServer.Instance == (Object)null))
				{
					ActivityServer.Instance.RecordServerEvent(ActivityEventType.Connected, rpc.m_socket.GetHostName(), "", Vector3.zero);
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "Disconnect")]
		private static class ZNet_Disconnect_RecordDisconnected
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Prefix(ZNet __instance, ZNetPeer peer)
			{
				//IL_003d: 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_0042: 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)
				if (__instance.IsServer() && peer != null && peer.m_rpc != null && !((Object)(object)ActivityServer.Instance == (Object)null))
				{
					Vector3 position = (((ZDOID)(ref peer.m_characterID)).IsNone() ? Vector3.zero : peer.GetRefPos());
					ActivityServer.Instance.RecordServerEvent(ActivityEventType.Disconnected, peer.m_rpc.m_socket.GetHostName(), peer.m_playerName, position);
				}
			}
		}
	}
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	internal static class ActivityCapture
	{
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(2)]
		internal static bool IsLocalPlayer(Character character)
		{
			return (Object)(object)character != (Object)null && (Object)(object)character == (Object)(object)Player.m_localPlayer;
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(2)]
		internal static Vector3 PositionOf(Component component)
		{
			//IL_0017: 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_001c: 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)
			return ((Object)(object)component != (Object)null) ? component.transform.position : Vector3.zero;
		}

		internal static void Report(ActivityEventType type, Vector3 position, string target = "", int amount = 0, string details = "", [<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(new byte[] { 2, 1 })] List<ActivityItem> items = null, [<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(2)] ActivityDamage damage = null)
		{
			//IL_008c: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			if (Vikings_ActivityLogPlugin.IsEventEnabled(type) && !((Object)(object)ZNet.instance == (Object)null) && ZRoutedRpc.instance != null)
			{
				Player localPlayer = Player.m_localPlayer;
				ActivityRecord activityRecord = new ActivityRecord
				{
					Type = type,
					WorldTime = ZNet.instance.GetTimeSeconds(),
					PlayerName = (((Object)(object)localPlayer != (Object)null) ? localPlayer.GetPlayerName() : ""),
					PlayerId = (((Object)(object)localPlayer != (Object)null) ? localPlayer.GetPlayerID() : 0),
					X = position.x,
					Y = position.y,
					Z = position.z,
					Target = (target ?? ""),
					Amount = amount,
					Details = (details ?? ""),
					Damage = damage
				};
				if (items != null)
				{
					activityRecord.Items = items;
				}
				ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "VAL_RecordActivity", new object[1] { ActivityPacket.Write(activityRecord) });
			}
		}

		internal static ActivityItem Item(ItemData item, int count, string source = "")
		{
			return new ActivityItem
			{
				Source = source,
				Prefab = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : item.m_shared.m_name),
				Count = count,
				Quality = item.m_quality,
				CrafterId = item.m_crafterID,
				CrafterName = ((item.m_crafterID != 0L) ? (item.m_crafterName ?? "") : ""),
				CustomData = CustomDataText(item.m_customData)
			};
		}

		internal static List<ActivityItem> Items(IEnumerable<ItemData> items, string source = "")
		{
			List<ActivityItem> list = new List<ActivityItem>();
			foreach (ItemData item in items)
			{
				if (item != null)
				{
					list.Add(Item(item, item.m_stack, source));
				}
			}
			return list;
		}

		internal static ActivityDamage DamageOf(HitData hit, float healthAfter = float.NaN)
		{
			//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_000e: 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_0026: 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_003e: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			DamageTypes damage = hit.m_damage;
			return new ActivityDamage
			{
				Damage = damage.m_damage,
				Blunt = damage.m_blunt,
				Slash = damage.m_slash,
				Pierce = damage.m_pierce,
				Fire = damage.m_fire,
				Frost = damage.m_frost,
				Lightning = damage.m_lightning,
				Poison = damage.m_poison,
				Spirit = damage.m_spirit,
				Chop = damage.m_chop,
				Pickaxe = damage.m_pickaxe,
				Total = ((DamageTypes)(ref damage)).GetTotalDamage(),
				HealthAfter = healthAfter
			};
		}

		internal static string PlayerLabel(Player player)
		{
			return player.GetPlayerName() + "(" + player.GetPlayerID().ToString(CultureInfo.InvariantCulture) + ")";
		}

		internal static string Format(Vector3 position)
		{
			//IL_000b: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			return string.Format(CultureInfo.InvariantCulture, "({0:0.0} {1:0.0} {2:0.0})", position.x, position.y, position.z);
		}

		private static string CustomDataText([<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(new byte[] { 2, 1, 1 })] Dictionary<string, string> data)
		{
			if (data == null || data.Count == 0)
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder();
			foreach (KeyValuePair<string, string> datum in data)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(", ");
				}
				stringBuilder.Append('[').Append(datum.Key).Append("]:[")
					.Append(datum.Value)
					.Append(']');
			}
			return stringBuilder.ToString();
		}
	}
	internal sealed class PeriodicSampler : MonoBehaviour
	{
		[HarmonyPatch(typeof(Player), "SetLocalPlayer")]
		private static class Player_SetLocalPlayer_AddSampler
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Player __instance)
			{
				if ((!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()) && (Object)(object)((Component)__instance).GetComponent<PeriodicSampler>() == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<PeriodicSampler>();
				}
			}
		}

		private const float PingIntervalSeconds = 60f;

		private const float InventoryIntervalSeconds = 600f;

		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(1)]
		private Player _player = null;

		private void Start()
		{
			_player = ((Component)this).GetComponent<Player>();
			((MonoBehaviour)this).InvokeRepeating("SamplePing", 60f, 60f);
			((MonoBehaviour)this).InvokeRepeating("SampleInventory", 1f, 600f);
		}

		private void SamplePing()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_player == (Object)null) && !((Character)_player).IsDead() && !((Object)(object)ZNet.instance == (Object)null))
			{
				float num = default(float);
				float num2 = default(float);
				int amount = default(int);
				float num3 = default(float);
				float num4 = default(float);
				ZNet.instance.GetNetStats(ref num, ref num2, ref amount, ref num3, ref num4);
				ActivityCapture.Report(ActivityEventType.Ping, ((Component)_player).transform.position, "", amount);
			}
		}

		private void SampleInventory()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_player == (Object)null) && !((Character)_player).IsDead())
			{
				ActivityCapture.Report(ActivityEventType.Inventory, ((Component)_player).transform.position, "", 0, "", ActivityCapture.Items(((Humanoid)_player).GetInventory().GetAllItems()));
			}
		}
	}
	internal static class CombatEvents
	{
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static class Character_ApplyDamage_RecordDamaged
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Finalizer(Character __instance, HitData hit)
			{
				//IL_002c: 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)
				if (ActivityCapture.IsLocalPlayer(__instance) && hit != null)
				{
					string target = AttackerLabel(hit);
					float health = __instance.GetHealth();
					ActivityCapture.Report(ActivityEventType.Damaged, ((Component)__instance).transform.position, target, 0, "", null, ActivityCapture.DamageOf(hit, health));
					if (health <= 0f)
					{
						ActivityCapture.Report(ActivityEventType.Dead, ((Component)__instance).transform.position, target);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		private static class Character_Damage_RecordDamage
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Character __instance, HitData hit)
			{
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				if (IsLocalPlayerHit(hit))
				{
					string details = "";
					Player val = (Player)(object)((__instance is Player) ? __instance : null);
					string target;
					if (val != null)
					{
						target = ActivityCapture.PlayerLabel(val);
					}
					else
					{
						target = Utils.GetPrefabName(((Component)__instance).gameObject);
						details = "lvl:" + __instance.GetLevel() + " tamed:" + __instance.IsTamed();
					}
					ActivityCapture.Report(ActivityEventType.Damage, ((Component)__instance).transform.position, target, 0, details, null, ActivityCapture.DamageOf(hit));
				}
			}
		}

		[HarmonyPatch(typeof(Destructible), "Damage")]
		private static class Destructible_Damage_RecordDamage
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Destructible __instance, HitData hit, bool __runOriginal)
			{
				if (__runOriginal)
				{
					RecordStructureDamage((Component)(object)__instance, hit);
				}
			}
		}

		[HarmonyPatch(typeof(HitArea), "Damage")]
		private static class HitArea_Damage_RecordDamage
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(HitArea __instance, HitData hit, bool __runOriginal)
			{
				if (__runOriginal)
				{
					RecordStructureDamage((Component)(object)__instance, hit);
				}
			}
		}

		[HarmonyPatch(typeof(MineRock), "Damage")]
		private static class MineRock_Damage_RecordDamage
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(MineRock __instance, HitData hit, bool __runOriginal)
			{
				if (__runOriginal)
				{
					RecordStructureDamage((Component)(object)__instance, hit);
				}
			}
		}

		[HarmonyPatch(typeof(MineRock5), "Damage")]
		private static class MineRock5_Damage_RecordDamage
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(MineRock5 __instance, HitData hit, bool __runOriginal)
			{
				if (__runOriginal)
				{
					RecordStructureDamage((Component)(object)__instance, hit);
				}
			}
		}

		[HarmonyPatch(typeof(Raven), "Damage")]
		private static class Raven_Damage_RecordDamage
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Raven __instance, HitData hit, bool __runOriginal)
			{
				if (__runOriginal)
				{
					RecordStructureDamage((Component)(object)__instance, hit);
				}
			}
		}

		[HarmonyPatch(typeof(WearNTear), "Damage")]
		private static class WearNTear_Damage_RecordDamage
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(WearNTear __instance, HitData hit, bool __runOriginal)
			{
				if (__runOriginal)
				{
					RecordStructureDamage((Component)(object)__instance, hit);
				}
			}
		}

		[HarmonyPatch(typeof(TreeBase), "Damage")]
		private static class TreeBase_Damage_RecordDamage
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(TreeBase __instance, HitData hit, bool __runOriginal)
			{
				if (__runOriginal)
				{
					RecordStructureDamage((Component)(object)__instance, hit);
				}
			}
		}

		[HarmonyPatch(typeof(TreeLog), "Damage")]
		private static class TreeLog_Damage_RecordDamage
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(TreeLog __instance, HitData hit, bool __runOriginal)
			{
				if (__runOriginal)
				{
					RecordStructureDamage((Component)(object)__instance, hit);
				}
			}
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static string AttackerLabel(HitData hit)
		{
			if (!hit.HaveAttacker())
			{
				return "none";
			}
			Character attacker = hit.GetAttacker();
			Player val = (Player)(object)((attacker is Player) ? attacker : null);
			if (val != null)
			{
				return ActivityCapture.PlayerLabel(val);
			}
			return ((Object)(object)attacker != (Object)null) ? Utils.GetPrefabName(((Component)attacker).gameObject) : "none";
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static bool IsLocalPlayerHit(HitData hit)
		{
			return hit != null && hit.HaveAttacker() && ActivityCapture.IsLocalPlayer(hit.GetAttacker());
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static void RecordStructureDamage(Component target, HitData hit)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (IsLocalPlayerHit(hit))
			{
				ActivityCapture.Report(ActivityEventType.Damage, ActivityCapture.PositionOf(target), Utils.GetPrefabName(target.gameObject), 0, "", null, ActivityCapture.DamageOf(hit));
			}
		}
	}
	internal static class CommandEvents
	{
		[HarmonyPatch(typeof(ConsoleCommand), "RunAction")]
		private static class ConsoleCommand_RunAction_RecordCommand
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Prefix(ConsoleEventArgs args)
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsDedicated() && args != null)
				{
					ActivityCapture.Report(ActivityEventType.Command, ActivityCapture.PositionOf((Component)(object)Player.m_localPlayer), "", 0, args.FullLine);
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "RemoteCommand")]
		private static class ZNet_RemoteCommand_RecordCommand
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Prefix(string command)
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsDedicated())
				{
					ActivityCapture.Report(ActivityEventType.CommandRemote, ActivityCapture.PositionOf((Component)(object)Player.m_localPlayer), "", 0, command ?? "");
				}
			}
		}
	}
	internal static class InventoryEvents
	{
		[HarmonyPatch(typeof(Inventory), "MoveAll")]
		private static class Inventory_MoveAll_RecordMoveAll
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Prefix(Inventory __instance, Inventory fromInventory)
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				if (fromInventory != null && IsPlayerAction(fromInventory, __instance))
				{
					ActivityCapture.Report(ActivityEventType.MoveAll, PlayerPosition(), "", 0, Route(fromInventory, __instance), ActivityCapture.Items(fromInventory.GetAllItems()));
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[]
		{
			typeof(Inventory),
			typeof(ItemData)
		})]
		private static class Inventory_MoveItemToThis_RecordMove
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Prefix(Inventory __instance, Inventory fromInventory, ItemData item)
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				if (item != null && IsPlayerAction(fromInventory, __instance))
				{
					ActivityCapture.Report(ActivityEventType.Move, PlayerPosition(), "", details: Route(fromInventory, __instance), amount: item.m_stack, items: new List<ActivityItem> { ActivityCapture.Item(item, item.m_stack) });
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[]
		{
			typeof(Inventory),
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int)
		})]
		private static class Inventory_MoveItemToThisAmount_RecordMove
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Prefix(Inventory __instance, Inventory fromInventory, ItemData item, int amount)
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				if (item != null && (__instance != fromInventory || item.m_stack != amount) && IsPlayerAction(fromInventory, __instance))
				{
					Vector3 position = PlayerPosition();
					string details = Route(fromInventory, __instance);
					ActivityCapture.Report(ActivityEventType.Move, position, "", amount, details, new List<ActivityItem> { ActivityCapture.Item(item, amount) });
				}
			}
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
		[HarmonyPatch(typeof(Inventory), "StackAll")]
		private static class Inventory_StackAll_RecordStackAll
		{
			private static void Prefix(Inventory fromInventory)
			{
				StackedItems.Clear();
				_stackSource = fromInventory;
			}

			private static void Postfix(Inventory __instance, Inventory fromInventory, int __result)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				_stackSource = null;
				if (__instance != fromInventory && __result != 0 && IsPlayerAction(fromInventory, __instance))
				{
					Vector3 position = PlayerPosition();
					string details = Route(fromInventory, __instance);
					ActivityCapture.Report(ActivityEventType.StackAll, position, "", __result, details, ActivityCapture.Items(StackedItems));
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData) })]
		private static class Inventory_RemoveItem_TrackStacked
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Inventory __instance, ItemData item)
			{
				if (_stackSource != null && __instance == _stackSource && item != null && !StackedItems.Contains(item))
				{
					StackedItems.Add(item);
				}
			}
		}

		[HarmonyPatch(typeof(TombStone), "Setup")]
		private static class TombStone_Setup_RecordGrave
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(TombStone __instance)
			{
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				Player localPlayer = Player.m_localPlayer;
				Container component = ((Component)__instance).GetComponent<Container>();
				if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)component == (Object)null))
				{
					List<ActivityItem> list = ActivityCapture.Items(component.GetInventory().GetAllItems(), "grave");
					list.AddRange(ActivityCapture.Items(((Humanoid)localPlayer).GetInventory().GetAllItems(), "player"));
					ActivityCapture.Report(ActivityEventType.Grave, ((Component)__instance).transform.position, "", 0, "", list);
				}
			}
		}

		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(2)]
		private static Inventory _stackSource;

		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(1)]
		private static readonly List<ItemData> StackedItems = new List<ItemData>();

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static string Route(Inventory from, Inventory to)
		{
			return "from:" + ((from != null) ? from.GetName() : "") + " to:" + ((to != null) ? to.GetName() : "");
		}

		private static Vector3 PlayerPosition()
		{
			//IL_0006: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			return ActivityCapture.PositionOf((Component)(object)Player.m_localPlayer);
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(2)]
		private static bool IsPlayerAction(Inventory first, Inventory second)
		{
			if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsDedicated())
			{
				return false;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			if (first == inventory || second == inventory)
			{
				return true;
			}
			Container val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_currentContainer : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Inventory inventory2 = val.GetInventory();
			return first == inventory2 || second == inventory2;
		}
	}
	internal static class ItemEvents
	{
		[HarmonyPatch(typeof(Humanoid), "EquipItem")]
		private static class Humanoid_EquipItem_RecordEquip
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Finalizer(Humanoid __instance, ItemData item, bool __result)
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				if (item != null && __result && ActivityCapture.IsLocalPlayer((Character)(object)__instance) && item.IsEquipable())
				{
					ActivityCapture.Report(ActivityEventType.Equip, ((Component)__instance).transform.position, "", 0, "", Single(item, item.m_stack));
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "UnequipItem")]
		private static class Humanoid_UnequipItem_RecordUnequip
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Prefix(Humanoid __instance, ItemData item)
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				if (item != null && ActivityCapture.IsLocalPlayer((Character)(object)__instance) && item.IsEquipable() && item.m_equipped)
				{
					ActivityCapture.Report(ActivityEventType.Unequip, ((Component)__instance).transform.position, "", 0, "", Single(item, item.m_stack));
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "DropItem")]
		private static class Humanoid_DropItem_RecordDrop
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Humanoid __instance, Inventory inventory, ItemData item, int amount, bool __result)
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				if (__result && item != null && ActivityCapture.IsLocalPlayer((Character)(object)__instance))
				{
					ActivityCapture.Report(ActivityEventType.Drop, ((Component)__instance).transform.position, (inventory != null) ? inventory.GetName() : "", amount, "", Single(item, amount));
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "Pickup")]
		private static class Humanoid_Pickup_RecordPickup
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Humanoid __instance, GameObject go, bool __result)
			{
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				ItemDrop val = default(ItemDrop);
				if (__result && !((Object)(object)go == (Object)null) && ActivityCapture.IsLocalPlayer((Character)(object)__instance) && go.TryGetComponent<ItemDrop>(ref val))
				{
					ActivityCapture.Report(ActivityEventType.Pickup, go.transform.position, "", 0, "", Single(val.m_itemData, val.m_itemData.m_stack));
				}
			}
		}

		[HarmonyPatch(typeof(Player), "ConsumeItem")]
		private static class Player_ConsumeItem_RecordConsume
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Player __instance, Inventory inventory, ItemData item, bool __result)
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				if (__result && item != null && ActivityCapture.IsLocalPlayer((Character)(object)__instance))
				{
					ActivityCapture.Report(ActivityEventType.Consume, ((Component)__instance).transform.position, (inventory != null) ? inventory.GetName() : "", 0, "", Single(item, 1));
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		private static class InventoryGui_DoCrafting_TrackCrafting
		{
			[HarmonyPriority(800)]
			private static void Prefix()
			{
				_crafting = true;
			}

			[HarmonyPriority(0)]
			private static void Finalizer()
			{
				_crafting = false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(string),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(long),
			typeof(string),
			typeof(Vector2i),
			typeof(bool),
			typeof(bool),
			typeof(bool)
		})]
		private static class Inventory_AddItem_RecordCraft
		{
			[HarmonyPriority(0)]
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Finalizer(ItemData __result)
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				if (_crafting && __result != null)
				{
					Player localPlayer = Player.m_localPlayer;
					if (!((Object)(object)localPlayer == (Object)null))
					{
						ActivityCapture.Report(ActivityEventType.Craft, ((Component)localPlayer).transform.position, "", 0, "", Single(__result, __result.m_stack));
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "RepairOneItem")]
		private static class InventoryGui_RepairOneItem_TrackRepair
		{
			private static void Prefix()
			{
				_repairingItem = true;
			}

			private static void Finalizer()
			{
				_repairingItem = false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "CanRepair")]
		private static class InventoryGui_CanRepair_RecordRepairItem
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(ItemData item, bool __result)
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				if (_repairingItem && __result && item != null)
				{
					Player localPlayer = Player.m_localPlayer;
					if (!((Object)(object)localPlayer == (Object)null))
					{
						ActivityCapture.Report(ActivityEventType.RepairItem, ((Component)localPlayer).transform.position, "", 0, "", Single(item, item.m_stack));
					}
				}
			}
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
		[HarmonyPatch(typeof(Player), "AddAdrenaline")]
		private static class Player_AddAdrenaline_RecordTrinket
		{
			private static void Prefix(Player __instance)
			{
				_trinketActiveBefore = ActivityCapture.IsLocalPlayer((Character)(object)__instance) && TrinketEffectActive(__instance, ActiveTrinket(__instance));
			}

			private static void Postfix(Player __instance)
			{
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				if (!_trinketActiveBefore && ActivityCapture.IsLocalPlayer((Character)(object)__instance))
				{
					ItemData val = ActiveTrinket(__instance);
					if (val != null && TrinketEffectActive(__instance, val))
					{
						ActivityCapture.Report(ActivityEventType.TrinketActivated, ((Component)__instance).transform.position, "", 0, "", Single(val, 1));
					}
				}
			}
		}

		private static bool _crafting;

		private static bool _repairingItem;

		private static bool _trinketActiveBefore;

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		[return: <e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(2)]
		private static ItemData ActiveTrinket(Player player)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (allItem != null && (int)allItem.m_shared.m_itemType == 24 && (Object)(object)allItem.m_shared.m_fullAdrenalineSE != (Object)null && allItem.m_shared.m_maxAdrenaline > 0f)
				{
					return allItem;
				}
			}
			return null;
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static bool TrinketEffectActive(Player player, [<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(2)] ItemData trinket)
		{
			return trinket != null && ((Character)player).GetSEMan().HaveStatusEffect(trinket.m_shared.m_fullAdrenalineSE.NameHash());
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static List<ActivityItem> Single(ItemData item, int count, string source = "")
		{
			return new List<ActivityItem> { ActivityCapture.Item(item, count, source) };
		}
	}
	internal static class PlayerEvents
	{
		[HarmonyPatch(typeof(Player), "OnSpawned")]
		private static class Player_OnSpawned_RecordSpawn
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Player __instance)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				if (ActivityCapture.IsLocalPlayer((Character)(object)__instance))
				{
					ActivityCapture.Report(ActivityEventType.Spawned, ((Component)__instance).transform.position, ActivityCapture.PlayerLabel(__instance));
				}
			}
		}

		[HarmonyPatch(typeof(Player), "PlacePiece")]
		private static class Player_PlacePiece_RecordPlace
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Player __instance, Piece piece, Vector3 pos)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				if (ActivityCapture.IsLocalPlayer((Character)(object)__instance) && !((Object)(object)piece == (Object)null))
				{
					ActivityCapture.Report(ActivityEventType.Place, pos, Utils.GetPrefabName(((Component)piece).gameObject));
				}
			}
		}

		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static class Player_TeleportTo_RecordTeleport
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Player __instance, Vector3 pos, bool distantTeleport, bool __result)
			{
				//IL_001e: 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)
				if (__result && ActivityCapture.IsLocalPlayer((Character)(object)__instance))
				{
					ActivityCapture.Report(ActivityEventType.Teleport, ((Component)__instance).transform.position, ActivityCapture.Format(pos), 0, "distant:" + distantTeleport);
				}
			}
		}

		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
		[HarmonyPatch(typeof(Player), "UpdateDodge")]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static class Player_UpdateDodge_RecordDodge
		{
			private static void Prefix(Player __instance)
			{
				if (ActivityCapture.IsLocalPlayer((Character)(object)__instance))
				{
					_wasDodging = ((Character)__instance).InDodge();
				}
			}

			private static void Postfix(Player __instance)
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				if (ActivityCapture.IsLocalPlayer((Character)(object)__instance))
				{
					bool flag = ((Character)__instance).InDodge();
					if (!_wasDodging && flag)
					{
						ActivityCapture.Report(ActivityEventType.Dodge, ((Component)__instance).transform.position);
					}
					_wasDodging = flag;
				}
			}
		}

		private static bool _wasDodging;
	}
	internal static class WorldEvents
	{
		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		[HarmonyPatch(typeof(Player), "RemovePiece")]
		private static class Player_RemovePiece_RecordRemove
		{
			private static void Prefix(Player __instance)
			{
				_removingPiece = ActivityCapture.IsLocalPlayer((Character)(object)__instance);
				_removedName = "";
			}

			private static void Postfix(Player __instance, bool __result)
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				bool flag = __result && _removingPiece && _removedName.Length > 0 && ActivityCapture.IsLocalPlayer((Character)(object)__instance);
				_removingPiece = false;
				if (flag)
				{
					ActivityCapture.Report(ActivityEventType.Remove, _removedPosition, _removedName);
				}
				_removedName = "";
			}
		}

		[HarmonyPatch(typeof(Player), "CheckCanRemovePiece")]
		private static class Player_CheckCanRemovePiece_TrackRemoved
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Piece piece, bool __result)
			{
				//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)
				if (__result && _removingPiece && !((Object)(object)piece == (Object)null))
				{
					_removedName = Utils.GetPrefabName(((Component)piece).gameObject);
					_removedPosition = ((Component)piece).transform.position;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Repair")]
		private static class Player_Repair_TrackRepair
		{
			private static void Prefix()
			{
				_repairingPiece = true;
			}

			private static void Finalizer()
			{
				_repairingPiece = false;
			}
		}

		[HarmonyPatch(typeof(WearNTear), "Repair")]
		private static class WearNTear_Repair_RecordRepairBuilding
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(WearNTear __instance, bool __result)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				if (_repairingPiece && __result)
				{
					ActivityCapture.Report(ActivityEventType.RepairBuilding, ((Component)__instance).transform.position, Utils.GetPrefabName(((Component)__instance).gameObject));
				}
			}
		}

		[HarmonyPatch(typeof(PrivateArea), "Interact")]
		private static class PrivateArea_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(PrivateArea __instance, Humanoid human, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, human, "owner:" + __instance.GetCreatorName() + " active:" + __instance.IsEnabled());
			}
		}

		[HarmonyPatch(typeof(WayStone), "Interact")]
		private static class WayStone_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(WayStone __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Vegvisir), "Interact")]
		private static class Vegvisir_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Vegvisir __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Vagon), "Interact")]
		private static class Vagon_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Vagon __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Trader), "Interact")]
		private static class Trader_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Trader __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(TombStone), "Interact")]
		private static class TombStone_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(TombStone __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(ToggleSwitch), "Interact")]
		private static class ToggleSwitch_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(ToggleSwitch __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Teleport), "Interact")]
		private static class Teleport_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Teleport __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Switch), "Interact")]
		private static class Switch_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Switch __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Sign), "Interact")]
		private static class Sign_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Sign __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(ShipControlls), "Interact")]
		private static class ShipControlls_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(ShipControlls __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(RuneStone), "Interact")]
		private static class RuneStone_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(RuneStone __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Raven), "Interact")]
		private static class Raven_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Raven __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(PickableItem), "Interact")]
		private static class PickableItem_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(PickableItem __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Pickable), "Interact")]
		private static class Pickable_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Pickable __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Ladder), "Interact")]
		private static class Ladder_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Ladder __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Beehive), "Interact")]
		private static class Beehive_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Beehive __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Container), "Interact")]
		private static class Container_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Container __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Door), "Interact")]
		private static class Door_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Door __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Fish), "Interact")]
		private static class Fish_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Fish __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(RopeAttachment), "Interact")]
		private static class RopeAttachment_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(RopeAttachment __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(SapCollector), "Interact")]
		private static class SapCollector_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(SapCollector __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Trap), "Interact")]
		private static class Trap_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Trap __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Turret), "Interact")]
		private static class Turret_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Turret __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(ItemDrop), "Interact")]
		private static class ItemDrop_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(ItemDrop __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Sadle), "Interact")]
		private static class Sadle_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Sadle __instance, Humanoid character, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, character);
			}
		}

		[HarmonyPatch(typeof(Feast), "Interact")]
		private static class Feast_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Feast __instance, Humanoid human, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, human);
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "Interact")]
		private static class TeleportWorld_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(TeleportWorld __instance, Humanoid human, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, human);
			}
		}

		[HarmonyPatch(typeof(Bed), "Interact")]
		private static class Bed_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Bed __instance, Humanoid human, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, human);
			}
		}

		[HarmonyPatch(typeof(Chair), "Interact")]
		private static class Chair_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Chair __instance, Humanoid human, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, human);
			}
		}

		[HarmonyPatch(typeof(Barber), "Interact")]
		private static class Barber_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Barber __instance, Humanoid human, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, human);
			}
		}

		[HarmonyPatch(typeof(ArcheryTarget), "Interact")]
		private static class ArcheryTarget_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(ArcheryTarget __instance, Humanoid user, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, user);
			}
		}

		[HarmonyPatch(typeof(Tameable), "Interact")]
		private static class Tameable_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Tameable __instance, Humanoid user, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, user);
			}
		}

		[HarmonyPatch(typeof(OfferingBowl), "Interact")]
		private static class OfferingBowl_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(OfferingBowl __instance, Humanoid user, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, user);
			}
		}

		[HarmonyPatch(typeof(CookingStation), "Interact")]
		private static class CookingStation_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(CookingStation __instance, Humanoid user, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, user);
			}
		}

		[HarmonyPatch(typeof(CraftingStation), "Interact")]
		private static class CraftingStation_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(CraftingStation __instance, Humanoid user, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, user);
			}
		}

		[HarmonyPatch(typeof(Fermenter), "Interact")]
		private static class Fermenter_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Fermenter __instance, Humanoid user, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, user);
			}
		}

		[HarmonyPatch(typeof(Fireplace), "Interact")]
		private static class Fireplace_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Fireplace __instance, Humanoid user, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, user);
			}
		}

		[HarmonyPatch(typeof(ItemStand), "Interact")]
		private static class ItemStand_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(ItemStand __instance, Humanoid user, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, user);
			}
		}

		[HarmonyPatch(typeof(Pet), "Interact")]
		private static class Pet_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Pet __instance, Humanoid user, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, user);
			}
		}

		[HarmonyPatch(typeof(ShieldGenerator), "Interact")]
		private static class ShieldGenerator_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(ShieldGenerator __instance, Humanoid user, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, user);
			}
		}

		[HarmonyPatch(typeof(Petable), "Interact")]
		private static class Petable_Interact_RecordInteract
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Petable __instance, Humanoid user, bool __result)
			{
				RecordInteraction((Component)(object)__instance, __result, user);
			}
		}

		[HarmonyPatch(typeof(CookingStation), "UseItem")]
		private static class CookingStation_UseItem_RecordUse
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(CookingStation __instance, Humanoid user, ItemData item, bool __result)
			{
				RecordUse((Component)(object)__instance, user, item, __result);
			}
		}

		[HarmonyPatch(typeof(Fireplace), "UseItem")]
		private static class Fireplace_UseItem_RecordUse
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Fireplace __instance, Humanoid user, ItemData item, bool __result)
			{
				RecordUse((Component)(object)__instance, user, item, __result);
			}
		}

		[HarmonyPatch(typeof(Fermenter), "UseItem")]
		private static class Fermenter_UseItem_RecordUse
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Fermenter __instance, Humanoid user, ItemData item, bool __result)
			{
				RecordUse((Component)(object)__instance, user, item, __result);
			}
		}

		[HarmonyPatch(typeof(ItemStand), "UseItem")]
		private static class ItemStand_UseItem_RecordUse
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(ItemStand __instance, Humanoid user, ItemData item, bool __result)
			{
				RecordUse((Component)(object)__instance, user, item, __result);
			}
		}

		[HarmonyPatch(typeof(OfferingBowl), "UseItem")]
		private static class OfferingBowl_UseItem_RecordUse
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(OfferingBowl __instance, Humanoid user, ItemData item, bool __result)
			{
				RecordUse((Component)(object)__instance, user, item, __result);
			}
		}

		[HarmonyPatch(typeof(Switch), "UseItem")]
		private static class Switch_UseItem_RecordUse
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Switch __instance, Humanoid user, ItemData item, bool __result)
			{
				RecordUse((Component)(object)__instance, user, item, __result);
			}
		}

		[HarmonyPatch(typeof(PrivateArea), "UseItem")]
		private static class PrivateArea_UseItem_RecordUse
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Finalizer(PrivateArea __instance, Humanoid user, ItemData item, bool __result)
			{
				RecordUse((Component)(object)__instance, user, item, __result);
			}
		}

		[HarmonyPatch(typeof(Tameable), "SetText")]
		private static class Tameable_SetText_RecordText
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Tameable __instance, string text)
			{
				if ((Object)(object)__instance.m_nview != (Object)null && __instance.m_nview.IsValid())
				{
					RecordText((Component)(object)__instance, text);
				}
			}
		}

		[HarmonyPatch(typeof(Sign), "SetText")]
		private static class Sign_SetText_RecordText
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(Sign __instance, string text)
			{
				if ((Object)(object)__instance.m_nview != (Object)null && __instance.m_nview.IsValid() && string.Equals(__instance.GetText(), text))
				{
					RecordText((Component)(object)__instance, text);
				}
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "SetText")]
		private static class TeleportWorld_SetText_RecordText
		{
			[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
			private static void Postfix(TeleportWorld __instance, string text)
			{
				if ((Object)(object)__instance.m_nview != (Object)null && __instance.m_nview.IsValid())
				{
					RecordText((Component)(object)__instance, text);
				}
			}
		}

		private static bool _removingPiece;

		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(1)]
		private static string _removedName = "";

		private static Vector3 _removedPosition;

		private static bool _repairingPiece;

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static void RecordInteraction(Component target, bool result, Humanoid actor, string info = "")
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if (ActivityCapture.IsLocalPlayer((Character)(object)actor) && !((Object)(object)target == (Object)null))
			{
				string details = "result:" + result + ((info.Length > 0) ? (" info:" + info) : "");
				ActivityCapture.Report(ActivityEventType.Interact, target.transform.position, Utils.GetPrefabName(target.gameObject), 0, details);
			}
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static void RecordUse(Component target, Humanoid user, ItemData item, bool result)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (result && item != null && ActivityCapture.IsLocalPlayer((Character)(object)user))
			{
				ActivityCapture.Report(ActivityEventType.Use, target.transform.position, Utils.GetPrefabName(target.gameObject), 0, "", new List<ActivityItem> { ActivityCapture.Item(item, 1) });
			}
		}

		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
		private static void RecordText(Component target, string text)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			ActivityCapture.Report(ActivityEventType.Text, target.transform.position, Utils.GetPrefabName(target.gameObject), 0, text ?? "");
		}
	}
	[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(0)]
	[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(1)]
	[BepInPlugin("radamanto.Vikings_ActivityLog", "Vikings_ActivityLog", "1.0.0")]
	public class Vikings_ActivityLogPlugin : BaseUnityPlugin
	{
		[<40068039-da89-4c14-aa16-01cfd3a68ffa>NullableContext(0)]
		private class ConfigurationManagerAttributes
		{
			public bool? Browsable = false;
		}

		public const string ModGUID = "radamanto.Vikings_ActivityLog";

		public const string ModName = "Vikings_ActivityLog";

		public const string ModVersion = "1.0.0";

		internal static ManualLogSource Log = null;

		internal static string PluginDirectory = "";

		private readonly Harmony _harmony = new Harmony("radamanto.Vikings_ActivityLog");

		internal static ConfigEntry<bool> CE_General_Enabled = null;

		internal static ConfigEntry<bool> CE_Retention_Enabled = null;

		internal static ConfigEntry<int> CE_Retention_Days = null;

		private static readonly Dictionary<ActivityEventType, ConfigEntry<bool>> EventSwitches = new Dictionary<ActivityEventType, ConfigEntry<bool>>();

		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(2)]
		private static ConfigSync ConfigSync;

		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(2)]
		private static ConfigEntry<bool> _serverConfigLocked;

		[<e8d1da4e-51b0-4742-9b18-4ef846081fed>Nullable(2)]
		private FileSystemWatcher _configWatcher;

		private long _lastCfgWrite;

		private bool _reloadScheduled;

		private bool _watcherReady;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? Paths.PluginPath;
			bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			try
			{
				SetupServerSync();
				Configure();
				_harmony.PatchAll();
			}
			finally
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet;
			}
			((BaseUnityPlugin)this).Config.Save();
			SetupConfigWatcher();
		}

		private void OnDestroy()
		{
			_watcherReady = false;
			_configWatcher?.Dispose();
			_configWatcher = null;
			_harmony.UnpatchSelf();
		}

		internal static bool IsEventEnabled(ActivityEventType type)
		{
			if (CE_