Decompiled source of YetAnotherRandomPaintingSwap v1.1.0

YetAnotherRandomPaintingSwap.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("YetAnotherRandomPaintingSwap")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1303411e96fb6e125cc75c5af886c19a2f0330ab")]
[assembly: AssemblyProduct("Yet Another Random Painting Swap")]
[assembly: AssemblyTitle("YetAnotherRandomPaintingSwap")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace YetAnotherRandomPaintingSwap
{
	[BepInPlugin("snowtyler.YetAnotherRandomPaintingSwap", "YetAnotherRandomPaintingSwap", "1.1.0")]
	public class YetAnotherRandomPaintingSwap : BaseUnityPlugin
	{
		public class PaintingGroup
		{
			public string paintingType;

			public string paintingFolderName;

			public HashSet<string> targetMaterials;

			public List<Material> loadedMaterials;

			public PaintingGroup(string paintingType, string paintingFolderName, HashSet<string> targetMaterials)
			{
				this.paintingType = paintingType;
				this.paintingFolderName = paintingFolderName;
				this.targetMaterials = targetMaterials;
				loadedMaterials = new List<Material>();
			}
		}

		[HarmonyPatch(typeof(LoadingUI), "LevelAnimationComplete")]
		public class PaintingSwapPatch
		{
			private static void Postfix()
			{
				Task.Run(async delegate
				{
					int waited = 0;
					int interval = 50;
					while (!receivedSeed.HasValue && waited < maxWaitTimeMs)
					{
						await Task.Delay(interval);
						waited += interval;
					}
					if (receivedSeed.HasValue)
					{
						logger.LogInfo($"[Postfix] Client using received seed: {receivedSeed.Value}");
						YetAnotherRandomPaintingSwapSwap.ReceivedSeed = receivedSeed.Value;
						receivedSeed = null;
					}
					else
					{
						logger.LogWarning("[Postfix] Client did not receive seed in time. Proceeding without it.");
					}
					swapper.ReplacePaintings();
				});
			}

			private static void Prefix()
			{
				if (swapper.GetModState() == YetAnotherRandomPaintingSwapSwap.ModState.Client)
				{
					PhotonNetwork.AddCallbackTarget((object)sync);
				}
				if (swapper.GetModState() == YetAnotherRandomPaintingSwapSwap.ModState.Host)
				{
					YetAnotherRandomPaintingSwapSwap.HostSeed = Random.Range(0, int.MaxValue);
					logger.LogInfo($"Generated Hostseed: {YetAnotherRandomPaintingSwapSwap.HostSeed}");
					PhotonNetwork.AddCallbackTarget((object)sync);
					sync.SendSeed(YetAnotherRandomPaintingSwapSwap.HostSeed);
				}
			}
		}

		[HarmonyPatch(typeof(NetworkConnect), "TryJoiningRoom")]
		public class JoinLobbyPatch
		{
			private static void Prefix()
			{
				logger.LogInfo("JoinLobbyPatch Prefix called.");
				if (swapper.GetModState() == YetAnotherRandomPaintingSwapSwap.ModState.SinglePlayer)
				{
					swapper.SetState(YetAnotherRandomPaintingSwapSwap.ModState.Client);
				}
			}
		}

		[HarmonyPatch(typeof(SteamManager), "HostLobby")]
		public class HostLobbyPatch
		{
			private static bool Prefix()
			{
				logger.LogInfo("HostLobbyPatch Prefix called.");
				if (swapper.GetModState() != 0)
				{
					swapper.SetState(YetAnotherRandomPaintingSwapSwap.ModState.Host);
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(SteamManager), "LeaveLobby")]
		public class LeaveLobbyPatch
		{
			private static void Postfix()
			{
				PhotonNetwork.RemoveCallbackTarget((object)sync);
				swapper.SetState(YetAnotherRandomPaintingSwapSwap.ModState.SinglePlayer);
			}
		}

		public static List<PaintingGroup> paintingGroups = new List<PaintingGroup>
		{
			new PaintingGroup("Landscape", "RandomLandscapePaintingSwap_Images", new HashSet<string> { "Painting_H_Landscape" }),
			new PaintingGroup("Portrait", "RandomPortraitPaintingSwap_Images", new HashSet<string> { "Painting_V_Furman", "painting teacher01", "painting teacher02", "painting teacher03", "painting teacher04", "Painting_S_Tree" }),
			new PaintingGroup("Square", "RandomSquarePaintingSwap_Images", new HashSet<string> { "Painting_S_Creep", "Painting_S_Creep 2_0", "Painting_S_Creep 2", "Painting Wizard Class" })
		};

		private static Logger logger = null;

		private static YetAnotherRandomPaintingSwapLoader loader = null;

		private static YetAnotherRandomPaintingSwapSwap swapper = null;

		private static YetAnotherRandomPaintingSwapSync sync = null;

		private static GrungeMaterialManager grungeMaterialManager = null;

		public static int? receivedSeed = null;

		public static readonly int maxWaitTimeMs = 3000;

		private readonly Harmony harmony = new Harmony("snowtyler.YetAnotherRandomPaintingSwap");

		private void Awake()
		{
			logger = new Logger("YetAnotherRandomPaintingSwap");
			logger.LogInfo("YetAnotherRandomPaintingSwap mod initialized.");
			PluginConfig.Init(((BaseUnityPlugin)this).Config);
			bool value = PluginConfig.Grunge.enableGrunge.Value;
			logger.LogInfo("Grunge effect is " + (value ? "ENABLED" : "DISABLED") + " in configuration");
			grungeMaterialManager = new GrungeMaterialManager(logger);
			bool flag = false;
			if (value)
			{
				if (grungeMaterialManager.LoadGrungeMaterials())
				{
					logger.LogInfo("Grunge materials loaded successfully");
				}
				else
				{
					logger.LogWarning("Failed to load grunge materials");
				}
			}
			loader = new YetAnotherRandomPaintingSwapLoader(logger, grungeMaterialManager);
			loader.LoadImagesFromAllPlugins();
			swapper = new YetAnotherRandomPaintingSwapSwap(logger, loader);
			sync = new YetAnotherRandomPaintingSwapSync(logger);
			harmony.PatchAll();
			if (PluginConfig.enableDebugLog.Value)
			{
				logger.LogInfo("Debug logging enabled");
			}
		}

		private void OnDestroy()
		{
			harmony.UnpatchSelf();
		}
	}
	internal static class PluginConfig
	{
		internal static class Grunge
		{
			internal static ConfigEntry<bool> enableGrunge;

			internal static ConfigEntry<Color> _BaseColor;

			internal static ConfigEntry<Color> _MainColor;

			internal static ConfigEntry<Color> _CracksColor;

			internal static ConfigEntry<Color> _OutlineColor;

			internal static ConfigEntry<float> _CracksPower;
		}

		internal static ConfigEntry<bool> enableDebugLog;

		internal static ConfigEntry<float> customPaintingChance;

		internal static void Init(ConfigFile config)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			enableDebugLog = config.Bind<bool>("General", "DebugLog", false, "Print extra logs for debugging");
			customPaintingChance = config.Bind<float>("General", "CustomPaintingChance", 1f, "The chance of a painting being replaced by a custom painting (1 = 100%, 0.5 = 50%)");
			Grunge.enableGrunge = config.Bind<bool>("Grunge", "EnableGrunge", true, "Whether the grunge effect is enabled");
			Grunge._BaseColor = config.Bind<Color>("Grunge", "_GrungeBaseColor", new Color(0f, 0f, 0f, 1f), "The base color of the grunge");
			Grunge._MainColor = config.Bind<Color>("Grunge", "_GrungeMainColor", new Color(0f, 0f, 0f, 1f), "The color of the main overlay of grunge");
			Grunge._CracksColor = config.Bind<Color>("Grunge", "_GrungeCracksColor", new Color(0f, 0f, 0f, 1f), "The color of the cracks in the grunge");
			Grunge._OutlineColor = config.Bind<Color>("Grunge", "_GrungeOutlineColor", new Color(0f, 0f, 0f, 1f), "The color of the grunge outlining the painting");
			Grunge._CracksPower = config.Bind<float>("Grunge", "_GrungeCracksPower", 1f, "The inverse of intensity of the cracks. 1.0 will have plenty of cracks, higher numbers will have less cracks (Values below 1.0 will start to look bad)");
		}
	}
	public class GrungeMaterialManager
	{
		private const string MATERIAL_LANDSCAPE_ASSET_NAME = "GrungeHorizontalMaterial";

		private const string MATERIAL_PORTRAIT_ASSET_NAME = "GrungeVerticalMaterial";

		private const string ASSET_BUNDLE_NAME = "painting";

		private const string PROP_BASE_COLOR = "_BaseColor";

		private const string PROP_MAIN_COLOR = "_MainColor";

		private const string PROP_CRACKS_COLOR = "_CracksColor";

		private const string PROP_OUTLINE_COLOR = "_OutlineColor";

		private const string PROP_CRACKS_POWER = "_CracksPower";

		private const string PROP_MAIN_TEX = "_MainTex";

		private Material _landscapeMaterial;

		private Material _portraitMaterial;

		private readonly Logger logger;

		public GrungeMaterialManager(Logger logger)
		{
			this.logger = logger;
		}

		public bool LoadGrungeMaterials()
		{
			if (!IsGrungeEnabled())
			{
				logger.LogInfo("Skipping grunge material loading as it's disabled in config");
				return false;
			}
			string location = Assembly.GetExecutingAssembly().Location;
			string directoryName = Path.GetDirectoryName(location);
			string text = Path.Combine(directoryName, "painting");
			logger.LogInfo("Loading asset bundle from: " + text);
			if (!File.Exists(text))
			{
				logger.LogWarning("Asset Bundle doesn't exist at: " + text);
				return false;
			}
			AssetBundle val = AssetBundle.LoadFromFile(text);
			if ((Object)(object)val == (Object)null)
			{
				logger.LogError("Failed to load asset bundle: painting");
				return false;
			}
			_landscapeMaterial = val.LoadAsset<Material>("GrungeHorizontalMaterial");
			if ((Object)(object)_landscapeMaterial == (Object)null)
			{
				logger.LogError("Could not load landscape painting material [GrungeHorizontalMaterial]!");
				return false;
			}
			_portraitMaterial = val.LoadAsset<Material>("GrungeVerticalMaterial");
			if ((Object)(object)_portraitMaterial == (Object)null)
			{
				logger.LogError("Could not load portrait painting material [GrungeVerticalMaterial]!");
				return false;
			}
			ConfigureGrungeMaterials();
			return true;
		}

		private void ConfigureGrungeMaterials()
		{
			logger.LogInfo($"Configuring grunge materials with CracksPower: {PluginConfig.Grunge._CracksPower.Value}");
			ConfigureGrungeMaterial(_landscapeMaterial);
			ConfigureGrungeMaterial(_portraitMaterial);
		}

		private void ConfigureGrungeMaterial(Material material)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)material == (Object)null))
			{
				material.SetColor("_BaseColor", PluginConfig.Grunge._BaseColor.Value);
				material.SetColor("_MainColor", PluginConfig.Grunge._MainColor.Value);
				material.SetColor("_CracksColor", PluginConfig.Grunge._CracksColor.Value);
				material.SetColor("_OutlineColor", PluginConfig.Grunge._OutlineColor.Value);
				material.SetFloat("_CracksPower", PluginConfig.Grunge._CracksPower.Value);
				material.shader.maximumLOD = 600;
			}
		}

		public Material CreateMaterialInstance(string paintingType, Texture2D texture)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			if (!IsGrungeEnabled())
			{
				return null;
			}
			Material baseMaterial = GetBaseMaterial(paintingType);
			if ((Object)(object)baseMaterial == (Object)null)
			{
				return null;
			}
			Material val = new Material(baseMaterial);
			val.SetTexture("_MainTex", (Texture)(object)texture);
			val.SetColor("_BaseColor", PluginConfig.Grunge._BaseColor.Value);
			val.SetColor("_MainColor", PluginConfig.Grunge._MainColor.Value);
			val.SetColor("_CracksColor", PluginConfig.Grunge._CracksColor.Value);
			val.SetColor("_OutlineColor", PluginConfig.Grunge._OutlineColor.Value);
			val.SetFloat("_CracksPower", PluginConfig.Grunge._CracksPower.Value);
			return val;
		}

		private Material GetBaseMaterial(string paintingType)
		{
			if (paintingType == "Portrait")
			{
				return _portraitMaterial;
			}
			return _landscapeMaterial;
		}

		public bool IsGrungeEnabled()
		{
			return PluginConfig.Grunge.enableGrunge.Value;
		}
	}
	public class YetAnotherRandomPaintingSwapLoader
	{
		private readonly Logger logger;

		private readonly GrungeMaterialManager grungeMaterialManager;

		private static readonly string[] validExtensions = new string[4] { ".png", ".jpg", ".jpeg", ".bmp" };

		public List<Material> LoadedMaterials { get; } = new List<Material>();


		public YetAnotherRandomPaintingSwapLoader(Logger logger, GrungeMaterialManager grungeMaterialManager)
		{
			this.logger = logger;
			this.grungeMaterialManager = grungeMaterialManager;
		}

		public void LoadImagesFromAllPlugins()
		{
			string pluginPath = Paths.PluginPath;
			if (!Directory.Exists(pluginPath))
			{
				logger.LogWarning("Plugins directory not found: " + pluginPath);
				return;
			}
			logger.LogInfo("Grunge effect is " + (grungeMaterialManager.IsGrungeEnabled() ? "enabled" : "disabled") + " while loading images");
			foreach (YetAnotherRandomPaintingSwap.PaintingGroup paintingGroup in YetAnotherRandomPaintingSwap.paintingGroups)
			{
				string[] directories = Directory.GetDirectories(pluginPath, paintingGroup.paintingFolderName, SearchOption.AllDirectories);
				if (directories.Length == 0)
				{
					logger.LogWarning("No '" + paintingGroup.paintingFolderName + "' folders found in plugins.");
					continue;
				}
				string[] array = directories;
				string[] array2 = array;
				foreach (string text in array2)
				{
					logger.LogInfo("Loading images from: " + text);
					LoadImagesFromDirectory(paintingGroup, text);
				}
			}
		}

		private void LoadImagesFromDirectory(YetAnotherRandomPaintingSwap.PaintingGroup paintingGroup, string directoryPath)
		{
			if (!Directory.Exists(directoryPath))
			{
				logger.LogWarning("Directory does not exist: " + directoryPath);
				return;
			}
			string[] array = (from file in Directory.EnumerateFiles(directoryPath, "*.*", SearchOption.AllDirectories)
				where validExtensions.Contains(Path.GetExtension(file).ToLower())
				select file).ToArray();
			if (array.Length == 0)
			{
				logger.LogWarning("No images found in " + directoryPath);
				return;
			}
			bool flag = grungeMaterialManager.IsGrungeEnabled();
			logger.LogInfo("Creating materials with grunge effect " + (flag ? "enabled" : "disabled"));
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i];
				string fileName = Path.GetFileName(text);
				Texture2D val = LoadTextureFromFile(text);
				if ((Object)(object)val != (Object)null)
				{
					Material val2;
					if (flag)
					{
						val2 = grungeMaterialManager.CreateMaterialInstance(paintingGroup.paintingType, val);
						if ((Object)(object)val2 == (Object)null)
						{
							val2 = CreateStandardMaterial(val);
							logger.LogInfo("Using standard shader for image: " + fileName + " (grunge creation failed)");
						}
						else
						{
							logger.LogInfo("Created grunge material for image: " + fileName);
						}
					}
					else
					{
						val2 = CreateStandardMaterial(val);
						logger.LogInfo("Using standard shader for image: " + fileName + " (grunge disabled)");
					}
					paintingGroup.loadedMaterials.Add(val2);
					logger.LogInfo($"Loaded image #{i + 1}: {fileName}");
				}
				else
				{
					logger.LogWarning($"Failed to load image #{i + 1}: {text}");
				}
			}
			logger.LogInfo($"Total images loaded for {paintingGroup.paintingType}: {paintingGroup.loadedMaterials.Count}");
		}

		private Material CreateStandardMaterial(Texture2D texture)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			return new Material(Shader.Find("Standard"))
			{
				mainTexture = (Texture)(object)texture
			};
		}

		private Texture2D LoadTextureFromFile(string filePath)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			byte[] array = File.ReadAllBytes(filePath);
			Texture2D val = new Texture2D(2, 2);
			if (ImageConversion.LoadImage(val, array))
			{
				val.Apply();
				return val;
			}
			return null;
		}
	}
	public class YetAnotherRandomPaintingSwapSwap
	{
		public enum ModState
		{
			Host,
			Client,
			SinglePlayer
		}

		private readonly Logger logger;

		private readonly YetAnotherRandomPaintingSwapLoader loader;

		private static int randomSeed = 0;

		public static int HostSeed = 0;

		public static int ReceivedSeed = 0;

		public static int Seed = 0;

		private int paintingsChangedCount;

		private static ModState currentState = ModState.SinglePlayer;

		public YetAnotherRandomPaintingSwapSwap(Logger logger, YetAnotherRandomPaintingSwapLoader loader)
		{
			this.logger = logger;
			this.loader = loader;
			logger.LogInfo($"Initial ModState: {currentState}");
			if (randomSeed == 0)
			{
				randomSeed = Random.Range(0, int.MaxValue);
				logger.LogInfo($"Generated initial random seed: {randomSeed}");
			}
		}

		public ModState GetModState()
		{
			return currentState;
		}

		public void ReplacePaintings()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			ModState modState = currentState;
			if (1 == 0)
			{
			}
			int num = modState switch
			{
				ModState.SinglePlayer => randomSeed, 
				ModState.Host => HostSeed, 
				ModState.Client => ReceivedSeed, 
				_ => Seed, 
			};
			if (1 == 0)
			{
			}
			int seed = num;
			Seed = seed;
			Scene activeScene = SceneManager.GetActiveScene();
			logger.LogInfo($"Applying seed {Seed} for painting swaps in scene: {((Scene)(ref activeScene)).name}");
			logger.LogInfo("Replacing materials with custom images...");
			paintingsChangedCount = 0;
			int num2 = 0;
			GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
			GameObject[] array = rootGameObjects;
			foreach (GameObject val in array)
			{
				MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true);
				MeshRenderer[] array2 = componentsInChildren;
				foreach (MeshRenderer val2 in array2)
				{
					Material[] sharedMaterials = ((Renderer)val2).sharedMaterials;
					bool flag = false;
					for (int k = 0; k < sharedMaterials.Length; k++)
					{
						num2++;
						foreach (YetAnotherRandomPaintingSwap.PaintingGroup paintingGroup in YetAnotherRandomPaintingSwap.paintingGroups)
						{
							if (!((Object)(object)sharedMaterials[k] != (Object)null) || !paintingGroup.targetMaterials.Contains(((Object)sharedMaterials[k]).name) || paintingGroup.loadedMaterials.Count <= 0)
							{
								continue;
							}
							if (Random.value > PluginConfig.customPaintingChance.Value)
							{
								if (PluginConfig.enableDebugLog.Value)
								{
									logger.LogInfo("Skipping replacement of " + ((Object)sharedMaterials[k]).name + " due to chance setting");
								}
								continue;
							}
							int index = Mathf.Abs((Seed + paintingsChangedCount) % paintingGroup.loadedMaterials.Count);
							sharedMaterials[k] = paintingGroup.loadedMaterials[index];
							paintingsChangedCount++;
							flag = true;
							if (PluginConfig.enableDebugLog.Value)
							{
								logger.LogInfo($"Replaced {((Object)((Component)val2).gameObject).name} material {k} with {paintingGroup.paintingType} painting");
							}
						}
					}
					if (flag)
					{
						((Renderer)val2).sharedMaterials = sharedMaterials;
					}
				}
			}
			logger.LogInfo($"Total materials checked: {num2}");
			logger.LogInfo($"Total paintings changed in this scene: {paintingsChangedCount}");
			logger.LogInfo($"RandomSeed = {randomSeed}");
			logger.LogInfo($"HostSeed = {HostSeed}");
			logger.LogInfo($"ReceivedSeed = {ReceivedSeed}");
		}

		public void SetState(ModState newState)
		{
			currentState = newState;
			logger.LogInfo($"Mod state set to: {currentState}");
		}
	}
	public class YetAnotherRandomPaintingSwapSync : MonoBehaviourPunCallbacks, IOnEventCallback
	{
		private readonly Logger logger;

		public const byte SeedEventCode = 1;

		public YetAnotherRandomPaintingSwapSync(Logger logger)
		{
			this.logger = logger;
		}

		public void SendSeed(int seed)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			object[] array = new object[1] { seed };
			logger.LogInfo("Sharing seed with other clients");
			RaiseEventOptions val = new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)0,
				CachingOption = (EventCaching)4
			};
			PhotonNetwork.RaiseEvent((byte)1, (object)array, val, SendOptions.SendReliable);
		}

		public void OnEvent(EventData photonEvent)
		{
			if (photonEvent.Code == 1)
			{
				int num = (int)((object[])photonEvent.CustomData)[0];
				logger.LogInfo($"Received seed: {num}");
				YetAnotherRandomPaintingSwap.receivedSeed = num;
			}
		}
	}
	public class Logger
	{
		private readonly string logFilePath;

		private readonly ManualLogSource logSource;

		public Logger(string modName)
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			logFilePath = Path.Combine(directoryName, modName + "_log.txt");
			if (File.Exists(logFilePath))
			{
				File.Delete(logFilePath);
			}
			logSource = Logger.CreateLogSource(modName);
		}

		public void LogInfo(string message)
		{
			WriteLog("INFO", message);
			logSource.LogInfo((object)message);
		}

		public void LogWarning(string message)
		{
			WriteLog("WARNING", message);
			logSource.LogWarning((object)message);
		}

		public void LogError(string message)
		{
			WriteLog("ERROR", message);
			logSource.LogError((object)message);
		}

		private void WriteLog(string level, string message)
		{
			string text = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [{level}] {message}";
			File.AppendAllText(logFilePath, text + Environment.NewLine);
		}

		public void LogMaterial(Material material)
		{
			if ((Object)(object)material != (Object)null && ((Object)material).name.ToLower().Contains("painting"))
			{
				LogInfo("Material containing 'painting': " + ((Object)material).name);
			}
		}

		public void ClearLog()
		{
			if (File.Exists(logFilePath))
			{
				File.Delete(logFilePath);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "YetAnotherRandomPaintingSwap";

		public const string PLUGIN_NAME = "Yet Another Random Painting Swap";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}