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 System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using PlayerCustomizationUtils;
using PlayerCustomizationUtils.Extensions;
using RWF;
using RWF.UI;
using TMPro;
using UnboundLib;
using UnboundLib.Networking;
using UnboundLib.Utils.UI;
using UniGif;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("URLFaceItemsPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("URLFaceItemsPlus")]
[assembly: AssemblyTitle("URLFaceItemsPlus")]
[assembly: AssemblyVersion("1.1.0.0")]
namespace URLFaceItemsPlus;
public class FaceItem : MonoBehaviour
{
private static readonly Regex NameRegex = new Regex("URL_(EYES|MOUTH|DETAIL)_(\\d+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private Player player;
private SpriteRenderer spriteRenderer;
private LoadedImage image;
private int frame;
private float nextFrameTime;
private int loadToken;
private float gifSpeed = 1f;
private float opacity = 1f;
public int ItemID { get; private set; } = -1;
public CharacterItemType ItemType { get; private set; }
public string Source { get; private set; }
public bool IsCardChoiceFace { get; private set; }
private CharacterItem Item => ((Component)this).GetComponent<CharacterItem>();
private bool ReadIdentification()
{
Match match = NameRegex.Match(((Object)((Component)this).gameObject).name);
if (!match.Success)
{
Plugin.LogError("Unable to parse item name '" + ((Object)((Component)this).gameObject).name + "'.");
return false;
}
string text = match.Groups[1].Value.ToLower();
ItemType = (CharacterItemType)((!(text == "eyes")) ? ((text == "mouth") ? 1 : 2) : 0);
ItemID = int.Parse(match.Groups[2].Value);
return true;
}
private void Start()
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Expected O, but got Unknown
//IL_01de: Unknown result type (might be due to invalid IL or missing references)
//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
//IL_02b3: Expected O, but got Unknown
//IL_030e: Unknown result type (might be due to invalid IL or missing references)
spriteRenderer = ((Component)this).GetComponent<SpriteRenderer>();
if (!ReadIdentification())
{
return;
}
if ((Object)(object)((Component)this).transform.root == (Object)(object)((Component)this).transform)
{
((Component)this).transform.localScale = Vector3.zero;
((Component)this).transform.position = 1000000f * Vector3.up;
return;
}
player = ((Component)((Component)this).transform.root).GetComponent<Player>();
if ((Object)(object)player == (Object)null)
{
Transform parent = ((Component)this).transform.parent;
object obj;
if (parent == null)
{
obj = null;
}
else
{
Transform parent2 = parent.parent;
if (parent2 == null)
{
obj = null;
}
else
{
Transform parent3 = parent2.parent;
obj = ((parent3 != null) ? ((Component)parent3).GetComponent<CardChoiceVisuals>() : null);
}
}
if ((Object)obj != (Object)null && (Object)(object)CardChoice.instance != (Object)null)
{
IsCardChoiceFace = true;
player = ((IEnumerable<Player>)PlayerManager.instance.players).FirstOrDefault((Func<Player, bool>)((Player p) => p.playerID == CardChoice.instance.pickrID));
}
}
if (PhotonNetwork.OfflineMode || PhotonNetwork.CurrentRoom == null || ((Object)(object)player != (Object)null && player.data.view.IsMine))
{
ApplyLocalSettings();
return;
}
if ((Object)(object)player != (Object)null)
{
if (!FaceItemManager.RemoteItemsEnabled)
{
Hide();
return;
}
Type? typeFromHandle = typeof(FaceItem);
RaiseEventOptions val = new RaiseEventOptions();
val.TargetActors = new int[1] { player.data.view.OwnerActorNr };
NetworkingManager.RPC(typeFromHandle, "RPCS_RequestProperties", val, new object[6]
{
PhotonNetwork.LocalPlayer.ActorNumber,
ItemID,
player.playerID,
((Object)this).GetInstanceID(),
(byte)ItemType,
IsCardChoiceFace
});
return;
}
Transform parent4 = ((Component)this).transform.parent;
object obj2;
if (parent4 == null)
{
obj2 = null;
}
else
{
Transform parent5 = parent4.parent;
if (parent5 == null)
{
obj2 = null;
}
else
{
Transform parent6 = parent5.parent;
if (parent6 == null)
{
obj2 = null;
}
else
{
Transform parent7 = parent6.parent;
if (parent7 == null)
{
obj2 = null;
}
else
{
Transform parent8 = parent7.parent;
if (parent8 == null)
{
obj2 = null;
}
else
{
Transform parent9 = parent8.parent;
if (parent9 == null)
{
obj2 = null;
}
else
{
Transform obj3 = parent9.Find("PlayerName");
obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<TextMeshProUGUI>() : null);
}
}
}
}
}
}
TextMeshProUGUI val2 = (TextMeshProUGUI)obj2;
Player val3 = (((Object)(object)val2 != (Object)null) ? FindPlayerByNickname(((TMP_Text)val2).text) : null);
if (val3 == null)
{
Hide();
}
else if (val3.IsLocal)
{
ApplyLocalSettings();
}
else if (FaceItemManager.RemoteItemsEnabled)
{
Type? typeFromHandle2 = typeof(FaceItem);
RaiseEventOptions val = new RaiseEventOptions();
val.TargetActors = new int[1] { val3.ActorNumber };
NetworkingManager.RPC(typeFromHandle2, "RPCS_RequestPropertiesByInstance", val, new object[5]
{
val3.ActorNumber,
PhotonNetwork.LocalPlayer.ActorNumber,
((Object)this).GetInstanceID(),
ItemID,
(byte)ItemType
});
}
else
{
Hide();
}
}
private void Hide()
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
private void ApplyLocalSettings()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
ApplyProperties(FaceItemManager.GetURL(ItemID, ItemType), FaceItemManager.GetLook(ItemID, ItemType), -1);
}
private void ApplyProperties(string source, float[] look, int ownerActor)
{
if ((Object)(object)Item != (Object)null)
{
CharacterItemExtensions.SetScale(Item, L(0, 1f));
CharacterItemExtensions.SetMoveHealthBarUp(Item, L(1, 0f));
}
SetBrightness(L(2, 1f));
SetOpacity(L(3, 1f));
SetRotation(L(4, 0f));
SetGifSpeed(L(5, 1f));
SetImage(source, ownerActor);
float L(int i, float def)
{
if (look == null || look.Length <= i)
{
return def;
}
return look[i];
}
}
internal void SetOpacity(float value)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
opacity = Mathf.Clamp01(value);
SpriteRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SpriteRenderer>(true);
foreach (SpriteRenderer obj in componentsInChildren)
{
Color color = obj.color;
color.a = opacity;
obj.color = color;
}
}
internal void SetRotation(float degrees)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
((Component)this).transform.localEulerAngles = new Vector3(0f, 0f, degrees);
}
internal void SetGifSpeed(float speed)
{
gifSpeed = Mathf.Clamp(speed, 0.1f, 30f);
}
internal void SetImage(string source, int ownerActor = -1, bool forceRefresh = false)
{
Source = source;
int token = ++loadToken;
ImageLoader.Load(source, delegate(LoadedImage img)
{
if ((Object)(object)this != (Object)null && token == loadToken)
{
ShowImage(img);
}
}, delegate(string err)
{
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)this == (Object)null) && token == loadToken)
{
if (err == "__missing_local__" && ownerActor >= 0 && ownerActor != PhotonNetwork.LocalPlayer.ActorNumber)
{
ImageSync.Request(ownerActor, ImageStore.HashFromSource(source), delegate
{
if ((Object)(object)this != (Object)null && token == loadToken)
{
SetImage(source);
}
});
}
else if (err != "__missing_local__")
{
Plugin.Log($"{ItemType} {ItemID + 1}: {err} ({source})");
}
}
}, forceRefresh);
}
private void ShowImage(LoadedImage img)
{
image = img;
frame = 0;
nextFrameTime = Time.time + img.Delays[0] / gifSpeed;
if ((Object)(object)spriteRenderer == (Object)null)
{
spriteRenderer = ((Component)this).GetComponent<SpriteRenderer>();
}
if ((Object)(object)spriteRenderer != (Object)null)
{
spriteRenderer.sprite = img.Frames[0];
}
}
internal void SetBrightness(float brightness)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
SpriteRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SpriteRenderer>(true);
float num = default(float);
float num2 = default(float);
float num3 = default(float);
foreach (SpriteRenderer obj in componentsInChildren)
{
Color.RGBToHSV(obj.color, ref num, ref num2, ref num3);
Color color = Color.HSVToRGB(num, num2, Mathf.Clamp01(brightness));
color.a = opacity;
obj.color = color;
}
}
private void Update()
{
if (image != null && image.Animated && !(Time.time < nextFrameTime) && !((Object)(object)spriteRenderer == (Object)null))
{
int num = 0;
while (Time.time >= nextFrameTime && num < image.Frames.Length)
{
frame = (frame + 1) % image.Frames.Length;
nextFrameTime += image.Delays[frame] / gifSpeed;
num++;
}
if (nextFrameTime < Time.time)
{
nextFrameTime = Time.time + image.Delays[frame] / gifSpeed;
}
spriteRenderer.sprite = image.Frames[frame];
}
}
[UnboundRPC]
private static void RPCS_RequestProperties(int requestingActor, int itemID, int playerID, int instanceID, byte type, bool isCardChoiceFace)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
Player val = ((IEnumerable<Player>)PlayerManager.instance.players).FirstOrDefault((Func<Player, bool>)((Player x) => x.playerID == playerID));
if (!((Object)(object)val == (Object)null) && val.data.view.IsMine)
{
CharacterItemType type2 = (CharacterItemType)type;
Type? typeFromHandle = typeof(FaceItem);
RaiseEventOptions val2 = new RaiseEventOptions();
val2.TargetActors = new int[1] { requestingActor };
NetworkingManager.RPC(typeFromHandle, "RPCA_SetProperties", val2, new object[6]
{
FaceItemManager.GetURL(itemID, type2),
playerID,
instanceID,
FaceItemManager.GetLook(itemID, type2),
isCardChoiceFace,
PhotonNetwork.LocalPlayer.ActorNumber
});
}
}
[UnboundRPC]
private static void RPCS_RequestPropertiesByInstance(int ownerID, int requestingActor, int instanceID, int itemID, byte type)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
if (PhotonNetwork.LocalPlayer.ActorNumber == ownerID)
{
CharacterItemType type2 = (CharacterItemType)type;
Type? typeFromHandle = typeof(FaceItem);
RaiseEventOptions val = new RaiseEventOptions();
val.TargetActors = new int[1] { requestingActor };
NetworkingManager.RPC(typeFromHandle, "RPCA_SetPropertiesByInstance", val, new object[4]
{
FaceItemManager.GetURL(itemID, type2),
instanceID,
FaceItemManager.GetLook(itemID, type2),
ownerID
});
}
}
[UnboundRPC]
private static void RPCA_SetProperties(string url, int playerID, int instanceID, float[] look, bool isCardChoiceFace, int ownerActor)
{
object obj2;
if (!isCardChoiceFace)
{
Player? obj = ((IEnumerable<Player>)PlayerManager.instance.players).FirstOrDefault((Func<Player, bool>)((Player p) => p.playerID == playerID));
obj2 = ((obj != null) ? ((Component)obj).gameObject : null);
}
else
{
CardChoiceVisuals instance = CardChoiceVisuals.instance;
obj2 = ((instance != null) ? ((Component)instance).gameObject : null);
}
((obj2 != null) ? ((GameObject)obj2).GetComponentsInChildren<FaceItem>(true).FirstOrDefault((FaceItem i) => ((Object)i).GetInstanceID() == instanceID) : null)?.ApplyProperties(url, look, ownerActor);
}
[UnboundRPC]
private static void RPCA_SetPropertiesByInstance(string url, int instanceID, float[] look, int ownerActor)
{
Object.FindObjectsOfType<FaceItem>().FirstOrDefault((FaceItem i) => ((Object)i).GetInstanceID() == instanceID)?.ApplyProperties(url, look, ownerActor);
}
private static Player FindPlayerByNickname(string nickname)
{
if (string.IsNullOrEmpty(nickname) || PhotonNetwork.CurrentRoom == null)
{
return null;
}
Dictionary<int, Player>.ValueCollection values = PhotonNetwork.CurrentRoom.Players.Values;
for (int num = nickname.Length; num > 0; num--)
{
string candidate = nickname.Substring(0, num);
Player val = ((IEnumerable<Player>)values).FirstOrDefault((Func<Player, bool>)((Player p) => p.NickName == candidate));
if (val != null)
{
return val;
}
}
return null;
}
}
public static class FaceItemManager
{
public const int ItemsPerType = 12;
public const string DefaultURL = "https://upload.wikimedia.org/wikipedia/commons/5/50/Smile_Image.png";
public static readonly CharacterItemType[] Types = (CharacterItemType[])(object)new CharacterItemType[3]
{
default(CharacterItemType),
(CharacterItemType)1,
(CharacterItemType)2
};
private static readonly Dictionary<CharacterItemType, FaceItem[]> prefabs = new Dictionary<CharacterItemType, FaceItem[]>();
private static bool inited;
public static bool RemoteItemsEnabled
{
get
{
return PlayerPrefs.GetInt(Key("RemoteURLObjectsEnabled"), 1) == 1;
}
set
{
PlayerPrefs.SetInt(Key("RemoteURLObjectsEnabled"), value ? 1 : 0);
}
}
public static void Init()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
if (inited)
{
return;
}
inited = true;
CharacterItemType[] types = Types;
foreach (CharacterItemType val in types)
{
prefabs[val] = new FaceItem[12];
for (int j = 0; j < 12; j++)
{
GameObject val2 = new GameObject(ItemGameObjectName(j, val));
Object.DontDestroyOnLoad((Object)(object)val2);
val2.AddComponent<SpriteRenderer>();
prefabs[val][j] = val2.AddComponent<FaceItem>();
}
}
}
public static void AddItemsToCharacterCreator()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < 12; i++)
{
CharacterItemType[] types = Types;
foreach (CharacterItemType val in types)
{
CustomCharacterItemManager.AddCustomCharacterItem(((Component)prefabs[val][i]).gameObject, val, 1f, 0f, 1f);
}
}
}
public static FaceItem GetPrefab(int id, CharacterItemType type)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
if (id < 0 || id >= 12 || !prefabs.TryGetValue(type, out var value))
{
return null;
}
return value[id];
}
public static string ItemGameObjectName(int id, CharacterItemType type)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
return $"URL_{type}_{id}".ToUpper();
}
public static string TypeLabel(CharacterItemType type)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Invalid comparison between Unknown and I4
if ((int)type != 0)
{
if ((int)type != 1)
{
return "Details";
}
return "Mouths";
}
return "Eyes";
}
private static string Key(string key)
{
return "URLCharacterItems_URLItem_" + key;
}
private static string Key(int id, CharacterItemType type, string field)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
return Key($"{type}{id}{field}");
}
public static string GetURL(int id, CharacterItemType type)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return PlayerPrefs.GetString(Key(id, type, "URL"), "https://upload.wikimedia.org/wikipedia/commons/5/50/Smile_Image.png");
}
public static void SetURL(int id, CharacterItemType type, string url)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
PlayerPrefs.SetString(Key(id, type, "URL"), url);
}
public static float GetScale(int id, CharacterItemType type)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return PlayerPrefs.GetFloat(Key(id, type, "Scale"), 1f);
}
public static void SetScale(int id, CharacterItemType type, float v)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
PlayerPrefs.SetFloat(Key(id, type, "Scale"), v);
}
public static float GetBrightness(int id, CharacterItemType type)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return PlayerPrefs.GetFloat(Key(id, type, "Brightness"), 1f);
}
public static void SetBrightness(int id, CharacterItemType type, float v)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
PlayerPrefs.SetFloat(Key(id, type, "Brightness"), v);
}
public static float GetHealthBarOffset(int id, CharacterItemType type)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return PlayerPrefs.GetFloat(Key(id, type, "HealthBarOffset"), 0f);
}
public static void SetHealthBarOffset(int id, CharacterItemType type, float v)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
PlayerPrefs.SetFloat(Key(id, type, "HealthBarOffset"), v);
}
public static float GetOpacity(int id, CharacterItemType type)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return PlayerPrefs.GetFloat(Key(id, type, "Opacity"), 1f);
}
public static void SetOpacity(int id, CharacterItemType type, float v)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
PlayerPrefs.SetFloat(Key(id, type, "Opacity"), v);
}
public static float GetRotation(int id, CharacterItemType type)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return PlayerPrefs.GetFloat(Key(id, type, "Rotation"), 0f);
}
public static void SetRotation(int id, CharacterItemType type, float v)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
PlayerPrefs.SetFloat(Key(id, type, "Rotation"), v);
}
public static float GetGifSpeed(int id, CharacterItemType type)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return PlayerPrefs.GetFloat(Key(id, type, "GifSpeed"), 1f);
}
public static void SetGifSpeed(int id, CharacterItemType type, float v)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
PlayerPrefs.SetFloat(Key(id, type, "GifSpeed"), v);
}
public static float[] GetLook(int id, CharacterItemType type)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
return new float[6]
{
GetScale(id, type),
GetHealthBarOffset(id, type),
GetBrightness(id, type),
GetOpacity(id, type),
GetRotation(id, type),
GetGifSpeed(id, type)
};
}
public static string DefaultName(int id, CharacterItemType type)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
return $"{type} {id + 1}".ToUpper();
}
public static string GetName(int id, CharacterItemType type)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
string text = PlayerPrefs.GetString(Key(id, type, "Name"), "");
if (!string.IsNullOrWhiteSpace(text) && text.Length <= 32)
{
return text;
}
return DefaultName(id, type);
}
public static void SetName(int id, CharacterItemType type, string name)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
PlayerPrefs.SetString(Key(id, type, "Name"), name);
}
public static void ResetSlot(int id, CharacterItemType type)
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
string[] array = new string[8] { "URL", "Scale", "Brightness", "HealthBarOffset", "Name", "Opacity", "Rotation", "GifSpeed" };
foreach (string field in array)
{
PlayerPrefs.DeleteKey(Key(id, type, field));
}
}
}
internal static class FileDialog
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private class OpenFileName
{
public int lStructSize = Marshal.SizeOf(typeof(OpenFileName));
public IntPtr hwndOwner = IntPtr.Zero;
public IntPtr hInstance = IntPtr.Zero;
public string lpstrFilter;
public string lpstrCustomFilter;
public int nMaxCustFilter;
public int nFilterIndex;
public string lpstrFile;
public int nMaxFile;
public string lpstrFileTitle;
public int nMaxFileTitle;
public string lpstrInitialDir;
public string lpstrTitle;
public int Flags;
public short nFileOffset;
public short nFileExtension;
public string lpstrDefExt;
public IntPtr lCustData = IntPtr.Zero;
public IntPtr lpfnHook = IntPtr.Zero;
public string lpTemplateName;
public IntPtr pvReserved = IntPtr.Zero;
public int dwReserved;
public int FlagsEx;
}
private const int OFN_NOCHANGEDIR = 8;
private const int OFN_PATHMUSTEXIST = 2048;
private const int OFN_FILEMUSTEXIST = 4096;
private const int OFN_EXPLORER = 524288;
private const uint CF_UNICODETEXT = 13u;
public static bool Supported => Environment.OSVersion.Platform == PlatformID.Win32NT;
[DllImport("comdlg32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool GetOpenFileName([In][Out] OpenFileName ofn);
[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
[DllImport("user32.dll")]
private static extern bool OpenClipboard(IntPtr owner);
[DllImport("user32.dll")]
private static extern bool CloseClipboard();
[DllImport("user32.dll")]
private static extern IntPtr GetClipboardData(uint format);
[DllImport("kernel32.dll")]
private static extern IntPtr GlobalLock(IntPtr mem);
[DllImport("kernel32.dll")]
private static extern bool GlobalUnlock(IntPtr mem);
public static string ReadClipboard()
{
if (!Supported || !OpenClipboard(IntPtr.Zero))
{
return "";
}
try
{
IntPtr clipboardData = GetClipboardData(13u);
if (clipboardData == IntPtr.Zero)
{
return "";
}
IntPtr intPtr = GlobalLock(clipboardData);
if (intPtr == IntPtr.Zero)
{
return "";
}
try
{
return Marshal.PtrToStringUni(intPtr) ?? "";
}
finally
{
GlobalUnlock(clipboardData);
}
}
catch
{
return "";
}
finally
{
CloseClipboard();
}
}
public static string OpenImage()
{
if (!Supported)
{
return null;
}
OpenFileName openFileName = new OpenFileName
{
hwndOwner = GetActiveWindow(),
lpstrFilter = "Images (*.png, *.jpg, *.gif)\0*.png;*.jpg;*.jpeg;*.gif\0All files\0*.*\0\0",
lpstrFile = new string('\0', 1024),
nMaxFile = 1024,
lpstrFileTitle = new string('\0', 256),
nMaxFileTitle = 256,
lpstrInitialDir = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
lpstrTitle = "Choose an image for your character",
Flags = 530440
};
try
{
return GetOpenFileName(openFileName) ? openFileName.lpstrFile.TrimEnd(new char[1]) : null;
}
catch (Exception ex)
{
Plugin.LogError("File dialog failed: " + ex.Message);
return null;
}
}
}
public sealed class LoadedImage
{
public Sprite[] Frames;
public float[] Delays;
public int Width;
public int Height;
public string Format;
public bool Animated => Frames.Length > 1;
public string Describe()
{
if (!Animated)
{
return $"{Format}, {Width}x{Height}";
}
return $"animated GIF, {Frames.Length} frames, {Width}x{Height}";
}
}
public static class ImageLoader
{
private class Waiter
{
public Action<LoadedImage> ok;
public Action<string> fail;
}
public const string MissingLocal = "__missing_local__";
private const int MaxDownloadBytes = 16777216;
private const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36";
private const string Accept = "image/png,image/jpeg,image/gif;q=0.9,image/*;q=0.5,*/*;q=0.2";
private static readonly Dictionary<string, LoadedImage> loaded = new Dictionary<string, LoadedImage>();
private static readonly Dictionary<string, List<Waiter>> pending = new Dictionary<string, List<Waiter>>();
public static void Load(string source, Action<LoadedImage> ok, Action<string> fail, bool forceRefresh = false)
{
if (string.IsNullOrEmpty(source))
{
fail?.Invoke("No image set.");
return;
}
LoadedImage value;
if (forceRefresh)
{
loaded.Remove(source);
if (!ImageStore.IsLocal(source))
{
ImageStore.DeleteCache(source);
}
}
else if (loaded.TryGetValue(source, out value))
{
ok?.Invoke(value);
return;
}
Waiter item = new Waiter
{
ok = ok,
fail = fail
};
if (pending.TryGetValue(source, out var value2))
{
value2.Add(item);
return;
}
pending[source] = new List<Waiter> { item };
((MonoBehaviour)Plugin.instance).StartCoroutine(LoadRoutine(source));
}
private static void Finish(string source, LoadedImage img, string error)
{
if (img != null)
{
loaded[source] = img;
}
if (!pending.TryGetValue(source, out var value))
{
return;
}
pending.Remove(source);
foreach (Waiter item in value)
{
try
{
if (img != null)
{
item.ok?.Invoke(img);
}
else
{
item.fail?.Invoke(error);
}
}
catch (Exception ex)
{
Plugin.LogError(ex.ToString());
}
}
}
private static IEnumerator LoadRoutine(string source)
{
byte[] bytes = null;
bool fromWeb = false;
if (ImageStore.IsLocal(source))
{
bytes = ImageStore.ReadUpload(ImageStore.HashFromSource(source));
if (bytes == null)
{
Finish(source, null, "__missing_local__");
yield break;
}
}
else
{
bytes = ImageStore.ReadCache(source);
if (bytes == null)
{
string error = null;
yield return Download(source, delegate(byte[] b)
{
bytes = b;
}, delegate(string e)
{
error = e;
});
if (bytes == null)
{
Finish(source, null, error);
yield break;
}
fromWeb = true;
}
}
LoadedImage result = null;
string decodeError = null;
yield return Decode(bytes, delegate(LoadedImage r)
{
result = r;
}, delegate(string e)
{
decodeError = e;
});
if (result != null && fromWeb)
{
ImageStore.WriteCache(source, bytes);
}
if (result == null && !fromWeb && !ImageStore.IsLocal(source))
{
ImageStore.DeleteCache(source);
}
Finish(source, result, decodeError);
}
private static IEnumerator Download(string url, Action<byte[]> ok, Action<string> fail)
{
UnityWebRequest www = UnityWebRequest.Get(url);
try
{
www.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36");
www.SetRequestHeader("Accept", "image/png,image/jpeg,image/gif;q=0.9,image/*;q=0.5,*/*;q=0.2");
www.timeout = 20;
yield return www.SendWebRequest();
if (www.isNetworkError)
{
fail("Couldn't reach that site (" + www.error + "). Check the link or your connection.");
yield break;
}
if (www.isHttpError)
{
long responseCode = www.responseCode;
object obj;
switch (responseCode)
{
default:
obj = $"The site returned an error (HTTP {responseCode}).";
break;
case 404L:
obj = "Nothing found at that link (HTTP 404).";
break;
case 401L:
case 403L:
obj = $"That site blocks outside downloads (HTTP {responseCode}). Save the image and use UPLOAD FROM PC instead.";
break;
}
fail((string)obj);
yield break;
}
byte[] data = www.downloadHandler.data;
if (data == null || data.Length == 0)
{
fail("The link returned an empty file.");
yield break;
}
if (data.Length > 16777216)
{
fail("That image is too large (max 16 MB).");
yield break;
}
ok(data);
}
finally
{
((IDisposable)www)?.Dispose();
}
}
public static string Sniff(byte[] b)
{
if (b == null || b.Length < 12)
{
return null;
}
if (b[0] == 137 && b[1] == 80 && b[2] == 78 && b[3] == 71)
{
return "PNG";
}
if (b[0] == byte.MaxValue && b[1] == 216 && b[2] == byte.MaxValue)
{
return "JPEG";
}
if (b[0] == 71 && b[1] == 73 && b[2] == 70 && b[3] == 56)
{
return "GIF";
}
if (b[0] == 82 && b[1] == 73 && b[2] == 70 && b[3] == 70 && b[8] == 87 && b[9] == 69 && b[10] == 66 && b[11] == 80)
{
return "WEBP";
}
if (b[4] == 102 && b[5] == 116 && b[6] == 121 && b[7] == 112)
{
return "AVIF";
}
if (b[0] == 66 && b[1] == 77)
{
return "BMP";
}
int i = 0;
if (b[0] == 239 && b[1] == 187 && b[2] == 191)
{
i = 3;
}
for (; i < b.Length && i < 64 && char.IsWhiteSpace((char)b[i]); i++)
{
}
if (i < b.Length && b[i] == 60)
{
return "HTML";
}
return null;
}
public static IEnumerator Decode(byte[] bytes, Action<LoadedImage> ok, Action<string> fail)
{
string text = Sniff(bytes);
switch (text)
{
case "PNG":
case "JPEG":
{
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
if (!ImageConversion.LoadImage(val, bytes, false))
{
Object.Destroy((Object)(object)val);
fail("That file is damaged or not a supported image.");
break;
}
Prepare(val);
ok(new LoadedImage
{
Frames = (Sprite[])(object)new Sprite[1] { MakeSprite(val) },
Delays = new float[1],
Width = ((Texture)val).width,
Height = ((Texture)val).height,
Format = text
});
break;
}
case "GIF":
{
List<GifTexture> frames = null;
int w = 0;
int h = 0;
yield return UniGif.GetTextureListCoroutine(bytes, (Action<List<GifTexture>, int, int, int>)delegate(List<GifTexture> list, int loops, int width, int height)
{
frames = list;
w = width;
h = height;
}, (FilterMode)1, (TextureWrapMode)1, false);
if (frames == null || frames.Count == 0)
{
fail("Couldn't read that GIF.");
break;
}
ok(new LoadedImage
{
Frames = frames.Select((GifTexture f) => MakeSprite(f.m_texture2d)).ToArray(),
Delays = frames.Select((GifTexture f) => (!(f.m_delaySec <= 0.01f)) ? f.m_delaySec : 0.1f).ToArray(),
Width = w,
Height = h,
Format = "GIF"
});
break;
}
case "WEBP":
case "AVIF":
fail("That image is " + text + ", which ROUNDS can't display. Save it as PNG and use UPLOAD FROM PC, or find a .png/.jpg/.gif link.");
break;
case "HTML":
fail("That link is a web page, not an image. Open the image itself, right-click it and choose 'Copy image address'.");
break;
default:
fail((text == null) ? "That isn't an image file ROUNDS can read (use PNG, JPG or GIF)." : (text + " images aren't supported (use PNG, JPG or GIF)."));
break;
}
}
private static void Prepare(Texture2D tex)
{
((Texture)tex).wrapMode = (TextureWrapMode)1;
((Texture)tex).filterMode = (FilterMode)1;
tex.Apply(false, true);
}
private static Sprite MakeSprite(Texture2D tex)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
return Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
}
public static string Normalize(string raw)
{
if (raw == null)
{
return null;
}
string text = raw.Trim().Trim('"', '\'', '<', '>', ' ');
if (text.Length == 0)
{
return null;
}
if (ImageStore.IsLocal(text))
{
return text;
}
if (text.StartsWith("//"))
{
text = "https:" + text;
}
if (!text.Contains("://"))
{
text = "https://" + text;
}
if (!Uri.TryCreate(text, UriKind.Absolute, out Uri result) || (result.Scheme != "http" && result.Scheme != "https") || !result.Host.Contains("."))
{
return null;
}
string text2 = result.Host.ToLowerInvariant();
string absolutePath = result.AbsolutePath;
if (text2.Contains("google.") && (absolutePath == "/imgres" || absolutePath == "/url"))
{
string text3 = Query(result, "imgurl") ?? Query(result, "url") ?? Query(result, "q");
if (text3 != null && text3.StartsWith("http"))
{
return Normalize(text3);
}
}
if (text2.EndsWith("bing.com") && absolutePath.StartsWith("/images"))
{
string text4 = Query(result, "mediaurl");
if (text4 != null)
{
return Normalize(text4);
}
}
if ((text2 == "imgur.com" || text2 == "www.imgur.com") && !absolutePath.StartsWith("/a/") && !absolutePath.StartsWith("/gallery/"))
{
string text5 = absolutePath.Trim(new char[1] { '/' });
if (text5.Length > 0 && !text5.Contains("/"))
{
return "https://i.imgur.com/" + StripExt(text5) + ".png";
}
}
if (text2 == "i.imgur.com" && (absolutePath.EndsWith(".gifv") || absolutePath.EndsWith(".mp4") || absolutePath.EndsWith(".webm") || absolutePath.EndsWith(".webp")))
{
return "https://i.imgur.com/" + StripExt(absolutePath.Trim(new char[1] { '/' })) + ".gif";
}
if (text2.EndsWith("giphy.com"))
{
string[] array = absolutePath.Trim(new char[1] { '/' }).Split(new char[1] { '/' });
string text6 = null;
if (array.Length >= 2 && (array[0] == "gifs" || array[0] == "stickers"))
{
text6 = array[1].Split(new char[1] { '-' }).Last();
}
else if (array.Length >= 2 && array[0] == "media")
{
text6 = array[1];
}
else if (text2 == "i.giphy.com" && array.Length == 1)
{
text6 = StripExt(array[0]);
}
if (!string.IsNullOrEmpty(text6))
{
return "https://media.giphy.com/media/" + text6 + "/giphy.gif";
}
}
switch (text2)
{
case "media.discordapp.net":
case "preview.redd.it":
case "external-preview.redd.it":
if (result.Query.Contains("format=webp"))
{
return result.AbsoluteUri.Replace("format=webp", "format=png");
}
break;
}
return result.AbsoluteUri;
}
private static string StripExt(string s)
{
int num = s.LastIndexOf('.');
if (num <= 0)
{
return s;
}
return s.Substring(0, num);
}
private static string Query(Uri uri, string key)
{
string[] array = uri.Query.TrimStart(new char[1] { '?' }).Split(new char[1] { '&' });
foreach (string text in array)
{
int num = text.IndexOf('=');
if (num > 0 && string.Equals(text.Substring(0, num), key, StringComparison.OrdinalIgnoreCase))
{
return Uri.UnescapeDataString(text.Substring(num + 1).Replace('+', ' '));
}
}
return null;
}
public static byte[] DecodeDataUri(string s)
{
s = s?.Trim();
if (s == null || !s.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
{
return null;
}
int num = s.IndexOf(',');
if (num < 0 || !s.Substring(0, num).EndsWith(";base64", StringComparison.OrdinalIgnoreCase))
{
return null;
}
try
{
return Convert.FromBase64String(s.Substring(num + 1));
}
catch
{
return null;
}
}
}
public static class ImageStore
{
public const string LocalPrefix = "local:";
public const int MaxUploadBytes = 3145728;
private static readonly Regex HashRegex = new Regex("^[0-9a-f]{40}$", RegexOptions.Compiled);
private static string uploadsDir;
private static string cacheDir;
public static void Init()
{
string path = Path.Combine(Paths.ConfigPath, "URLFaceItemsPlus");
uploadsDir = Path.Combine(path, "uploads");
cacheDir = Path.Combine(path, "cache");
Directory.CreateDirectory(uploadsDir);
Directory.CreateDirectory(cacheDir);
}
public static string Sha1(byte[] bytes)
{
using SHA1 sHA = SHA1.Create();
byte[] array = sHA.ComputeHash(bytes);
StringBuilder stringBuilder = new StringBuilder(40);
byte[] array2 = array;
foreach (byte b in array2)
{
stringBuilder.Append(b.ToString("x2"));
}
return stringBuilder.ToString();
}
public static bool IsValidHash(string hash)
{
if (hash != null)
{
return HashRegex.IsMatch(hash);
}
return false;
}
public static bool IsLocal(string source)
{
return source?.StartsWith("local:", StringComparison.Ordinal) ?? false;
}
public static string HashFromSource(string source)
{
if (!IsLocal(source))
{
return null;
}
return source.Substring("local:".Length);
}
public static string SaveUpload(byte[] bytes)
{
string text = Sha1(bytes);
string path = Path.Combine(uploadsDir, text + ".img");
if (!File.Exists(path))
{
File.WriteAllBytes(path, bytes);
}
return "local:" + text;
}
public static byte[] ReadUpload(string hash)
{
if (!IsValidHash(hash))
{
return null;
}
string path = Path.Combine(uploadsDir, hash + ".img");
if (!File.Exists(path))
{
return null;
}
return File.ReadAllBytes(path);
}
public static byte[] ReadCache(string url)
{
try
{
string path = CachePath(url);
return File.Exists(path) ? File.ReadAllBytes(path) : null;
}
catch
{
return null;
}
}
public static void WriteCache(string url, byte[] bytes)
{
try
{
File.WriteAllBytes(CachePath(url), bytes);
}
catch (Exception ex)
{
Plugin.LogError("Could not write cache: " + ex.Message);
}
}
public static void DeleteCache(string url)
{
try
{
File.Delete(CachePath(url));
}
catch
{
}
}
public static int ClearCache()
{
int num = 0;
string[] files = Directory.GetFiles(cacheDir);
foreach (string path in files)
{
try
{
File.Delete(path);
num++;
}
catch
{
}
}
return num;
}
private static string CachePath(string url)
{
return Path.Combine(cacheDir, Sha1(Encoding.UTF8.GetBytes(url)) + ".img");
}
}
public static class ImageSync
{
private class Incoming
{
public byte[][] chunks;
public int received;
public float requestedAt;
public readonly List<Action> waiters = new List<Action>();
}
private const int ChunkSize = 24576;
private const int MaxChunks = 129;
private const int ChunksPerFrame = 2;
private const float RetryAfter = 20f;
private static readonly Dictionary<string, Incoming> incoming = new Dictionary<string, Incoming>();
public static void Request(int ownerActor, string hash, Action onReady)
{
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Expected O, but got Unknown
if (!ImageStore.IsValidHash(hash) || PhotonNetwork.OfflineMode || PhotonNetwork.CurrentRoom == null)
{
return;
}
if (incoming.TryGetValue(hash, out var value))
{
value.waiters.Add(onReady);
if (Time.realtimeSinceStartup - value.requestedAt < 20f)
{
return;
}
value.chunks = null;
value.received = 0;
}
else
{
value = new Incoming();
value.waiters.Add(onReady);
incoming[hash] = value;
}
value.requestedAt = Time.realtimeSinceStartup;
Type? typeFromHandle = typeof(ImageSync);
RaiseEventOptions val = new RaiseEventOptions();
val.TargetActors = new int[1] { ownerActor };
NetworkingManager.RPC(typeFromHandle, "RPCS_RequestImage", val, new object[2]
{
PhotonNetwork.LocalPlayer.ActorNumber,
hash
});
}
[UnboundRPC]
private static void RPCS_RequestImage(int requestingActor, string hash)
{
byte[] array = ImageStore.ReadUpload(hash);
if (array != null && array.Length <= 3145728)
{
((MonoBehaviour)Plugin.instance).StartCoroutine(SendChunks(requestingActor, hash, array));
}
}
private static IEnumerator SendChunks(int target, string hash, byte[] bytes)
{
int total = (bytes.Length + 24576 - 1) / 24576;
RaiseEventOptions val = new RaiseEventOptions();
val.TargetActors = new int[1] { target };
RaiseEventOptions options = val;
for (int i = 0; i < total; i++)
{
int num = Math.Min(24576, bytes.Length - i * 24576);
byte[] array = new byte[num];
Buffer.BlockCopy(bytes, i * 24576, array, 0, num);
NetworkingManager.RPC(typeof(ImageSync), "RPCA_ImageChunk", options, new object[4] { hash, i, total, array });
if ((i + 1) % 2 == 0)
{
yield return null;
}
}
}
[UnboundRPC]
private static void RPCA_ImageChunk(string hash, int index, int total, byte[] data)
{
if (!incoming.TryGetValue(hash, out var value) || total <= 0 || total > 129 || index < 0 || index >= total || data == null || data.Length > 24576)
{
return;
}
if (value.chunks == null || value.chunks.Length != total)
{
value.chunks = new byte[total][];
value.received = 0;
}
if (value.chunks[index] != null)
{
return;
}
value.chunks[index] = data;
if (++value.received < total)
{
return;
}
int num = 0;
byte[][] chunks = value.chunks;
foreach (byte[] array in chunks)
{
num += array.Length;
}
byte[] array2 = new byte[num];
int num2 = 0;
chunks = value.chunks;
foreach (byte[] array3 in chunks)
{
Buffer.BlockCopy(array3, 0, array2, num2, array3.Length);
num2 += array3.Length;
}
incoming.Remove(hash);
if (ImageStore.Sha1(array2) != hash)
{
Plugin.LogError("Received image failed its integrity check; ignoring.");
return;
}
ImageStore.SaveUpload(array2);
foreach (Action waiter in value.waiters)
{
try
{
waiter?.Invoke();
}
catch (Exception ex)
{
Plugin.LogError(ex.ToString());
}
}
}
}
internal static class OutfitSlots
{
public const int VanillaCount = 8;
public const int PageSize = 8;
public const int TotalCount = 16;
internal static bool loadingInAwake;
private static bool selectionRestored;
private static readonly MethodInfo SelectFaceMethod = AccessTools.Method(typeof(CharacterCreatorHandler), "SelectFace", (Type[])null, (Type[])null);
private static string SelectedKey(int player)
{
return $"URLFaceItemsPlus_SelectedFace{player}";
}
internal static void EnsureFaces(CharacterCreatorHandler handler)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
if (!((Object)(object)handler == (Object)null) && handler.playerFaces != null && handler.playerFaces.Length < 16)
{
int num = handler.playerFaces.Length;
PlayerFace[] array = handler.playerFaces;
Array.Resize(ref array, 16);
for (int i = num; i < 16; i++)
{
array[i] = new PlayerFace();
array[i].LoadFace(i.ToString());
}
handler.playerFaces = array;
}
}
internal static void RestoreSelection(CharacterCreatorHandler handler)
{
if (selectionRestored || (Object)(object)handler == (Object)null || handler.selectedFaceID == null || SelectFaceMethod == null)
{
return;
}
selectionRestored = true;
for (int i = 0; i < handler.selectedFaceID.Length; i++)
{
int num = PlayerPrefs.GetInt(SelectedKey(i), -1);
if (num >= 8 && num < handler.playerFaces.Length)
{
SelectFaceMethod.Invoke(handler, new object[3]
{
i,
handler.playerFaces[num],
num
});
}
}
}
internal static int SavedSelection(int player, int fallback)
{
int num = PlayerPrefs.GetInt(SelectedKey(player), -1);
if (num < 8 || num >= 16)
{
return fallback;
}
return num;
}
internal static void ExpandRowsIn(Component root)
{
if ((Object)(object)root == (Object)null)
{
return;
}
EnsureFaces(CharacterCreatorHandler.instance);
foreach (Transform item in (from p in root.GetComponentsInChildren<CharacterCreatorPortrait>(true)
select ((Component)p).transform.parent).Distinct().ToList())
{
OutfitRow.Expand(item);
}
}
internal static bool IsLobbyRow(Transform row)
{
if (!((Object)(object)((Component)row).GetComponentInParent<CharacterSelectionInstance>() != (Object)null))
{
return (Object)(object)((Component)row).GetComponentInParent<PrivateRoomCharacterSelectionInstance>() != (Object)null;
}
return true;
}
internal static void OnFaceSelected(int player, int faceID)
{
if (!loadingInAwake)
{
if (faceID >= 8)
{
PlayerPrefs.SetInt(SelectedKey(player), faceID);
PlayerPrefs.SetInt("SelectedFace" + player, 0);
}
else
{
PlayerPrefs.DeleteKey(SelectedKey(player));
}
}
}
}
[HarmonyPatch(typeof(CharacterCreatorHandler), "Awake")]
internal static class Patch_CharacterCreatorHandler_Awake
{
private static void Prefix(CharacterCreatorHandler __instance)
{
OutfitSlots.loadingInAwake = true;
OutfitSlots.EnsureFaces(__instance);
}
private static void Postfix(CharacterCreatorHandler __instance)
{
OutfitSlots.loadingInAwake = false;
OutfitSlots.RestoreSelection(__instance);
}
private static Exception Finalizer(Exception __exception)
{
OutfitSlots.loadingInAwake = false;
return __exception;
}
}
[HarmonyPatch(typeof(CharacterCreatorHandler), "SelectFace")]
internal static class Patch_CharacterCreatorHandler_SelectFace
{
private static void Postfix(int __0, int __2)
{
OutfitSlots.OnFaceSelected(__0, __2);
}
}
[HarmonyPatch(typeof(CharacterCreatorPortrait), "Start")]
internal static class Patch_CharacterCreatorPortrait_Start
{
private static void Prefix(CharacterCreatorPortrait __instance)
{
CharacterCreatorHandler instance = CharacterCreatorHandler.instance;
OutfitSlots.EnsureFaces(instance);
OutfitSlots.RestoreSelection(instance);
Transform parent = ((Component)__instance).transform.parent;
if (OutfitRow.Expand(parent) && !OutfitSlots.IsLobbyRow(parent))
{
OutfitPager.Attach(parent);
}
}
}
[HarmonyPatch(typeof(CharacterSelectionInstance), "Start")]
internal static class Patch_CharacterSelectionInstance_Start
{
[HarmonyPriority(800)]
private static void Prefix(CharacterSelectionInstance __instance)
{
OutfitSlots.ExpandRowsIn((Component)(object)__instance);
}
}
[HarmonyPatch(typeof(CharacterSelectionInstance), "StartPicking")]
internal static class Patch_CharacterSelectionInstance_StartPicking
{
[HarmonyPriority(800)]
private static void Prefix(CharacterSelectionInstance __instance)
{
OutfitSlots.ExpandRowsIn((Component)(object)__instance);
}
private static void Postfix(CharacterSelectionInstance __instance, Player pickingPlayer)
{
if ((Object)(object)pickingPlayer != (Object)null)
{
__instance.currentlySelectedFace = OutfitSlots.SavedSelection(pickingPlayer.playerID, __instance.currentlySelectedFace);
}
}
}
[HarmonyPatch(typeof(PrivateRoomCharacterSelectionInstance), "OnPhotonInstantiate")]
internal static class Patch_RWFPicker_OnPhotonInstantiate
{
[HarmonyPriority(800)]
private static void Prefix(PrivateRoomCharacterSelectionInstance __instance)
{
OutfitSlots.ExpandRowsIn((Component)(object)__instance);
}
}
[HarmonyPatch(typeof(PrivateRoomCharacterSelectionInstance), "Start")]
internal static class Patch_RWFPicker_Start
{
[HarmonyPriority(800)]
private static void Prefix(PrivateRoomCharacterSelectionInstance __instance)
{
OutfitSlots.ExpandRowsIn((Component)(object)__instance);
}
}
[HarmonyPatch(typeof(PrivateRoomCharacterSelectionInstance), "StartPicking")]
internal static class Patch_RWFPicker_StartPicking
{
[HarmonyPriority(800)]
private static void Prefix(PrivateRoomCharacterSelectionInstance __instance)
{
OutfitSlots.ExpandRowsIn((Component)(object)__instance);
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
internal static class Patch_RWFLobbyCharacter_Ctor
{
private static void Postfix(LobbyCharacter __instance)
{
__instance.faceID = OutfitSlots.SavedSelection(__instance.localID, __instance.faceID);
}
}
internal class OutfitRow : MonoBehaviour
{
[SerializeField]
private bool expanded;
internal static bool Expand(Transform row)
{
if ((Object)(object)row == (Object)null)
{
return false;
}
OutfitSlots.EnsureFaces(CharacterCreatorHandler.instance);
OutfitRow component = ((Component)row).GetComponent<OutfitRow>();
if ((Object)(object)component != (Object)null)
{
return component.expanded;
}
component = ((Component)row).gameObject.AddComponent<OutfitRow>();
int num = 0;
for (int i = 0; i < row.childCount; i++)
{
if ((Object)(object)((Component)row.GetChild(i)).GetComponent<CharacterCreatorPortrait>() != (Object)null)
{
num++;
}
}
if (num == 16 && row.childCount == 16)
{
return component.expanded = true;
}
if (num != 8 || row.childCount != 8)
{
return component.expanded = false;
}
GameObject gameObject = ((Component)row.GetChild(0)).gameObject;
for (int j = 8; j < 16; j++)
{
GameObject obj = Object.Instantiate<GameObject>(gameObject, row, false);
((Object)obj).name = ((Object)gameObject).name;
CharacterCreatorPortrait component2 = obj.GetComponent<CharacterCreatorPortrait>();
CharacterCreatorHandler instance = CharacterCreatorHandler.instance;
if ((Object)(object)component2 != (Object)null && (Object)(object)instance != (Object)null && instance.playerFaces != null && j < instance.playerFaces.Length)
{
component2.myFace = instance.GetFacePreset(j);
}
}
return component.expanded = true;
}
}
internal class OutfitPager : MonoBehaviour
{
private RectTransform left;
private RectTransform right;
private TextMeshProUGUI pageLabel;
private GameObject sharedHint;
private Transform sharedHintParent;
private Vector3 sharedHintLocalPos;
private Vector3 sharedHintOffset;
private bool sharedHintSearched;
private bool sharedHintMoved;
public int Page { get; private set; }
public int PageCount => Mathf.CeilToInt((float)((Component)this).transform.childCount / 8f);
internal static void Attach(Transform row)
{
if (!((Object)(object)row == (Object)null) && !((Object)(object)((Component)row).GetComponent<OutfitPager>() != (Object)null))
{
OutfitPager outfitPager = ((Component)row).gameObject.AddComponent<OutfitPager>();
outfitPager.BuildArrows();
int valueOrDefault = (CharacterCreatorHandler.instance?.selectedFaceID?.FirstOrDefault()).GetValueOrDefault();
outfitPager.SetPage(valueOrDefault / 8, fromUser: false);
}
}
public void SetPage(int page, bool fromUser = true)
{
Page = Mathf.Clamp(page, 0, PageCount - 1);
for (int i = 0; i < ((Component)this).transform.childCount; i++)
{
((Component)((Component)this).transform.GetChild(i)).gameObject.SetActive(i / 8 == Page);
}
if ((Object)(object)left != (Object)null)
{
((Component)left).gameObject.SetActive(Page > 0);
}
if ((Object)(object)right != (Object)null)
{
((Component)right).gameObject.SetActive(Page < PageCount - 1);
}
if ((Object)(object)pageLabel != (Object)null)
{
((TMP_Text)pageLabel).text = $"{Page + 1}/{PageCount}";
}
if (fromUser && (Object)(object)EventSystem.current != (Object)null)
{
int num = CharacterCreatorHandler.instance?.selectedFaceID?.FirstOrDefault() ?? (-1);
int num2 = ((num / 8 == Page) ? num : (Page * 8));
if (num2 >= 0 && num2 < ((Component)this).transform.childCount)
{
EventSystem.current.SetSelectedGameObject(((Component)((Component)this).transform.GetChild(num2)).gameObject);
}
}
}
private void BuildArrows()
{
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Expected O, but got Unknown
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
Transform parent = ((Component)this).transform.parent;
if (!((Object)(object)parent == (Object)null))
{
TextMeshProUGUI? obj = ((IEnumerable<TextMeshProUGUI>)((Component)((Component)this).transform.root).GetComponentsInChildren<TextMeshProUGUI>(true)).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI t) => (Object)(object)((TMP_Text)t).font != (Object)null));
TMP_FontAsset font = ((obj != null) ? ((TMP_Text)obj).font : null) ?? TMP_Settings.defaultFontAsset;
Rect rect = ((RectTransform)((Component)this).transform.GetChild(0)).rect;
float num = Mathf.Max(40f, ((Rect)(ref rect)).height * 0.6f);
left = MakeArrow("<", parent, font, num, delegate
{
SetPage(Page - 1);
});
right = MakeArrow(">", parent, font, num, delegate
{
SetPage(Page + 1);
});
GameObject val = new GameObject("URLFIP_PageLabel", new Type[1] { typeof(RectTransform) });
val.transform.SetParent(parent, false);
val.AddComponent<LayoutElement>().ignoreLayout = true;
((RectTransform)val.transform).sizeDelta = new Vector2(num * 2f, num * 0.6f);
pageLabel = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)pageLabel).font = font;
((TMP_Text)pageLabel).fontSize = num * 0.35f;
((TMP_Text)pageLabel).alignment = (TextAlignmentOptions)514;
((Graphic)pageLabel).color = new Color(1f, 1f, 1f, 0.6f);
((Graphic)pageLabel).raycastTarget = false;
}
}
private static RectTransform MakeArrow(string label, Transform holder, TMP_FontAsset font, float size, Action onClick)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Expected O, but got Unknown
//IL_0072: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: 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_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: 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_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Expected O, but got Unknown
GameObject val = new GameObject("URLFIP_Arrow" + ((label == "<") ? "Left" : "Right"), new Type[1] { typeof(RectTransform) });
val.transform.SetParent(holder, false);
val.AddComponent<LayoutElement>().ignoreLayout = true;
RectTransform val2 = (RectTransform)val.transform;
val2.sizeDelta = new Vector2(size, size);
((Graphic)val.AddComponent<Image>()).color = new Color(1f, 1f, 1f, 0.001f);
GameObject val3 = new GameObject("Text", new Type[1] { typeof(RectTransform) });
val3.transform.SetParent(val.transform, false);
RectTransform val4 = (RectTransform)val3.transform;
val4.anchorMin = Vector2.zero;
val4.anchorMax = Vector2.one;
Vector2 offsetMin = (val4.offsetMax = Vector2.zero);
val4.offsetMin = offsetMin;
TextMeshProUGUI val5 = val3.AddComponent<TextMeshProUGUI>();
((TMP_Text)val5).text = label;
((TMP_Text)val5).font = font;
((TMP_Text)val5).fontSize = size * 0.9f;
((TMP_Text)val5).alignment = (TextAlignmentOptions)514;
((Graphic)val5).raycastTarget = false;
Button obj = val.AddComponent<Button>();
((Selectable)obj).targetGraphic = (Graphic)(object)val5;
ColorBlock colors = ((Selectable)obj).colors;
((ColorBlock)(ref colors)).normalColor = new Color(1f, 1f, 1f, 0.75f);
((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.6f, 0.2f, 1f);
((ColorBlock)(ref colors)).pressedColor = new Color(1f, 0.45f, 0.1f, 1f);
((Selectable)obj).colors = colors;
((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
{
onClick();
});
return val2;
}
private static GameObject FindHintIn(Transform t, Func<Transform, bool> skip = null)
{
TextMeshProUGUI[] componentsInChildren = ((Component)t).GetComponentsInChildren<TextMeshProUGUI>(true);
foreach (TextMeshProUGUI val in componentsInChildren)
{
if ((skip == null || !skip(((TMP_Text)val).transform)) && !string.IsNullOrEmpty(((TMP_Text)val).text) && ((TMP_Text)val).text.ToUpperInvariant().Contains("EDIT"))
{
Transform parent = ((TMP_Text)val).transform.parent;
if (!((Object)(object)parent == (Object)null) && !((Object)(object)parent == (Object)(object)t) && !((Object)(object)((Component)parent).GetComponent<CharacterCreatorPortrait>() != (Object)null))
{
return ((Component)parent).gameObject;
}
return ((Component)val).gameObject;
}
}
return null;
}
private bool InsideAnyButton(Transform t)
{
for (int i = 0; i < ((Component)this).transform.childCount; i++)
{
if (t.IsChildOf(((Component)this).transform.GetChild(i)))
{
return true;
}
}
return false;
}
private void UpdateEditHint()
{
//IL_025e: Unknown result type (might be due to invalid IL or missing references)
//IL_0264: Unknown result type (might be due to invalid IL or missing references)
//IL_0269: Unknown result type (might be due to invalid IL or missing references)
//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
//IL_0215: Unknown result type (might be due to invalid IL or missing references)
//IL_021c: Unknown result type (might be due to invalid IL or missing references)
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
//IL_0203: Unknown result type (might be due to invalid IL or missing references)
//IL_0226: Unknown result type (might be due to invalid IL or missing references)
CharacterCreatorHandler instance = CharacterCreatorHandler.instance;
int num = (((Object)(object)instance != (Object)null && instance.selectedFaceID != null && instance.selectedFaceID.Length != 0) ? instance.selectedFaceID[0] : (-1));
bool flag = num >= 0 && num < ((Component)this).transform.childCount && num / 8 == Page;
if (Page > 0)
{
bool flag2 = false;
for (int i = Page * 8; i < ((Component)this).transform.childCount && i < (Page + 1) * 8; i++)
{
GameObject val = FindHintIn(((Component)this).transform.GetChild(i));
if (!((Object)(object)val == (Object)null))
{
flag2 = true;
bool flag3 = flag && i == num;
if (val.activeSelf != flag3)
{
val.SetActive(flag3);
}
}
}
if (flag2)
{
return;
}
}
if (!sharedHintSearched)
{
sharedHintSearched = true;
Transform val2 = (((Object)(object)((Component)this).transform.parent != (Object)null && (Object)(object)((Component)this).transform.parent.parent != (Object)null) ? ((Component)this).transform.parent.parent : ((Component)this).transform.parent);
sharedHint = (((Object)(object)val2 != (Object)null) ? FindHintIn(val2, InsideAnyButton) : null);
if ((Object)(object)sharedHint != (Object)null)
{
sharedHintParent = sharedHint.transform.parent;
sharedHintLocalPos = sharedHint.transform.localPosition;
Transform val3 = null;
float num2 = float.MaxValue;
for (int j = 0; j < Mathf.Min(8, ((Component)this).transform.childCount); j++)
{
float num3 = Vector3.Distance(((Component)this).transform.GetChild(j).position, sharedHint.transform.position);
if (num3 < num2)
{
num2 = num3;
val3 = ((Component)this).transform.GetChild(j);
}
}
sharedHintOffset = (((Object)(object)val3 != (Object)null) ? (sharedHint.transform.position - val3.position) : Vector3.zero);
}
}
if ((Object)(object)sharedHint == (Object)null)
{
return;
}
if (Page > 0 && flag)
{
sharedHint.transform.position = ((Component)this).transform.GetChild(num).position + sharedHintOffset;
if (!sharedHint.activeSelf)
{
sharedHint.SetActive(true);
}
sharedHintMoved = true;
}
else if (sharedHintMoved)
{
sharedHint.transform.SetParent(sharedHintParent, false);
sharedHint.transform.localPosition = sharedHintLocalPos;
sharedHintMoved = false;
}
}
private void LateUpdate()
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: 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_00c5: 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_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_018d: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
UpdateEditHint();
if ((Object)(object)left == (Object)null && (Object)(object)right == (Object)null)
{
return;
}
RectTransform val = (RectTransform)((Component)this).transform;
float num = float.MaxValue;
float num2 = float.MinValue;
float num3 = 0f;
float num4 = float.MaxValue;
int num5 = 0;
for (int i = 0; i < ((Transform)val).childCount; i++)
{
Transform child = ((Transform)val).GetChild(i);
RectTransform val2 = (RectTransform)(object)((child is RectTransform) ? child : null);
if (!((Object)(object)val2 == (Object)null) && ((Component)val2).gameObject.activeSelf)
{
Vector3 localPosition = ((Transform)val2).localPosition;
Rect rect = val2.rect;
num = Mathf.Min(num, localPosition.x + ((Rect)(ref rect)).xMin);
num2 = Mathf.Max(num2, localPosition.x + ((Rect)(ref rect)).xMax);
num3 += localPosition.y + ((Rect)(ref rect)).center.y;
num4 = Mathf.Min(num4, localPosition.y + ((Rect)(ref rect)).yMin);
num5++;
}
}
if (num5 != 0)
{
num3 /= (float)num5;
float num6 = (((Object)(object)left != (Object)null) ? (left.sizeDelta.x * 0.75f) : 40f);
if ((Object)(object)left != (Object)null)
{
((Transform)left).position = ((Transform)val).TransformPoint(new Vector3(num - num6, num3, 0f));
}
if ((Object)(object)right != (Object)null)
{
((Transform)right).position = ((Transform)val).TransformPoint(new Vector3(num2 + num6, num3, 0f));
}
if ((Object)(object)pageLabel != (Object)null)
{
((Component)pageLabel).gameObject.SetActive(PageCount > 1);
((Transform)((TMP_Text)pageLabel).rectTransform).position = ((Transform)val).TransformPoint(new Vector3((num + num2) * 0.5f, num4 - ((TMP_Text)pageLabel).rectTransform.sizeDelta.y * 0.6f, 0f));
}
}
}
private void OnDisable()
{
if ((Object)(object)left != (Object)null)
{
((Component)left).gameObject.SetActive(false);
}
if ((Object)(object)right != (Object)null)
{
((Component)right).gameObject.SetActive(false);
}
if ((Object)(object)pageLabel != (Object)null)
{
((Component)pageLabel).gameObject.SetActive(false);
}
}
private void OnEnable()
{
if (!((Object)(object)left == (Object)null))
{
((Component)left).gameObject.SetActive(Page > 0);
((Component)right).gameObject.SetActive(Page < PageCount - 1);
}
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInIncompatibility("pykess.rounds.plugins.urlcharacteritems")]
[BepInPlugin("zen.rounds.plugins.urlfaceitemsplus", "URL Face Items Plus", "1.1.0")]
[BepInProcess("Rounds.exe")]
public class Plugin : BaseUnityPlugin
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static UnityAction <>9__7_0;
internal void <Start>b__7_0()
{
}
}
public const string ModId = "zen.rounds.plugins.urlfaceitemsplus";
public const string ModName = "URL Face Items Plus";
public const string Version = "1.1.0";
public static Plugin instance;
internal static void Log(string msg)
{
Debug.Log("[URL Face Items Plus] " + msg);
}
internal static void LogError(string msg)
{
Debug.LogError("[URL Face Items Plus] " + msg);
}
private void Awake()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
instance = this;
ImageStore.Init();
new Harmony("zen.rounds.plugins.urlfaceitemsplus").PatchAll();
}
private void Start()
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Expected O, but got Unknown
Unbound.RegisterCredits("URL Face Items Plus", new string[2] { "Zen", "Pykess (original URL Face Items)" }, new string[2] { "Original mod", "Support Pykess" }, new string[2] { "https://thunderstore.io/c/rounds/p/Pykess/URL_Face_Items/", "https://ko-fi.com/pykess" });
object obj = <>c.<>9__7_0;
if (obj == null)
{
UnityAction val = delegate
{
};
<>c.<>9__7_0 = val;
obj = (object)val;
}
Unbound.RegisterMenu("URL Face Items Plus", (UnityAction)obj, (Action<GameObject>)SettingsMenu.Build, (GameObject)null, false);
FaceItemManager.Init();
FaceItemManager.AddItemsToCharacterCreator();
}
}
internal static class SettingsMenu
{
private class SlotUI
{
public int id;
public CharacterItemType type;
public TMP_InputField linkField;
public TextMeshProUGUI status;
public RectTransform previewTop;
public RectTransform previewBottom;
public bool suppress;
public void Status(string color, string msg)
{
if ((Object)(object)status != (Object)null)
{
((TMP_Text)status).text = "<color=" + color + ">" + msg + "</color>";
}
}
public void SetLinkText(string text, bool applyNow)
{
suppress = true;
if ((Object)(object)linkField != (Object)null)
{
linkField.text = Display(text);
}
suppress = false;
if (applyNow)
{
Apply(this, text, forceRefresh: false);
}
}
}
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static UnityAction <>9__6_1;
public static UnityAction<bool> <>9__6_2;
internal void <Build>b__6_1()
{
}
internal void <Build>b__6_2(bool v)
{
FaceItemManager.RemoteItemsEnabled = v;
}
}
private const string Good = "#8CE68C";
private const string Bad = "#FF7A7A";
private const string Info = "#BBBBBB";
private static readonly Dictionary<string, List<TextMeshProUGUI>> nameLabels = new Dictionary<string, List<TextMeshProUGUI>>();
private static FaceItem preview;
private static Coroutine pendingApply;
private static readonly Dictionary<string, SlotUI> slots = new Dictionary<string, SlotUI>();
private static GameObject previewRoot;
private static GameObject PreviewRoot
{
get
{
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)previewRoot == (Object)null)
{
previewRoot = Object.Instantiate<GameObject>(((Component)((Component)CharacterCreatorHandler.instance).transform.GetChild(0).GetChild(1).GetChild(0)).gameObject);
((Behaviour)((Component)previewRoot.transform.Find("PutItemsUnderHere")).GetComponent<CharacterCreatorDragging>()).enabled = false;
previewRoot.transform.position = new Vector3(0f, 2.25f, 0f);
previewRoot.AddComponent<PreviewFollower>();
Object.DontDestroyOnLoad((Object)(object)previewRoot);
}
return previewRoot;
}
}
public static void Build(GameObject menu)
{
//IL_004a: 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_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Expected O, but got Unknown
//IL_0178: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Expected O, but got Unknown
TextMeshProUGUI val = default(TextMeshProUGUI);
MenuHandler.CreateText("URL Face Items Plus".ToUpper(), menu, ref val, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
MenuHandler.CreateText("Put any image or GIF on your character", menu, ref val, 30, false, (Color?)new Color(0.75f, 0.75f, 0.75f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
MenuHandler.CreateText(" ", menu, ref val, 20, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
CharacterItemType[] types = FaceItemManager.Types;
foreach (CharacterItemType type in types)
{
string text = FaceItemManager.TypeLabel(type);
object obj = <>c.<>9__6_1;
if (obj == null)
{
UnityAction val2 = delegate
{
};
<>c.<>9__6_1 = val2;
obj = (object)val2;
}
BuildTypeMenu(MenuHandler.CreateMenu(text, (UnityAction)obj, menu, 60, true, true, ((Component)menu.transform.parent).gameObject, true, -1), type);
}
MenuHandler.CreateText(" ", menu, ref val, 20, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
bool remoteItemsEnabled = FaceItemManager.RemoteItemsEnabled;
UnityAction<bool> obj2 = delegate(bool v)
{
FaceItemManager.RemoteItemsEnabled = v;
};
TextAlignmentOptions? val3 = (TextAlignmentOptions)514;
MenuHandler.CreateToggle(remoteItemsEnabled, "Show other players' custom items", menu, obj2, 40, true, (Color?)null, (TMP_FontAsset)null, (Material)null, val3);
TextMeshProUGUI cacheInfo = null;
MenuHandler.CreateButton("Clear downloaded image cache", menu, (UnityAction)delegate
{
int num = ImageStore.ClearCache();
if ((Object)(object)cacheInfo != (Object)null)
{
((TMP_Text)cacheInfo).text = string.Format("<color={0}>Removed {1} cached download(s). They'll re-download when needed.</color>", "#BBBBBB", num);
}
}, 35, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
MenuHandler.CreateText("", menu, ref cacheInfo, 25, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
}
private static void BuildTypeMenu(GameObject menu, CharacterItemType type)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Expected O, but got Unknown
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
TextMeshProUGUI val = default(TextMeshProUGUI);
MenuHandler.CreateText(FaceItemManager.TypeLabel(type).ToUpper() + " SLOTS", menu, ref val, 50, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
MenuHandler.CreateText("After setting a slot, add it in the character customizer like any other " + FaceItemManager.TypeLabel(type).ToLower() + ".", menu, ref val, 25, false, (Color?)new Color(0.75f, 0.75f, 0.75f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
for (int i = 0; i < 12; i++)
{
int id = i;
string name = FaceItemManager.GetName(id, type);
GameObject menu2 = MenuHandler.CreateMenu(name, (UnityAction)delegate
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
OpenSlot(id, type);
}, menu, 45, true, true, ((Component)menu.transform.parent).gameObject, true, -1);
Transform obj = menu.transform.Find("Group/Grid/Scroll View/Viewport/Content") ?? menu.transform.Find("Group");
object obj2;
if (obj == null)
{
obj2 = null;
}
else
{
Transform obj3 = obj.Find(name);
obj2 = ((obj3 != null) ? ((Component)obj3).GetComponentInChildren<TextMeshProUGUI>() : null);
}
TextMeshProUGUI val2 = (TextMeshProUGUI)obj2;
if ((Object)(object)val2 != (Object)null)
{
Labels(id, type).Add(val2);
}
BuildSlotMenu(menu2, type, id);
}
}
private static List<TextMeshProUGUI> Labels(int id, CharacterItemType type)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
string key = $"{type}{id}";
if (!nameLabels.TryGetValue(key, out var value))
{
value = (nameLabels[key] = new List<TextMeshProUGUI>());
}
return value;
}
private static void BuildSlotMenu(GameObject menu, CharacterItemType type, int id)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: 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_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Expected O, but got Unknown
//IL_0222: Unknown result type (might be due to invalid IL or missing references)
//IL_0245: Expected O, but got Unknown
//IL_026e: Unknown result type (might be due to invalid IL or missing references)
//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
//IL_032a: Unknown result type (might be due to invalid IL or missing references)
//IL_0388: Unknown result type (might be due to invalid IL or missing references)
//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
//IL_0433: Unknown result type (might be due to invalid IL or missing references)
//IL_0439: Invalid comparison between Unknown and I4
//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
//IL_020f: Expected O, but got Unknown
//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
//IL_0508: Expected O, but got Unknown
//IL_0454: Unknown result type (might be due to invalid IL or missing references)
//IL_0534: Unknown result type (might be due to invalid IL or missing references)
//IL_053e: Expected O, but got Unknown
new Color(0.75f, 0.75f, 0.75f);
SlotUI slot = new SlotUI
{
id = id,
type = type
};
slots[$"{type}{id}"] = slot;
TextMeshProUGUI val = default(TextMeshProUGUI);
Labels(id, type).Add(MenuHandler.CreateText(FaceItemManager.GetName(id, type), menu, ref val, 42, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null).GetComponentInChildren<TextMeshProUGUI>());
GameObject val2 = null;
GameObject val3 = null;
for (int i = 0; i < 4; i++)
{
GameObject val4 = MenuHandler.CreateText(" ", menu, ref val, 44, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
if (i == 0)
{
val2 = val4;
}
val3 = val4;
}
slot.previewTop = val2.GetComponent<RectTransform>();
slot.previewBottom = val3.GetComponent<RectTransform>();
MenuHandler.CreateText("", menu, ref slot.status, 22, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
slot.linkField = MenuHandler.CreateInputField(Display(FaceItemManager.GetURL(id, type)), 24, menu, (UnityAction<string>)delegate(string v)
{
if (!slot.suppress)
{
if (pendingApply != null)
{
((MonoBehaviour)Plugin.instance).StopCoroutine(pendingApply);
}
pendingApply = ((MonoBehaviour)Plugin.instance).StartCoroutine(ApplyAfterTyping(slot, v));
}
}).GetComponentInChildren<TMP_InputField>();
List<GameObject> list = new List<GameObject> { MenuHandler.CreateButton("Paste link", menu, (UnityAction)delegate
{
slot.SetLinkText(FileDialog.ReadClipboard(), applyNow: true);
}, 26, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null) };
if (FileDialog.Supported)
{
list.Add(MenuHandler.CreateButton("Upload from PC", menu, (UnityAction)delegate
{
Upload(slot);
}, 26, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null));
}
list.Add(MenuHandler.CreateButton("Reload", menu, (UnityAction)delegate
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
Apply(slot, FaceItemManager.GetURL(id, type), forceRefresh: true);
}, 26, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null));
Row(list.ToArray());
Slider scaleSlider = default(Slider);
MenuHandler.CreateSlider("Size", menu, 24, 0f, 10f, FaceItemManager.GetScale(id, type), (UnityAction<float>)delegate(float v)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
FaceItemManager.SetScale(id, type, v);
if ((Object)(object)preview != (Object)null)
{
((Component)preview).transform.localScale = Vector3.one * v;
}
}, ref scaleSlider, false, (Color?)null, (Direction)0, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
Slider brightnessSlider = default(Slider);
MenuHandler.CreateSlider("Brightness", menu, 24, 0f, 1f, FaceItemManager.GetBrightness(id, type), (UnityAction<float>)delegate(float v)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
FaceItemManager.SetBrightness(id, type, v);
if ((Object)(object)preview != (Object)null)
{
preview.SetBrightness(v);
}
}, ref brightnessSlider, false, (Color?)null, (Direction)0, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
Slider opacitySlider = default(Slider);
MenuHandler.CreateSlider("Opacity", menu, 24, 0f, 1f, FaceItemManager.GetOpacity(id, type), (UnityAction<float>)delegate(float v)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
FaceItemManager.SetOpacity(id, type, v);
if ((Object)(object)preview != (Object)null)
{
preview.SetOpacity(v);
}
}, ref opacitySlider, false, (Color?)null, (Direction)0, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
Slider rotationSlider = default(Slider);
MenuHandler.CreateSlider("Rotation", menu, 24, -180f, 180f, FaceItemManager.GetRotation(id, type), (UnityAction<float>)delegate(float v)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
FaceItemManager.SetRotation(id, type, v);
if ((Object)(object)preview != (Object)null)
{
preview.SetRotation(v);
}
}, ref rotationSlider, true, (Color?)null, (Direction)0, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
Slider gifSpeedSlider = default(Slider);
MenuHandler.CreateSlider("GIF speed", menu, 24, 0.25f, 30f, FaceItemManager.GetGifSpeed(id, type), (UnityAction<float>)delegate(float v)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
FaceItemManager.SetGifSpeed(id, type, v);
if ((Object)(object)preview != (Object)null)
{
preview.SetGifSpeed(v);
}
}, ref gifSpeedSlider, false, (Color?)null, (Direction)0, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
Slider healthSlider = null;
if ((int)type == 2)
{
MenuHandler.CreateSlider("Raise health bar", menu, 24, 0f, 2f, FaceItemManager.GetHealthBarOffset(id, type), (UnityAction<float>)delegate(float v)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
FaceItemManager.SetHealthBarOffset(id, type, v);
}, ref healthSlider, false, (Color?)null, (Direction)0, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
}
TMP_InputField nameField = MenuHandler.CreateInputField(FaceItemManager.GetName(id, type), 24, menu, (UnityAction<string>)delegate(string v)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if (string.IsNullOrWhiteSpace(v) || v.Length > 32)
{
return;
}
FaceItemManager.SetName(id, type, v);
foreach (TextMeshProUGUI item in Labels(id, type))
{
if ((Object)(object)item != (Object)null)
{
((TMP_Text)item).text = v.ToUpper();
}
}
}).GetComponentInChildren<TMP_InputField>();
MenuHandler.CreateButton("Reset slot", menu, (UnityAction)delegate
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
FaceItemManager.ResetSlot(id, type);
scaleSlider.value = 1f;
brightnessSlider.value = 1f;
opacitySlider.value = 1f;
rotationSlider.value = 0f;
gifSpeedSlider.value = 1f;
if ((Object)(object)healthSlider != (Object)null)
{
healthSlider.value = 0f;
}
nameField.text = FaceItemManager.DefaultName(id, type);
slot.SetLinkText("https://upload.wikimedia.org/wikipedia/commons/5/50/Smile_Image.png", applyNow: true);
}, 24, true, (Color?)new Color(1f, 0.55f, 0.55f), (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
Transform obj = menu.transform.Find("Group/Back");
if (obj != null)
{
Button component = ((Component)obj).GetComponent<Button>();
if (component != null)
{
((UnityEvent)component.onClick).AddListener(new UnityAction(ClosePreview));
}
}
}
private static void Row(params GameObject[] items)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
if (items.Length == 0 || (Object)(object)items[0] == (Object)null)
{
return;
}
Transform parent = items[0].transform.parent;
GameObject val = new GameObject("Row", new Type[1] { typeof(RectTransform) });
val.transform.SetParent(parent, false);
val.transform.SetSiblingIndex(items[0].transform.GetSiblingIndex());
HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)obj).spacing = 20f;
((LayoutGroup)obj).childAlignment = (TextAnchor)4;
((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
float num = 0f;
foreach (GameObject val2 in items)
{
if (!((Object)(object)val2 == (Object)null))
{
num = Mathf.Max(num, LayoutUtility.GetPreferredHeight(val2.GetComponent<RectTransform>()));
val2.transform.SetParent(val.transform, false);
LayoutElement obj2 = val2.GetComponent<LayoutElement>() ?? val2.AddComponent<LayoutElement>();
obj2.flexibleWidth = 0f;
obj2.preferredWidth = 300f;
obj2.minWidth = 0f;
}
}
LayoutElement obj3 = val.AddComponent<LayoutElement>();
obj3.preferredHeight = Mathf.Max(num, 40f);
obj3.flexibleWidth = 1f;
}
private static string Display(string source)
{
if (!ImageStore.IsLocal(source))
{
return source;
}
return "(uploaded from PC)";
}
private static IEnumerator ApplyAfterTyping(SlotUI slot, string text)
{
yield return (object)new WaitForSecondsRealtime(0.6f);
pendingApply = null;
Apply(slot, text, forceRefresh: false);
}
private static void Apply(SlotUI slot, string raw, bool forceRefresh)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
if (raw == "(uploaded from PC)")
{
raw = FaceItemManager.GetURL(slot.id, slot.type);
}
byte[] array = ImageLoader.DecodeDataUri(raw);
string source;
if (array != null)
{
if (array.Length > 3145728)
{
slot.Status("#FF7A7A", "That image is too large (max 3 MB).");
return;
}
source = ImageStore.SaveUpload(array);
slot.SetLinkText(source, applyNow: false);
}
else
{
source = ImageLoader.Normalize(raw);
if (source == null)
{
slot.Status("#FF7A7A", string.IsNullOrWhiteSpace(raw) ? "Paste an image link or upload a file." : "That doesn't look like a link.");
return;
}
if (source != raw.Trim())
{
slot.SetLinkText(source, applyNow: false);
}
}
slot.Status("#BBBBBB", "Loading...");
ImageLoader.Load(source, delegate(LoadedImage img)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
FaceItemManager.SetURL(slot.id, slot.type, source);
slot.Status("#8CE68C", "Loaded: " + img.Describe());
if ((Object)(object)preview != (Object)null && preview.ItemID == slot.id && preview.ItemType == slot.type)
{
preview.SetImage(source);
}
}, delegate(string err)
{
slot.Status("#FF7A7A", (err == "__missing_local__") ? "That uploaded file is missing. Upload it again." : err);
}, forceRefresh);
}
private static void Upload(SlotUI slot)
{
string text = FileDialog.OpenImage();
if (string.IsNullOrEmpty(text))
{
return;
}
byte[] array;
try
{
array = File.ReadAllBytes(text);
}
catch (Exception ex)
{
slot.Status("#FF7A7A", "Couldn't read that file: " + ex.Message);
return;
}
if (array.Length > 3145728)
{
slot.Status("#FF7A7A", $"That file is {(float)array.Length / 1048576f:0.0} MB. Max is 3 MB so other players can receive it.");
return;
}
string text2 = ImageLoader.Sniff(array);
if (text2 != "PNG" && text2 != "JPEG" && text2 != "GIF")
{
slot.Status("#FF7A7A", (text2 == "WEBP" || text2 == "AVIF") ? (text2 + " files can't be shown in ROUNDS. Re-save it as PNG first.") : "Use a PNG, JPG or GIF file.");
}
else
{
slot.SetLinkText(ImageStore.SaveUpload(array), applyNow: true);
}
}
private static void OpenSlot(int id, CharacterItemType type)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
Transform val = PreviewRoot.transform.Find("PutItemsUnderHere");
PreviewRoot.SetActive(true);
ClearChildren(val);
preview = Object.Instantiate<GameObject>(((Component)FaceItemManager.GetPrefab(id, type)).gameObject, val).GetComponent<FaceItem>();
((Component)preview).transform.localScale = Vector3.one * FaceItemManager.GetScale(id, type);
((Component)preview).transform.localPosition = Vector3.zero;
if (slots.TryGetValue($"{type}{id}", out var slot))
{
PreviewFollower component = PreviewRoot.GetComponent<PreviewFollower>();
component.top = slot.previewTop;
component.bottom = slot.previewBottom;
string uRL = FaceItemManager.GetURL(id, type);
slot.Status("#BBBBBB", "Loading...");
ImageLoader.Load(uRL, delegate(LoadedImage img)
{
slot.Status("#8CE68C", "Loaded: " + img.Describe());
}, delegate(string err)
{
slot.Status("#FF7A7A", (err == "__missing_local__") ? "That uploaded file is missing. Upload it again." : err);
});
}
}
private static void ClosePreview()
{
if (!((Object)(object)previewRoot == (Object)null))
{
ClearChildren(previewRoot.transform.Find("PutItemsUnderHere"));
previewRoot.SetActive(false);
preview = null;
}
}
private static void ClearChildren(Transform t)
{
while (t.childCount > 0)
{
Object.DestroyImmediate((Object)(object)((Component)t.GetChild(0)).gameObject);
}
}
}
internal class PreviewFollower : MonoBehaviour
{
public RectTransform top;
public RectTransform bottom;
private void LateUpdate()
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: 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_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: 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_00b3: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: 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)
Camera main = Camera.main;
if (!((Object)(object)top == (Object)null) && !((Object)(object)bottom == (Object)null) && !((Object)(object)main == (Object)null))
{
Canvas componentInParent = ((Component)top).GetComponentInParent<Canvas>();
Camera obj = (((Object)(object)componentInParent == (Object)null || (int)componentInParent.renderMode == 0) ? null : componentInParent.worldCamera);
Vector2 val = RectTransformUtility.WorldToScreenPoint(obj, ((Transform)top).position);
Vector2 val2 = RectTransformUtility.WorldToScreenPoint(obj, ((Transform)bottom).position);
Vector2 val3 = (val + val2) * 0.5f;
float num = ((Component)this).transform.position.z - ((Component)main).transform.position.z;
Vector3 val4 = main.ScreenToWorldPoint(new Vector3(val3.x, val3.y, num));
((Component)this).transform.position = new Vector3(val4.x, val4.y, ((Component)this).transform.position.z);
}
}
}