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;
}
}