using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace RTLC.GWYF.TextureRuntime;
[BepInPlugin("rtlc.gwyf.texture", "RTLC.GWYF Texture Runtime", "0.3.5")]
public sealed class Plugin : BaseUnityPlugin
{
private sealed class Replacement
{
public string Name;
public string Path;
public Texture2D Texture;
public readonly HashSet<int> PatchedTextures = new HashSet<int>();
public readonly Dictionary<int, Sprite> SpriteCache = new Dictionary<int, Sprite>();
}
private readonly Dictionary<string, Replacement> _replacements = new Dictionary<string, Replacement>(StringComparer.OrdinalIgnoreCase);
private ManualLogSource _log;
private bool _loaded;
private void Awake()
{
_log = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogInfo((object)"RTLC.GWYF texture module loaded. © RTLC Team. Все права защищены.");
SceneManager.sceneLoaded += OnSceneLoaded;
((MonoBehaviour)this).StartCoroutine(LoadReplacementsAndApply());
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (_loaded)
{
((MonoBehaviour)this).StartCoroutine(ApplyDelayed("scene " + ((Scene)(ref scene)).name));
}
}
private IEnumerator LoadReplacementsAndApply()
{
string pluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
string textureDirectory = Path.Combine(pluginDirectory ?? string.Empty, "Textures");
if (!Directory.Exists(textureDirectory))
{
_log.LogWarning((object)("Texture directory does not exist: " + textureDirectory));
yield break;
}
string[] files = Directory.GetFiles(textureDirectory, "*.png", SearchOption.TopDirectoryOnly);
Array.Sort(files, (IComparer<string>?)StringComparer.OrdinalIgnoreCase);
for (int i = 0; i < files.Length; i++)
{
yield return LoadReplacement(files[i]);
}
_loaded = true;
if (_replacements.Count == 0)
{
_log.LogWarning((object)"No replacement PNG files found.");
yield break;
}
_log.LogInfo((object)("Texture replacement hooks installed. Replacement count: " + _replacements.Count));
yield return ApplyDelayed("startup");
}
private IEnumerator LoadReplacement(string path)
{
string uri = new Uri(Path.GetFullPath(path)).AbsoluteUri;
UnityWebRequest request = UnityWebRequestTexture.GetTexture(uri, false);
yield return request.SendWebRequest();
if ((int)request.result != 1)
{
_log.LogWarning((object)("Failed to load replacement PNG: " + path + " - " + request.error));
request.Dispose();
yield break;
}
Texture2D texture = DownloadHandlerTexture.GetContent(request);
request.Dispose();
if ((Object)(object)texture == (Object)null)
{
_log.LogWarning((object)("Loaded replacement PNG returned null texture: " + path));
yield break;
}
string name = Path.GetFileNameWithoutExtension(path);
((Object)texture).name = name + "_RU";
((Texture)texture).wrapMode = (TextureWrapMode)1;
((Texture)texture).filterMode = (FilterMode)1;
((Texture)texture).anisoLevel = 0;
_replacements[name] = new Replacement
{
Name = name,
Path = path,
Texture = texture
};
_log.LogDebug((object)("Loaded replacement texture: " + name + " (" + ((Texture)texture).width + "x" + ((Texture)texture).height + ") from " + path));
}
private IEnumerator ApplyDelayed(string reason)
{
ApplyReplacements(reason + " immediate");
yield return (object)new WaitForSecondsRealtime(0.25f);
ApplyReplacements(reason + " +0.25s");
yield return (object)new WaitForSecondsRealtime(1f);
ApplyReplacements(reason + " +1.25s");
}
private void ApplyReplacements(string reason)
{
int num = PatchLoadedTextures();
int num2 = PatchImages();
int num3 = PatchRawImages();
int num4 = PatchSpriteRenderers();
int num5 = PatchMaterials();
if (num > 0 || num2 > 0 || num3 > 0 || num4 > 0 || num5 > 0)
{
_log.LogDebug((object)("Applied texture replacements (" + reason + "): textures=" + num + ", images=" + num2 + ", rawImages=" + num3 + ", spriteRenderers=" + num4 + ", materials=" + num5));
}
}
private int PatchLoadedTextures()
{
int num = 0;
Texture2D[] array = Resources.FindObjectsOfTypeAll<Texture2D>();
foreach (Texture2D val in array)
{
if ((Object)(object)val == (Object)null || !_replacements.TryGetValue(((Object)val).name, out var value))
{
continue;
}
int instanceID = ((Object)val).GetInstanceID();
if (!value.PatchedTextures.Contains(instanceID) && !object.ReferenceEquals(val, value.Texture) && ((Texture)val).width == ((Texture)value.Texture).width && ((Texture)val).height == ((Texture)value.Texture).height)
{
try
{
Graphics.CopyTexture((Texture)(object)value.Texture, (Texture)(object)val);
value.PatchedTextures.Add(instanceID);
num++;
}
catch (Exception ex)
{
value.PatchedTextures.Add(instanceID);
_log.LogWarning((object)("Could not copy replacement into Texture2D " + ((Object)val).name + "; will rely on sprite/material patching. " + ex.Message));
}
}
}
return num;
}
private int PatchImages()
{
int num = 0;
Image[] array = Resources.FindObjectsOfTypeAll<Image>();
foreach (Image val in array)
{
if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null)
{
continue;
}
Replacement replacement = FindReplacementForSprite(val.sprite);
if (replacement != null)
{
Sprite replacementSprite = GetReplacementSprite(replacement, val.sprite);
if (!((Object)(object)replacementSprite == (Object)null) && !object.ReferenceEquals(val.sprite, replacementSprite))
{
val.sprite = replacementSprite;
((Graphic)val).SetAllDirty();
num++;
}
}
}
return num;
}
private int PatchRawImages()
{
int num = 0;
RawImage[] array = Resources.FindObjectsOfTypeAll<RawImage>();
foreach (RawImage val in array)
{
if (!((Object)(object)val == (Object)null) && !((Object)(object)val.texture == (Object)null) && _replacements.TryGetValue(((Object)val.texture).name, out var value) && !object.ReferenceEquals(val.texture, value.Texture))
{
val.texture = (Texture)(object)value.Texture;
((Graphic)val).SetAllDirty();
num++;
}
}
return num;
}
private int PatchSpriteRenderers()
{
int num = 0;
SpriteRenderer[] array = Resources.FindObjectsOfTypeAll<SpriteRenderer>();
foreach (SpriteRenderer val in array)
{
if ((Object)(object)val == (Object)null || (Object)(object)val.sprite == (Object)null)
{
continue;
}
Replacement replacement = FindReplacementForSprite(val.sprite);
if (replacement != null)
{
Sprite replacementSprite = GetReplacementSprite(replacement, val.sprite);
if (!((Object)(object)replacementSprite == (Object)null) && !object.ReferenceEquals(val.sprite, replacementSprite))
{
val.sprite = replacementSprite;
num++;
}
}
}
return num;
}
private int PatchMaterials()
{
int num = 0;
Renderer[] array = Resources.FindObjectsOfTypeAll<Renderer>();
foreach (Renderer val in array)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
Material[] sharedMaterials = val.sharedMaterials;
if (sharedMaterials == null)
{
continue;
}
foreach (Material val2 in sharedMaterials)
{
if (!((Object)(object)val2 == (Object)null))
{
num += PatchMaterialTextures(val2);
}
}
}
return num;
}
private int PatchMaterialTextures(Material material)
{
int num = 0;
num += PatchMaterialTexture(material, "_MainTex");
num += PatchMaterialTexture(material, "_BaseMap");
num += PatchMaterialTexture(material, "_BaseColorMap");
num += PatchMaterialTexture(material, "_UnlitColorMap");
num += PatchMaterialTexture(material, "_EmissionMap");
num += PatchMaterialTexture(material, "_DetailAlbedoMap");
string[] array;
try
{
array = material.GetTexturePropertyNames();
}
catch
{
array = null;
}
if (array != null)
{
for (int i = 0; i < array.Length; i++)
{
num += PatchMaterialTexture(material, array[i]);
}
}
return num;
}
private int PatchMaterialTexture(Material material, string propertyName)
{
if (string.IsNullOrEmpty(propertyName) || !material.HasProperty(propertyName))
{
return 0;
}
Texture texture = material.GetTexture(propertyName);
if ((Object)(object)texture == (Object)null)
{
return 0;
}
if (!_replacements.TryGetValue(((Object)texture).name, out var value))
{
return 0;
}
if (object.ReferenceEquals(texture, value.Texture))
{
return 0;
}
material.SetTexture(propertyName, (Texture)(object)value.Texture);
return 1;
}
private Replacement FindReplacementForSprite(Sprite sprite)
{
if (_replacements.TryGetValue(((Object)sprite).name, out var value))
{
return value;
}
Texture2D texture = sprite.texture;
if ((Object)(object)texture != (Object)null && _replacements.TryGetValue(((Object)texture).name, out value))
{
return value;
}
return null;
}
private Sprite GetReplacementSprite(Replacement replacement, Sprite source)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
int instanceID = ((Object)source).GetInstanceID();
if (replacement.SpriteCache.TryGetValue(instanceID, out var value))
{
return value;
}
Rect rect = source.rect;
if (((Rect)(ref rect)).xMax > (float)((Texture)replacement.Texture).width || ((Rect)(ref rect)).yMax > (float)((Texture)replacement.Texture).height)
{
((Rect)(ref rect))..ctor(0f, 0f, (float)((Texture)replacement.Texture).width, (float)((Texture)replacement.Texture).height);
}
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(0.5f, 0.5f);
Rect rect2 = source.rect;
if (((Rect)(ref rect2)).width > 0f)
{
Rect rect3 = source.rect;
if (((Rect)(ref rect3)).height > 0f)
{
float x = source.pivot.x;
Rect rect4 = source.rect;
float num = x / ((Rect)(ref rect4)).width;
float y = source.pivot.y;
Rect rect5 = source.rect;
((Vector2)(ref val))..ctor(num, y / ((Rect)(ref rect5)).height);
}
}
Sprite val2 = Sprite.Create(replacement.Texture, rect, val, source.pixelsPerUnit, 0u, (SpriteMeshType)0, source.border);
((Object)val2).name = replacement.Name;
replacement.SpriteCache[instanceID] = val2;
return val2;
}
}