using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
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("BuceesFix3")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BuceesFix3")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("041a1648-997a-4121-a82d-24ef27ea1368")]
[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.0.5")]
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 <SwapWorker>d__20 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public BuceesTexturesPlugin <>4__this;
private int <i>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <SwapWorker>d__20(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Expected O, but got Unknown
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01b1: 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;
goto IL_01c2;
case 3:
<>1__state = -1;
goto IL_01c2;
case 4:
<>1__state = -1;
goto IL_0170;
case 5:
{
<>1__state = -1;
goto IL_01c2;
}
IL_01c2:
if (<>4__this._pngTextures.Count == 0)
{
<>2__current = (object)new WaitForSeconds(2f);
<>1__state = 3;
return true;
}
if (<>4__this._forceRefresh || Time.time >= <>4__this._nextCacheRefreshTime || <>4__this._materialCache.Count == 0)
{
<>4__this.RefreshMaterialCache();
<>4__this._forceRefresh = false;
<>4__this._nextCacheRefreshTime = Time.time + 5f;
}
<i>5__1 = 0;
goto IL_0183;
IL_0183:
if (<i>5__1 < <>4__this._materialCache.Count)
{
<>4__this.ApplyToMaterial(<>4__this._materialCache[<i>5__1]);
if (<i>5__1 % 70 == 0)
{
<>2__current = null;
<>1__state = 4;
return true;
}
goto IL_0170;
}
<>2__current = (object)new WaitForSeconds(1.25f);
<>1__state = 5;
return true;
IL_0170:
<i>5__1++;
goto IL_0183;
}
}
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.0.5";
private readonly Dictionary<string, SwapSpec> _replacements = new Dictionary<string, SwapSpec>(StringComparer.OrdinalIgnoreCase)
{
{
"painting board",
new SwapSpec("bucees_paintingBoard", SwapKind.BaseColor)
},
{
"painting aurora",
new SwapSpec("bucees_AuroraPainting", SwapKind.BaseColor)
},
{
"Painting McJannek",
new SwapSpec("bucees_painting", SwapKind.BaseColor)
},
{
"Painting McJannek Outside",
new SwapSpec("bucees_paintingOutside", SwapKind.BaseColor)
},
{
"painting calendar",
new SwapSpec("bucees_calendar", SwapKind.BaseColor)
},
{
"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>(StringComparer.OrdinalIgnoreCase);
private readonly HashSet<string> _ourTextureNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private readonly List<Material> _materialCache = new List<Material>(2048);
private readonly HashSet<int> _materialIds = new HashSet<int>();
private readonly Dictionary<int, string[]> _shaderTexturePropsCache = new Dictionary<int, string[]>();
private bool _forceRefresh;
private const int MaterialsPerFrame = 70;
private const float CacheRefreshInterval = 5f;
private const float IdleDelay = 1.25f;
private float _nextCacheRefreshTime;
private string PngFolder => Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
private void Awake()
{
LoadAllPngs();
SceneManager.sceneLoaded += delegate
{
_forceRefresh = true;
};
SceneManager.activeSceneChanged += delegate
{
_forceRefresh = true;
};
_forceRefresh = true;
((MonoBehaviour)this).StartCoroutine(SwapWorker());
}
private void LoadAllPngs()
{
foreach (SwapSpec value in _replacements.Values)
{
if (!_pngTextures.ContainsKey(value.PngStem))
{
Texture2D val = LoadPngTexture(value.PngStem);
if ((Object)(object)val != (Object)null)
{
_pngTextures[value.PngStem] = val;
_ourTextureNames.Add(((Object)val).name);
}
}
}
}
[IteratorStateMachine(typeof(<SwapWorker>d__20))]
private IEnumerator SwapWorker()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <SwapWorker>d__20(0)
{
<>4__this = this
};
}
private void RefreshMaterialCache()
{
_materialCache.Clear();
_materialIds.Clear();
Material[] array = Resources.FindObjectsOfTypeAll<Material>();
foreach (Material val in array)
{
if (!((Object)(object)val == (Object)null))
{
int instanceID = ((Object)val).GetInstanceID();
if (_materialIds.Add(instanceID))
{
_materialCache.Add(val);
}
}
}
}
private void ApplyToMaterial(Material mat)
{
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)mat == (Object)null)
{
return;
}
Shader shader = mat.shader;
if ((Object)(object)shader == (Object)null)
{
return;
}
string[] texturePropNames = GetTexturePropNames(shader);
if (texturePropNames == null || texturePropNames.Length == 0)
{
return;
}
foreach (string text in texturePropNames)
{
Texture texture;
try
{
texture = mat.GetTexture(text);
}
catch
{
continue;
}
if ((Object)(object)texture == (Object)null || !_ShouldReplaceThisTexture(((Object)texture).name, text, out var spec) || !_pngTextures.TryGetValue(spec.PngStem, out var value) || (Object)(object)value == (Object)null || texture == value)
{
continue;
}
mat.SetTexture(text, (Texture)(object)value);
if (spec.Kind == SwapKind.BaseColor)
{
if (mat.HasProperty("_BaseColor"))
{
mat.SetColor("_BaseColor", Color.white);
}
if (mat.HasProperty("_Color"))
{
mat.SetColor("_Color", Color.white);
}
}
else
{
if (mat.HasProperty("_EmissionColor"))
{
mat.SetColor("_EmissionColor", Color.white);
}
mat.EnableKeyword("_EMISSION");
}
}
}
private bool _ShouldReplaceThisTexture(string textureName, string propName, out SwapSpec spec)
{
spec = default(SwapSpec);
if (string.IsNullOrEmpty(textureName))
{
return false;
}
if (_ourTextureNames.Contains(textureName))
{
return false;
}
if (_replacements.TryGetValue(textureName, out spec))
{
return true;
}
if (IsBaseColorProperty(propName) && textureName.IndexOf("heavy water", StringComparison.OrdinalIgnoreCase) >= 0)
{
return _replacements.TryGetValue("heavy water_DefaultMaterial_BaseColor", out spec);
}
return false;
}
private string[] GetTexturePropNames(Shader shader)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Invalid comparison between Unknown and I4
int instanceID = ((Object)shader).GetInstanceID();
if (_shaderTexturePropsCache.TryGetValue(instanceID, out var value))
{
return value;
}
int propertyCount;
try
{
propertyCount = shader.GetPropertyCount();
}
catch
{
return Array.Empty<string>();
}
List<string> list = new List<string>(8);
for (int i = 0; i < propertyCount; i++)
{
if ((int)shader.GetPropertyType(i) == 4)
{
string propertyName = shader.GetPropertyName(i);
if (!string.IsNullOrEmpty(propertyName))
{
list.Add(propertyName);
}
}
}
string[] array = list.ToArray();
_shaderTexturePropsCache[instanceID] = array;
return array;
}
private static 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 Texture2D LoadPngTexture(string pngStem)
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
string path = Path.Combine(PngFolder, pngStem + ".png");
if (!File.Exists(path))
{
return null;
}
byte[] data;
try
{
data = File.ReadAllBytes(path);
}
catch
{
return null;
}
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, false)
{
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;
try
{
obj = method.Invoke(null, new object[3] { target, data, markNonReadable });
}
catch
{
return false;
}
bool flag = default(bool);
int num;
if (obj is bool)
{
flag = (bool)obj;
num = 1;
}
else
{
num = 0;
}
return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
}
}