Decompiled source of BuceesStation v1.0.1

Bucees.dll

Decompiled 17 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
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: AssemblyTitle("Bucees2")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Bucees2")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ee125148-39e5-49e3-ab4e-253e10319c38")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BuceesTextures;

[BepInPlugin("rebecca.repo.buceestextures", "Bucees Texture Swaps", "1.2.2")]
public class BuceesTexturesPlugin : BaseUnityPlugin
{
	private enum SwapKind
	{
		BaseColor,
		Emissive
	}

	private struct SwapSpec
	{
		public string PngStem;

		public SwapKind Kind;

		public SwapSpec(string stem, SwapKind kind)
		{
			PngStem = stem;
			Kind = kind;
		}
	}

	[CompilerGenerated]
	private sealed class <RetryApplyForSeconds>d__15 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public float totalSeconds;

		public float intervalSeconds;

		public BuceesTexturesPlugin <>4__this;

		private float <end>5__1;

		private int <swaps>5__2;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <RetryApplyForSeconds>d__15(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				<>2__current = null;
				<>1__state = 2;
				return true;
			case 2:
				<>1__state = -1;
				<end>5__1 = Time.time + totalSeconds;
				break;
			case 3:
				<>1__state = -1;
				break;
			}
			if (Time.time < <end>5__1)
			{
				<swaps>5__2 = <>4__this.ApplySwapsToMaterialsOnce();
				if (<swaps>5__2 > 0)
				{
					return false;
				}
				<>2__current = (object)new WaitForSeconds(intervalSeconds);
				<>1__state = 3;
				return true;
			}
			return false;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	public const string PluginGuid = "rebecca.repo.buceestextures";

	public const string PluginName = "Bucees Texture Swaps";

	public const string PluginVersion = "1.2.2";

	internal static ManualLogSource Log;

	private readonly Dictionary<string, SwapSpec> _replacements = new Dictionary<string, SwapSpec>
	{
		{
			"shop props_DefaultMaterial_BaseColor",
			new SwapSpec("bucees_shopprops", SwapKind.BaseColor)
		},
		{
			"centrifuge_Arctic Valuable Centrifuge_BaseColor",
			new SwapSpec("bucees_centrifuge", SwapKind.BaseColor)
		},
		{
			"arctic valuable big crate_DefaultMaterial_BaseColor",
			new SwapSpec("bucees_crate", SwapKind.BaseColor)
		},
		{
			"heavy water_DefaultMaterial_BaseColor",
			new SwapSpec("bucees_heavywater", SwapKind.BaseColor)
		},
		{
			"arctic small valuables_DefaultMaterial_BaseColor",
			new SwapSpec("bucees_mug", SwapKind.BaseColor)
		},
		{
			"new valaubles_Valuable Arctic Calculator_BaseColor",
			new SwapSpec("bucees_calculator", SwapKind.BaseColor)
		},
		{
			"cryo pod_Arctic Valuable Cryo Pod_BaseColor",
			new SwapSpec("bucees_cryopod", SwapKind.BaseColor)
		},
		{
			"cryo pod_Arctic Valuable Cryo Pod_Emissive",
			new SwapSpec("bucees_cryopod_emissive", SwapKind.Emissive)
		},
		{
			"new valaubles_Valuable Arctic Keycard_BaseColor",
			new SwapSpec("bucees_keycard", SwapKind.BaseColor)
		},
		{
			"new valaubles_Valuable Arctic Scale_BaseColor",
			new SwapSpec("bucees_scale", SwapKind.BaseColor)
		},
		{
			"science station new uv_DefaultMaterial_BaseColor",
			new SwapSpec("bucees_sciencestation", SwapKind.BaseColor)
		},
		{
			"Arctic snow bike_DefaultMaterial_BaseColor",
			new SwapSpec("bucees_snowbike", SwapKind.BaseColor)
		}
	};

	private readonly Dictionary<string, Texture2D> _pngTextures = new Dictionary<string, Texture2D>();

	private readonly HashSet<string> _swapOnceKeys = new HashSet<string>();

	private readonly HashSet<string> _missingPngWarned = new HashSet<string>();

	private string PngFolder => Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);

	private void Awake()
	{
		Log = ((BaseUnityPlugin)this).Logger;
		LoadAllPngs();
		SceneManager.sceneLoaded += OnSceneLoaded;
		((MonoBehaviour)this).StartCoroutine(RetryApplyForSeconds(90f, 1f));
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		((MonoBehaviour)this).StartCoroutine(RetryApplyForSeconds(90f, 1f));
	}

	private void LoadAllPngs()
	{
		foreach (KeyValuePair<string, SwapSpec> replacement in _replacements)
		{
			string pngStem = replacement.Value.PngStem;
			if (!_pngTextures.ContainsKey(pngStem))
			{
				Texture2D val = LoadPngTexture(pngStem);
				if ((Object)(object)val != (Object)null)
				{
					_pngTextures[pngStem] = val;
				}
			}
		}
	}

	[IteratorStateMachine(typeof(<RetryApplyForSeconds>d__15))]
	private IEnumerator RetryApplyForSeconds(float totalSeconds, float intervalSeconds)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <RetryApplyForSeconds>d__15(0)
		{
			<>4__this = this,
			totalSeconds = totalSeconds,
			intervalSeconds = intervalSeconds
		};
	}

	private int ApplySwapsToMaterialsOnce()
	{
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Invalid comparison between Unknown and I4
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		if (_pngTextures.Count == 0)
		{
			return 0;
		}
		List<Material> list = (from m in Resources.FindObjectsOfTypeAll<Material>()
			where (Object)(object)m != (Object)null
			select m).Distinct().ToList();
		int num = 0;
		for (int i = 0; i < list.Count; i++)
		{
			Material val = list[i];
			Shader shader = val.shader;
			if ((Object)(object)shader == (Object)null)
			{
				continue;
			}
			int propertyCount = shader.GetPropertyCount();
			bool flag = false;
			for (int j = 0; j < propertyCount; j++)
			{
				if ((int)shader.GetPropertyType(j) != 4)
				{
					continue;
				}
				string propertyName = shader.GetPropertyName(j);
				Texture val2 = null;
				try
				{
					val2 = val.GetTexture(propertyName);
				}
				catch
				{
					continue;
				}
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				SwapSpec value;
				bool flag2 = _replacements.TryGetValue(((Object)val2).name, out value);
				if (!flag2 && IsHeavyWaterLike(((Object)val2).name) && IsBaseColorProperty(propertyName) && _replacements.TryGetValue("heavy water_DefaultMaterial_BaseColor", out var value2))
				{
					value = value2;
					flag2 = true;
				}
				if (!flag2 || !_pngTextures.TryGetValue(value.PngStem, out var value3))
				{
					continue;
				}
				string item = ((Object)val).GetInstanceID() + "|" + propertyName + "|" + ((Object)val2).name;
				if (_swapOnceKeys.Contains(item))
				{
					continue;
				}
				val.SetTexture(propertyName, (Texture)(object)value3);
				if (value.Kind == SwapKind.BaseColor)
				{
					if (val.HasProperty("_BaseColor"))
					{
						val.SetColor("_BaseColor", Color.white);
					}
					if (val.HasProperty("_Color"))
					{
						val.SetColor("_Color", Color.white);
					}
				}
				else if (value.Kind == SwapKind.Emissive)
				{
					if (val.HasProperty("_EmissionColor"))
					{
						val.SetColor("_EmissionColor", Color.white);
					}
					val.EnableKeyword("_EMISSION");
				}
				_swapOnceKeys.Add(item);
				flag = true;
			}
			if (flag)
			{
				num++;
			}
		}
		return num;
	}

	private bool IsBaseColorProperty(string propName)
	{
		if (string.IsNullOrEmpty(propName))
		{
			return false;
		}
		string text = propName.ToLowerInvariant();
		int result;
		switch (text)
		{
		default:
			result = (text.Contains("basecolor") ? 1 : 0);
			break;
		case "_basecolormap":
		case "_maintex":
		case "_basemap":
			result = 1;
			break;
		}
		return (byte)result != 0;
	}

	private bool IsHeavyWaterLike(string textureName)
	{
		if (string.IsNullOrEmpty(textureName))
		{
			return false;
		}
		return textureName.ToLowerInvariant().Contains("heavy water");
	}

	private Texture2D LoadPngTexture(string pngStem)
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Expected O, but got Unknown
		string text = Path.Combine(PngFolder, pngStem + ".png");
		if (!File.Exists(text))
		{
			if (!_missingPngWarned.Contains(pngStem))
			{
				_missingPngWarned.Add(pngStem);
				Log.LogWarning((object)("Missing PNG next to DLL: " + text));
			}
			return null;
		}
		byte[] data = File.ReadAllBytes(text);
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, false);
		((Object)val).name = pngStem;
		if (!LoadImageReflection(val, data, markNonReadable: false))
		{
			return null;
		}
		val.Apply(true, false);
		return val;
	}

	private bool LoadImageReflection(Texture2D target, byte[] data, bool markNonReadable)
	{
		Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule") ?? Type.GetType("UnityEngine.ImageConversion, UnityEngine");
		if (type == null)
		{
			return false;
		}
		MethodInfo method = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3]
		{
			typeof(Texture2D),
			typeof(byte[]),
			typeof(bool)
		}, null);
		if (method == null)
		{
			return false;
		}
		object obj = method.Invoke(null, new object[3] { target, data, markNonReadable });
		return obj is bool && (bool)obj;
	}
}