using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Decorators;
using PluginConfig.API.Fields;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CustomPaintings")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ea98faf9271e0bc46962792138f494db6f51e993")]
[assembly: AssemblyProduct("CustomPaintings")]
[assembly: AssemblyTitle("CustomPaintings")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 CustomPaintings
{
public enum ReplacementStrategy
{
DeterministicRelaxedBestFit,
RandomRelaxedBestFit,
StrictBestFit,
Random
}
public class ConfigManager : BaseUnityPlugin
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static PostStringValueChangeEvent <>9__4_0;
public static PostEnumValueChangeEvent<ReplacementStrategy> <>9__4_1;
public static PostFloatValueChangeEvent <>9__4_2;
internal void <Init>b__4_0(string _)
{
Replacer.LoadCustomImages();
Replacer.DoReplacements();
}
internal void <Init>b__4_1(ReplacementStrategy _)
{
Replacer.DoReplacements();
}
internal void <Init>b__4_2(float _)
{
Replacer.DoReplacements();
}
}
public static PluginConfigurator PConf;
public static StringField CustomImageDir;
public static EnumField<ReplacementStrategy> ReplacementStrategy;
public static FloatField FitAspectRatioRelax;
public static void Init()
{
//IL_0050: 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_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Expected O, but got Unknown
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Expected O, but got Unknown
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Expected O, but got Unknown
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Expected O, but got Unknown
if (PConf != null)
{
return;
}
PConf = PluginConfigurator.Create("Custom Paintings", "com.github.end-4.customPaintings");
string text = Path.Combine(Core.workingDir, "icon.png");
if (File.Exists(text))
{
PConf.SetIconWithURL(text);
}
new ConfigHeader(PConf.rootPanel, "", 10);
new ConfigHeader(PConf.rootPanel, "-- CUSTOM PAINTINGS --", 24);
new ConfigHeader(PConf.rootPanel, "- Absolutely make sure the path is correct!\n- Allowed image types are PNG and JPG", 12, (TextAlignmentOptions)513);
CustomImageDir = new StringField(PConf.rootPanel, "Image pool folder", "folderPath", Path.Combine(Core.workingDir, "assets/defaultPool"));
StringField customImageDir = CustomImageDir;
object obj = <>c.<>9__4_0;
if (obj == null)
{
PostStringValueChangeEvent val = delegate
{
Replacer.LoadCustomImages();
Replacer.DoReplacements();
};
<>c.<>9__4_0 = val;
obj = (object)val;
}
customImageDir.postValueChangeEvent += (PostStringValueChangeEvent)obj;
ReplacementStrategy = new EnumField<ReplacementStrategy>(PConf.rootPanel, "Replacement strategy", "replacementStrategy", CustomPaintings.ReplacementStrategy.RandomRelaxedBestFit);
ReplacementStrategy.postValueChangeEvent += delegate
{
Replacer.DoReplacements();
};
FitAspectRatioRelax = new FloatField(PConf.rootPanel, "Fit aspect ratio relax amount", "fitAspectRatioRelax", 0.3f);
FloatField fitAspectRatioRelax = FitAspectRatioRelax;
object obj2 = <>c.<>9__4_2;
if (obj2 == null)
{
PostFloatValueChangeEvent val2 = delegate
{
Replacer.DoReplacements();
};
<>c.<>9__4_2 = val2;
obj2 = (object)val2;
}
fitAspectRatioRelax.postValueChangeEvent += (PostFloatValueChangeEvent)obj2;
new ConfigHeader(PConf.rootPanel, "", 30);
new ConfigHeader(PConf.rootPanel, "The artworks bundled with this mod are by Ravimo and licensed under CC-BY 4.0\n\nRavimo: https://www.pixiv.net/en/users/60562229/illustrations\nLicense: https://creativecommons.org/licenses/by/4.0/deed", 10, (TextAlignmentOptions)513);
Core.Log.LogInfo((object)"ConfigManager initialized");
}
}
[BepInPlugin("com.github.end-4.customPaintings", "CustomPaintings", "1.0.0")]
public class Core : BaseUnityPlugin
{
public static string workingPath = Assembly.GetExecutingAssembly().Location;
public static string workingDir = Path.GetDirectoryName(workingPath);
internal static ManualLogSource Log;
public const string PluginGUID = "com.github.end-4.customPaintings";
private void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
ConfigManager.Init();
Replacer.LoadCustomImages();
Replacer.DoReplacements();
SceneManager.sceneLoaded += Replacer.DoReplacements;
Log.LogInfo((object)"CustomPaintings loaded!");
}
}
public class Replacer : BaseUnityPlugin
{
private struct CustomTexture
{
public Texture2D texture;
public float aspectRatio;
public string name;
}
private static readonly List<string> MaterialPaths = new List<string>(38)
{
"Assets/Materials/Environment/Layer 1/StainedGlassBig.mat", "Assets/Materials/Environment/Layer 1/StainedGlassBigTransparent.mat", "Assets/Materials/Environment/Layer 1/StainedGlassBlue.mat", "Assets/Materials/Environment/Layer 1/StainedGlassGabriel1.mat", "Assets/Materials/Environment/Layer 1/StainedGlassLit.mat", "Assets/Materials/Environment/Layer 1/StainedGlassRed.mat", "Assets/Materials/Environment/Paintings/045.mat", "Assets/Materials/Environment/Paintings/101.mat", "Assets/Materials/Environment/Paintings/118.mat", "Assets/Materials/Environment/Paintings/161.mat",
"Assets/Materials/Environment/Paintings/166.mat", "Assets/Materials/Environment/Paintings/203.mat", "Assets/Materials/Environment/Paintings/208.mat", "Assets/Materials/Environment/Paintings/209.mat", "Assets/Materials/Environment/Paintings/210.mat", "Assets/Materials/Environment/Paintings/223.mat", "Assets/Materials/Environment/Paintings/226.mat", "Assets/Materials/Environment/Paintings/285.mat", "Assets/Materials/Environment/Paintings/286.mat", "Assets/Materials/Environment/Paintings/287.mat",
"Assets/Materials/Environment/Paintings/Archangels.mat", "Assets/Materials/Environment/Paintings/CityoftheDeadSunPoster.mat", "Assets/Materials/Environment/Paintings/Default.mat", "Assets/Materials/Environment/Paintings/Ferryman.mat", "Assets/Materials/Environment/Paintings/FerrymanGabriel.mat", "Assets/Materials/Environment/Paintings/FerrymanGabrielDestroyed.mat", "Assets/Materials/Environment/Paintings/FerrymanMirror.mat", "Assets/Materials/Environment/Paintings/FerrymanRocket.mat", "Assets/Materials/Environment/Paintings/KingMinos.mat", "Assets/Materials/Environment/Paintings/KingSisyphus.mat",
"Assets/Materials/Environment/Paintings/Leviathan.mat", "Assets/Materials/Environment/Paintings/VanGogh.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Clothes.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Clothes NoFog.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Fox.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Fox NoFog.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Wing.mat", "Assets/Materials/Environment/Layer 8/Supermarket/Ad_Wing NoFog.mat"
};
private static List<CustomTexture> CustomTextures = new List<CustomTexture>();
private static Dictionary<Material, Vector2> MatDimensions = new Dictionary<Material, Vector2>();
private static int GetDeterministicHash(string input, int max)
{
using SHA256 sHA = SHA256.Create();
return Math.Abs(BitConverter.ToInt32(sHA.ComputeHash(Encoding.UTF8.GetBytes(input)), 0)) % max;
}
private static CustomTexture FindBestMatch(float targetAspectRatio, string targetName)
{
foreach (CustomTexture customTexture in CustomTextures)
{
if (customTexture.name.Equals(targetName, StringComparison.OrdinalIgnoreCase))
{
return customTexture;
}
}
CustomTexture result = CustomTextures[0];
if (ConfigManager.ReplacementStrategy.value == ReplacementStrategy.DeterministicRelaxedBestFit || ConfigManager.ReplacementStrategy.value == ReplacementStrategy.RandomRelaxedBestFit || ConfigManager.ReplacementStrategy.value == ReplacementStrategy.StrictBestFit)
{
float num = Mathf.Abs(targetAspectRatio - result.aspectRatio);
List<int> list = new List<int>();
for (int i = 0; i < CustomTextures.Count; i++)
{
float num2 = Mathf.Abs(targetAspectRatio - CustomTextures[i].aspectRatio);
if (num2 <= ConfigManager.FitAspectRatioRelax.value)
{
list.Add(i);
}
else if (num2 < num)
{
num = num2;
result = CustomTextures[i];
}
}
if (ConfigManager.ReplacementStrategy.value != ReplacementStrategy.StrictBestFit && list.Count > 0)
{
int index = ((ConfigManager.ReplacementStrategy.value != 0) ? Random.Range(0, list.Count) : GetDeterministicHash(targetName, list.Count));
result = CustomTextures[list[index]];
}
}
else if (ConfigManager.ReplacementStrategy.value == ReplacementStrategy.Random)
{
result = CustomTextures[Random.Range(0, CustomTextures.Count)];
}
return result;
}
private static void ReplaceTexture(Material toReplace, string assetPath)
{
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)toReplace == (Object)null) && !((Object)(object)toReplace.mainTexture == (Object)null) && CustomTextures.Count != 0)
{
if (!MatDimensions.ContainsKey(toReplace))
{
MatDimensions.Add(toReplace, new Vector2((float)toReplace.mainTexture.width, (float)toReplace.mainTexture.height));
}
float num = MatDimensions[toReplace].x / MatDimensions[toReplace].y;
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(assetPath);
CustomTexture customTexture = FindBestMatch(num, fileNameWithoutExtension);
toReplace.mainTexture = (Texture)(object)customTexture.texture;
Vector2 one = Vector2.one;
Vector2 zero = Vector2.zero;
if (customTexture.aspectRatio > num)
{
one.x = num / customTexture.aspectRatio;
zero.x = (1f - one.x) / 2f;
}
else
{
one.y = customTexture.aspectRatio / num;
zero.y = (1f - one.y) / 2f;
}
toReplace.mainTextureScale = one;
toReplace.mainTextureOffset = zero;
}
}
public static void LoadCustomImages()
{
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
CustomTextures.Clear();
string value = ConfigManager.CustomImageDir.value;
if (Directory.Exists(value))
{
string[] files = Directory.GetFiles(value, "*.*", SearchOption.AllDirectories);
foreach (string path in files)
{
switch (Path.GetExtension(path).ToLower())
{
case ".png":
case ".jpg":
case ".jpeg":
{
byte[] array = File.ReadAllBytes(path);
Texture2D val = new Texture2D(2, 2);
if (ImageConversion.LoadImage(val, array))
{
CustomTextures.Add(new CustomTexture
{
texture = val,
aspectRatio = (float)((Texture)val).width / (float)((Texture)val).height,
name = Path.GetFileNameWithoutExtension(path)
});
}
break;
}
}
}
}
if (CustomTextures.Count == 0)
{
Core.Log.LogWarning((object)("No custom images found in " + value));
}
else
{
Core.Log.LogInfo((object)$"Loaded {CustomTextures.Count} custom images");
}
}
private static void ReplaceMaterialAssets()
{
//IL_0011: 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)
for (int i = 0; i < MaterialPaths.Count; i++)
{
string text = MaterialPaths[i];
ReplaceTexture(Addressables.LoadAssetAsync<Material>((object)text).WaitForCompletion(), text);
}
}
public static void DoReplacements()
{
ReplaceMaterialAssets();
}
public static void DoReplacements(Scene scene, LoadSceneMode mode)
{
DoReplacements();
}
}
public class ExportUtils
{
private static string SafeFileName(string s)
{
return s.Replace("/", "-");
}
public static void ExportMaterialTexture(Material mat, string folderPath, string namePrefix = "")
{
//IL_0107: 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_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_0149: Expected O, but got Unknown
//IL_018f: Expected O, but got Unknown
if ((Object)(object)mat == (Object)null || (Object)(object)mat.mainTexture == (Object)null)
{
Core.Log.LogError((object)"Material or Main Texture is missing.");
return;
}
if (((Object)mat).name.StartsWith("Hidden"))
{
Core.Log.LogError((object)"Not exporting hidden material.");
return;
}
Core.Log.LogInfo((object)("Exporting material: " + ((Object)mat).name + " with mainTexture: " + ((Object)mat.mainTexture).name));
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
Texture mainTexture = mat.mainTexture;
if (mainTexture.width == 0 || mainTexture.height == 0)
{
Core.Log.LogError((object)"Texture is empty, skipping.");
return;
}
Core.Log.LogInfo((object)$"Texture size {mainTexture.width}x{mainTexture.height}");
RenderTexture temporary = RenderTexture.GetTemporary(mainTexture.width, mainTexture.height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)1);
Graphics.Blit(mainTexture, temporary);
RenderTexture active = RenderTexture.active;
RenderTexture.active = temporary;
Texture2D val = new Texture2D(mainTexture.width, mainTexture.height);
val.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0);
val.Apply();
RenderTexture.active = active;
RenderTexture.ReleaseTemporary(temporary);
byte[] bytes = ImageConversion.EncodeToPNG(val);
string path = SafeFileName(namePrefix + ((Object)mat).name + ".png");
string text = Path.Combine(folderPath, path);
File.WriteAllBytes(text, bytes);
Core.Log.LogInfo((object)("Texture exported successfully to: " + text));
Object.DestroyImmediate((Object)val);
}
public static void ExportImageToPNG(Image uiImage, string folderPath, string namePrefix = "")
{
//IL_0045: 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_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Expected O, but got Unknown
//IL_012a: Expected O, but got Unknown
if ((Object)(object)uiImage == (Object)null || (Object)(object)uiImage.sprite == (Object)null)
{
Core.Log.LogError((object)"Image component or Sprite is missing.");
return;
}
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
Sprite sprite = uiImage.sprite;
Texture2D texture = sprite.texture;
Rect rect = sprite.rect;
int num = (int)((Rect)(ref rect)).width;
rect = sprite.rect;
int num2 = (int)((Rect)(ref rect)).height;
RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)1);
Graphics.Blit((Texture)(object)texture, temporary);
RenderTexture active = RenderTexture.active;
RenderTexture.active = temporary;
Texture2D val = new Texture2D(num, num2);
rect = sprite.rect;
float x = ((Rect)(ref rect)).x;
rect = sprite.rect;
val.ReadPixels(new Rect(x, ((Rect)(ref rect)).y, (float)num, (float)num2), 0, 0);
val.Apply();
RenderTexture.active = active;
RenderTexture.ReleaseTemporary(temporary);
byte[] bytes = ImageConversion.EncodeToPNG(val);
string path = SafeFileName(namePrefix + ((Object)uiImage).name + ".png");
string text = Path.Combine(folderPath, path);
File.WriteAllBytes(text, bytes);
Core.Log.LogInfo((object)("UI Image exported to: " + text));
Object.DestroyImmediate((Object)val);
}
}
}