Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Engineer Skin Pack v0.1.1
BepInEx/plugins/Local-Eclipse_Engineer_Skins_Playtest/Local-Engineer_Mine_Surveyor_Playtest/EngineerMineSurveyor.dll
Decompiled a week agousing 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.Text; using BepInEx; using EntityStates; using EntityStates.Engi.EngiWeapon; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.Projectile; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EngineerMineSurveyorPlaytest; [BepInPlugin("eclipseplaytest.engineer.e2", "Engineer - Mine Surveyor (Playtest)", "0.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EngineerMineSurveyor : BaseUnityPlugin { private sealed class Prepared { public string BodyName; public GameObject Model; public ModelSkinController Controller; public SkinDef Skin; public Mesh Mesh; public Mesh Reference; public Material Material; } private sealed class Design { public string Slug; public string Name; public Color32[] Colors; public Design(string slug, string name, Color32[] colors) { Slug = slug; Name = name; Colors = colors; } } public sealed class MineSurveyorVisuals : MonoBehaviour { private sealed class Saved { public Renderer Renderer; public Mesh Mesh; public Material[] Materials; public Bounds Bounds; public bool Offscreen; public bool ChangeMesh; public bool ChangeMaterial; public Mesh AssignedMesh; public Material[] AssignedMaterials; public bool ChangeBounds; public Bounds AssignedBounds; public bool ChangeOffscreen; public bool AssignedOffscreen; } private readonly Dictionary<Renderer, Saved> changed = new Dictionary<Renderer, Saved>(); private ModelSkinController controller; private CharacterBody body; private EntityStateMachine[] machines; private bool lobbyDirty = true; private static readonly FieldInfo Blueprint = typeof(PlaceTurret).GetField("blueprints", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo Wrist = typeof(PlaceTurret).GetField("wristDisplayObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private void Applied(int index) { if (!OwnSkin() && changed.Count > 0) { Restore(); } lobbyDirty = true; } private void Start() { controller = ((Component)this).GetComponentInChildren<ModelSkinController>(true); body = ((Component)this).GetComponentInParent<CharacterBody>(); machines = (EntityStateMachine[])(Object.op_Implicit((Object)(object)body) ? ((Array)((Component)body).GetComponents<EntityStateMachine>()) : ((Array)new EntityStateMachine[0])); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; } } private bool OwnSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length && Object.op_Implicit((Object)(object)controller.skins[currentSkinIndex])) { return ((Object)controller.skins[currentSkinIndex]).name.StartsWith("skinEclipsePlaytestEngineerE2_", StringComparison.Ordinal); } return false; } private Saved Save(Renderer r) { //IL_0074: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (changed.TryGetValue(r, out var value)) { return value; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((r is SkinnedMeshRenderer) ? r : null); MeshFilter component = ((Component)r).GetComponent<MeshFilter>(); value = new Saved { Renderer = r, Materials = r.sharedMaterials, Mesh = (Object.op_Implicit((Object)(object)val) ? val.sharedMesh : (Object.op_Implicit((Object)(object)component) ? component.sharedMesh : null)), Bounds = (Bounds)(Object.op_Implicit((Object)(object)val) ? ((Renderer)val).localBounds : default(Bounds)), Offscreen = (Object.op_Implicit((Object)(object)val) && val.updateWhenOffscreen) }; changed.Add(r, value); return value; } private void ApplySkinned(SkinnedMeshRenderer r, string asset, bool keepMaterial) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00bf: Unknown result type (might be due to invalid IL or missing references) Saved saved = Save((Renderer)(object)r); saved.ChangeMesh = true; saved.ChangeMaterial = !keepMaterial; Mesh val = (saved.AssignedMesh = instance.MeshFor(asset, r)); if ((Object)(object)r.sharedMesh != (Object)(object)val) { r.sharedMesh = val; Mesh val2 = new Mesh(); r.BakeMesh(val2); Bounds bounds = saved.Bounds; Bounds bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).min); bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).max); ((Bounds)(ref bounds)).Expand(((Bounds)(ref bounds)).size * 0.5f); ((Renderer)r).localBounds = bounds; saved.ChangeBounds = true; saved.AssignedBounds = bounds; Object.Destroy((Object)(object)val2); } r.updateWhenOffscreen = true; saved.ChangeOffscreen = true; saved.AssignedOffscreen = true; if (!keepMaterial) { ((Renderer)r).sharedMaterial = instance.prepared.Single((Prepared p) => p.BodyName == ((asset == "walker") ? "EngiWalkerTurretBody" : "EngiTurretBody")).Material; saved.AssignedMaterials = ((Renderer)r).sharedMaterials; } } private void Restore() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) foreach (Saved value in changed.Values) { if (!Object.op_Implicit((Object)(object)value.Renderer)) { continue; } Renderer renderer = value.Renderer; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); MeshFilter component = ((Component)value.Renderer).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)val)) { if (value.ChangeMesh && (Object)(object)val.sharedMesh == (Object)(object)value.AssignedMesh) { if (value.ChangeBounds && ((Renderer)val).localBounds == value.AssignedBounds) { ((Renderer)val).localBounds = value.Bounds; } if (value.ChangeOffscreen && val.updateWhenOffscreen == value.AssignedOffscreen) { val.updateWhenOffscreen = value.Offscreen; } val.sharedMesh = value.Mesh; } } else if (Object.op_Implicit((Object)(object)component) && value.ChangeMesh && (Object)(object)component.sharedMesh == (Object)(object)value.AssignedMesh) { component.sharedMesh = value.Mesh; } if (value.ChangeMaterial && value.AssignedMaterials != null && value.Renderer.sharedMaterials.SequenceEqual(value.AssignedMaterials)) { value.Renderer.sharedMaterials = value.Materials; } } changed.Clear(); } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)instance) || !instance.registered) { return; } Renderer[] array = changed.Keys.Where((Renderer r) => !Object.op_Implicit((Object)(object)r)).ToArray(); foreach (Renderer key in array) { changed.Remove(key); } if (!OwnSkin()) { if (changed.Count > 0) { Restore(); } lobbyDirty = true; return; } if (!Object.op_Implicit((Object)(object)body)) { if (!lobbyDirty) { return; } lobbyDirty = false; SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if (val.bones.Length == 15 && Object.op_Implicit((Object)(object)((Component)this).transform.Find("TurretHolder")) && ((Component)val).transform.IsChildOf(((Component)this).transform.Find("TurretHolder"))) { ApplySkinned(val, "turret", keepMaterial: false); } else if (((Object)val).name.IndexOf("Mine", StringComparison.OrdinalIgnoreCase) >= 0) { Saved saved = Save((Renderer)(object)val); saved.ChangeMaterial = true; ((Renderer)val).sharedMaterials = instance.PaintMine(saved.Materials); saved.AssignedMaterials = ((Renderer)val).sharedMaterials; } } MeshRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren2) { if (((Object)val2).name == "EngiMineMesh") { Saved saved2 = Save((Renderer)(object)val2); saved2.ChangeMaterial = true; ((Renderer)val2).sharedMaterials = instance.PaintMine(saved2.Materials); saved2.AssignedMaterials = ((Renderer)val2).sharedMaterials; } } return; } EntityStateMachine[] array2 = machines; for (int num = 0; num < array2.Length; num++) { EntityState state = array2[num].state; PlaceTurret val3 = (PlaceTurret)(object)((state is PlaceTurret) ? state : null); if (val3 == null) { continue; } string asset = ((val3 is PlaceWalkerTurret) ? "walker" : "turret"); object? obj = Blueprint?.GetValue(val3); BlueprintController val4 = (BlueprintController)((obj is BlueprintController) ? obj : null); if (Object.op_Implicit((Object)(object)val4)) { SkinnedMeshRenderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val5 in componentsInChildren) { if (val5.bones.Length == 15) { ApplySkinned(val5, asset, keepMaterial: true); } } } object? obj2 = Wrist?.GetValue(val3); GameObject val6 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (!Object.op_Implicit((Object)(object)val6)) { continue; } MeshFilter[] componentsInChildren3 = val6.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val7 in componentsInChildren3) { if (((Object)val7).name == "EngiTurretMesh") { Renderer component = ((Component)val7).GetComponent<Renderer>(); Saved saved3 = Save(component); saved3.ChangeMesh = true; val7.sharedMesh = instance.WristMesh(asset); saved3.AssignedMesh = val7.sharedMesh; } } } } private void OnDisable() { Restore(); lobbyDirty = true; } private void OnDestroy() { if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } } } public const string Guid = "eclipseplaytest.engineer.e2"; public const string Version = "0.1.2"; private static EngineerMineSurveyor instance; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private float registrationDeadline; private string folder; private SkinDef skin; private GameObject modelPrefab; private readonly List<Prepared> prepared = new List<Prepared>(); private bool registered; private static readonly Design[] Designs = new Design[1] { new Design("mine-surveyor", "Mine Surveyor (Playtest)", (Color32[])(object)new Color32[4] { new Color32((byte)214, (byte)160, (byte)48, byte.MaxValue), new Color32((byte)223, (byte)211, (byte)175, byte.MaxValue), new Color32((byte)91, (byte)93, (byte)82, byte.MaxValue), new Color32((byte)47, (byte)53, (byte)49, byte.MaxValue) }) }; private GameObject cosmeticStorage; private Texture2D minePaint; private readonly Dictionary<string, Mesh> remappedMeshes = new Dictionary<string, Mesh>(); private readonly Dictionary<Material, Material> mineMaterials = new Dictionary<Material, Material>(); private readonly Dictionary<string, Mesh> wristMeshes = new Dictionary<string, Mesh>(); private void Awake() { folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); instance = this; SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(EngineerMineSurveyor)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; } [SystemInitializer(new Type[] { typeof(BodyCatalog) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { yield break; } instance.registrationDeadline = Time.realtimeSinceStartup + 45f; IEnumerator routine = instance.RegisterAsync(); while (true) { bool flag; try { flag = routine.MoveNext(); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E2_REGISTRATION_FAILED: " + ex)); break; } if (!flag) { break; } yield return null; } (routine as IDisposable)?.Dispose(); } private IEnumerator RegisterAsync() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E2_REGISTRATION_BEGIN 0.1.2"); string[][] array = new string[3][] { new string[4] { "EngiTurretBody", "turret", "15", "skinEngiTurretDefault" }, new string[4] { "EngiWalkerTurretBody", "walker", "15", "skinEngiWalkerTurretDefault" }, new string[4] { "EngiBody", "mine-surveyor", "83", "skinEngiDefault" } }; foreach (string[] array2 in array) { IEnumerator routine = Prepare(array2[0], array2[1], int.Parse(array2[2]), array2[3]); while (routine.MoveNext()) { yield return null; } } Prepared bodySkin = prepared.Single((Prepared p) => p.BodyName == "EngiBody"); bodySkin.Skin.skinDefParams.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[2] { new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiTurretBody"), minionSkin = prepared.Single((Prepared p) => p.BodyName == "EngiTurretBody").Skin }, new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiWalkerTurretBody"), minionSkin = prepared.Single((Prepared p) => p.BodyName == "EngiWalkerTurretBody").Skin } }; IEnumerator ghostRoutine = PrepareMineGhosts(bodySkin.Skin); while (ghostRoutine.MoveNext()) { yield return null; } foreach (Prepared item in prepared) { item.Controller.skins = item.Controller.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { item.Skin }).ToArray(); } modelPrefab = bodySkin.Model; skin = bodySkin.Skin; registered = true; foreach (Prepared item2 in prepared) { if (!Object.op_Implicit((Object)(object)item2.Model.GetComponent<MineSurveyorVisuals>())) { item2.Model.AddComponent<MineSurveyorVisuals>(); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E2_REGISTERED Mine Surveyor, both turret variants, unlocked=true version=0.1.2"); } private IEnumerator Prepare(string bodyName, string assetName, int boneCount, string defaultName) { GameObject val = BodyCatalog.FindBodyPrefab(bodyName); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing body " + bodyName); } GameObject model = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = model.GetComponent<ModelSkinController>(); SkinDef baseSkin = null; if (Object.op_Implicit((Object)(object)controller) && controller.skins != null && controller.skins.Length != 0) { baseSkin = controller.skins[0]; } if (!Object.op_Implicit((Object)(object)baseSkin)) { AsyncOperationHandle<SkinDef> h = Addressables.LoadAssetAsync<SkinDef>((object)("RoR2/Base/Engi/" + defaultName + ".asset")); retainedAssets.Add(AsyncOperationHandle<SkinDef>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline("default skin " + bodyName); yield return null; } baseSkin = h.Result; } if (!Object.op_Implicit((Object)(object)baseSkin)) { throw new InvalidOperationException("Missing default skin " + bodyName); } SkinDefParams bp = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)bp) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> h2 = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(h2)); while (!h2.IsDone) { CheckLoadDeadline("parameters " + bodyName); yield return null; } bp = h2.Result; } if (!Object.op_Implicit((Object)(object)bp)) { throw new InvalidOperationException("Missing parameters " + bodyName); } SkinnedMeshRenderer target = model.GetComponentsInChildren<SkinnedMeshRenderer>(true).Single((SkinnedMeshRenderer r) => r.bones.Length == boneCount); Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = bp.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference)) { AsyncOperationHandle<Mesh> h3 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(h3)); while (!h3.IsDone) { CheckLoadDeadline("mesh " + bodyName); yield return null; } reference = h3.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != target.bones.Length) { throw new InvalidOperationException("Bind pose mismatch " + bodyName); } RendererInfo ri = bp.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = ri.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && ri.defaultMaterialAddress != null && ((AssetReference)ri.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> h4 = Addressables.LoadAssetAsync<Material>(((AssetReference)ri.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(h4)); while (!h4.IsDone) { CheckLoadDeadline("material " + bodyName); yield return null; } val3 = h4.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Missing native material " + bodyName); } Mesh val4 = ReadMesh(Path.Combine(folder, assetName + ".meshbin"), target, reference); ((Object)val4).name = "EclipsePlaytest_EngineerE2_" + assetName; Material val5 = new Material(val3) { name = "matEclipsePlaytest_EngineerE2_" + assetName }; val5.SetTexture("_MainTex", (Texture)(object)ReadTexture("albedo-spec.png", linear: false)); val5.SetTexture("_NormalTex", (Texture)(object)ReadTexture("normal.png", linear: true)); val5.SetColor("_Color", Color.white); val5.SetFloat("_NormalStrength", 0.3f); val5.SetFloat("_Smoothness", 0.28f); val5.SetFloat("_SpecularStrength", 0.35f); val5.SetFloat("_SpecularExponent", 8f); val5.SetFloat("_EmPower", 0f); val5.SetTexture("_EmTex", (Texture)(object)Texture2D.blackTexture); val5.DisableKeyword("LIMBREMOVAL"); val5.SetFloat("_LimbRemovalOn", 0f); ri.defaultMaterial = val5; ri.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { ri }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = val4, meshAddress = new AssetReferenceT<Mesh>("") } }; SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>(); ((Object)val7).name = "skinEclipsePlaytestEngineerE2_" + assetName; val7.nameToken = "ECLIPSEPLAYTEST_ENGINEER_E2_" + assetName.ToUpperInvariant().Replace('-', '_'); LanguageAPI.Add(val7.nameToken, (bodyName == "EngiBody") ? "Mine Surveyor (Playtest)" : ("Mine Surveyor " + assetName)); val7.icon = CreateIcon(Designs[0].Colors); val7.unlockableDef = null; val7.rootObject = model; val7.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; val7.skinDefParams = val6; if (!Object.op_Implicit((Object)(object)controller)) { controller = model.AddComponent<ModelSkinController>(); controller.skins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; } prepared.Add(new Prepared { BodyName = bodyName, Model = model, Controller = controller, Skin = val7, Mesh = val4, Reference = reference, Material = val5 }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E2_PREPARED body=" + bodyName + " vertices=" + val4.vertexCount + " unlocked=true")); } private static Sprite CreateIcon(Color32[] colors) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00c6: 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_0083: 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_0071: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : colors[num]); } } val.SetPixels32(array); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private void CheckLoadDeadline(string asset) { if (Time.realtimeSinceStartup > registrationDeadline) { throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin."); } } private void SyncDisplaySkins() { if (!registered) { return; } SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "EngiBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)val.displayPrefab.GetComponent<MineSurveyorVisuals>())) { val.displayPrefab.AddComponent<MineSurveyorVisuals>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E2_DISPLAY_READY skins=" + val2.skins.Length)); } } private Texture2D ReadTexture(string name, bool linear) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0037: Expected O, but got Unknown //IL_004b: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear) { name = name, anisoLevel = 4, filterMode = (FilterMode)2 }; if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(folder, name)), false)) { throw new InvalidDataException("Cannot decode " + name); } return val; } private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_0400: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (new string(binaryReader.ReadChars(4)) != "PWE2") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0 || !hashSet.Add(array[i])) { throw new InvalidDataException("Missing/duplicate reference bone: " + name); } } Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num3]; for (int num5 = 0; num5 < num3; num5++) { Matrix4x4 val = default(Matrix4x4); for (int num6 = 0; num6 < 4; num6++) { for (int num7 = 0; num7 < 4; num7++) { float num8 = binaryReader.ReadSingle(); if (float.IsNaN(num8) || float.IsInfinity(num8)) { throw new InvalidDataException("Invalid bind matrix."); } ((Matrix4x4)(ref val))[num6, num7] = num8; } } if (Math.Abs(((Matrix4x4)(ref val)).determinant) < 1E-05f) { throw new InvalidDataException("Singular bind matrix."); } array2[array[num5]] = val; } Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector3[] array4 = (Vector3[])(object)new Vector3[num]; Vector2[] array5 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array6 = (BoneWeight[])(object)new BoneWeight[num]; for (int num9 = 0; num9 < num; num9++) { array3[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array5[num9] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); int[] array7 = new int[4]; for (int num10 = 0; num10 < 4; num10++) { int num11 = binaryReader.ReadInt32(); if (num11 < 0 || num11 >= num3) { throw new InvalidDataException("Bone out of range."); } array7[num10] = array[num11]; } float[] array8 = new float[4]; for (int num12 = 0; num12 < 4; num12++) { array8[num12] = binaryReader.ReadSingle(); } if (array8.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array8.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } if (!Finite(array3[num9]) || !Finite(array4[num9])) { throw new InvalidDataException("Non-finite vertex."); } int num13 = num9; BoneWeight val2 = default(BoneWeight); ((BoneWeight)(ref val2)).boneIndex0 = array7[0]; ((BoneWeight)(ref val2)).boneIndex1 = array7[1]; ((BoneWeight)(ref val2)).boneIndex2 = array7[2]; ((BoneWeight)(ref val2)).boneIndex3 = array7[3]; ((BoneWeight)(ref val2)).weight0 = array8[0]; ((BoneWeight)(ref val2)).weight1 = array8[1]; ((BoneWeight)(ref val2)).weight2 = array8[2]; ((BoneWeight)(ref val2)).weight3 = array8[3]; array6[num13] = val2; } int[] array9 = new int[num2]; for (int num14 = 0; num14 < num2; num14++) { array9[num14] = binaryReader.ReadInt32(); if (array9[num14] < 0 || array9[num14] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } Mesh val3 = new Mesh { name = "EclipsePlaytestEngineerMineSurveyor", indexFormat = (IndexFormat)(num > 65535), vertices = array3, normals = array4, uv = array5, boneWeights = array6, bindposes = array2, triangles = array9 }; val3.RecalculateBounds(); val3.RecalculateTangents(); return val3; } private IEnumerator PrepareMineGhosts(SkinDef bodySkin) { cosmeticStorage = new GameObject("MineSurveyorCosmeticPrefabs"); cosmeticStorage.SetActive(false); Object.DontDestroyOnLoad((Object)(object)cosmeticStorage); minePaint = new Texture2D(2, 2, (TextureFormat)4, false); minePaint.SetPixels(Enumerable.Repeat<Color>(new Color(0.65f, 0.39f, 0.07f, 0.2f), 4).ToArray()); minePaint.Apply(); List<ProjectileGhostReplacement> replacements = new List<ProjectileGhostReplacement>(); string[] array = new string[2] { "EngiMine", "SpiderMine" }; foreach (string name in array) { AsyncOperationHandle<GameObject> h = Addressables.LoadAssetAsync<GameObject>((object)("RoR2/Base/Engi/" + name + ".prefab")); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline(name); yield return null; } if (!Object.op_Implicit((Object)(object)h.Result)) { throw new InvalidOperationException("Missing mine projectile " + name); } ProjectileController component = h.Result.GetComponent<ProjectileController>(); GameObject val = component.ghostPrefab; if (!Object.op_Implicit((Object)(object)val) && component.ghostPrefabAddress != null && ((AssetReference)component.ghostPrefabAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<GameObject> gh = Addressables.LoadAssetAsync<GameObject>(((AssetReference)component.ghostPrefabAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(gh)); while (!gh.IsDone) { CheckLoadDeadline(name + " ghost"); yield return null; } val = gh.Result; } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing mine ghost " + name); } GameObject val2 = Object.Instantiate<GameObject>(val, cosmeticStorage.transform); ((Object)val2).name = "EclipseMineSurveyor_" + name + "Ghost"; val2.SetActive(true); SkinnedMeshRenderer[] componentsInChildren = val2.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val3 in componentsInChildren) { ((Renderer)val3).sharedMaterials = PaintMine(((Renderer)val3).sharedMaterials); } replacements.Add(new ProjectileGhostReplacement { projectilePrefab = h.Result, projectileGhostReplacementPrefab = val2, ghostReplacementAddress = new AssetReferenceT<GameObject>("") }); } bodySkin.skinDefParams.projectileGhostReplacements = replacements.ToArray(); } private Material[] PaintMine(Material[] sources) { return ((IEnumerable<Material>)sources).Select((Func<Material, Material>)delegate(Material src) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)src)) { return src; } if (mineMaterials.TryGetValue(src, out var value)) { return value; } value = new Material(src) { name = "MineSurveyorMine_" + ((Object)src).name }; value.SetTexture("_MainTex", (Texture)(object)minePaint); value.SetColor("_Color", Color.white); value.SetFloat("_Smoothness", 0.25f); value.SetFloat("_SpecularStrength", 0.3f); mineMaterials.Add(src, value); return value; }).ToArray(); } private Mesh MeshFor(string asset, SkinnedMeshRenderer target) { string key = asset + "|" + string.Join("|", target.bones.Select((Transform b) => (!Object.op_Implicit((Object)(object)b)) ? "<null>" : ((Object)b).name)); if (!remappedMeshes.TryGetValue(key, out var value)) { value = ReadMesh(Path.Combine(folder, asset + ".meshbin"), target, target.sharedMesh); remappedMeshes.Add(key, value); } return value; } private Mesh WristMesh(string asset) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: 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_0103: Unknown result type (might be due to invalid IL or missing references) if (wristMeshes.TryGetValue(asset, out var value)) { return value; } Prepared prepared = this.prepared.Single((Prepared p) => p.BodyName == ((asset == "walker") ? "EngiWalkerTurretBody" : "EngiTurretBody")); prepared.Model.GetComponentsInChildren<SkinnedMeshRenderer>(true).Single((SkinnedMeshRenderer x) => x.bones.Length == 15); Matrix4x4 val = ((Matrix4x4)(ref prepared.Reference.bindposes[0])).inverse * prepared.Mesh.bindposes[0]; value = Object.Instantiate<Mesh>(prepared.Mesh); Vector3[] vertices = value.vertices; Vector3[] normals = value.normals; Matrix4x4 inverse = ((Matrix4x4)(ref val)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int num = 0; num < vertices.Length; num++) { vertices[num] = ((Matrix4x4)(ref val)).MultiplyPoint3x4(vertices[num]); int num2 = num; Vector3 val2 = ((Matrix4x4)(ref transpose)).MultiplyVector(normals[num]); normals[num2] = ((Vector3)(ref val2)).normalized; } value.vertices = vertices; value.normals = normals; value.RecalculateBounds(); value.RecalculateTangents(); wristMeshes.Add(asset, value); return value; } private static bool Finite(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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_0028: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(v.x + v.y + v.z)) { return !float.IsInfinity(v.x + v.y + v.z); } return false; } }
BepInEx/plugins/Local-Eclipse_Engineer_Skins_Playtest/Local-Engineer_Union_Builder_Playtest/EngineerUnionBuilder.dll
Decompiled a week agousing 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.Text; using BepInEx; using EntityStates; using EntityStates.Engi.EngiWeapon; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.Projectile; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EngineerUnionBuilderPlaytest; [BepInPlugin("eclipseplaytest.engineer.e1", "Engineer - Union Builder (Playtest)", "0.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EngineerUnionBuilder : BaseUnityPlugin { private sealed class Prepared { public SkinDef[] OriginalSkins; public SkinDef[] CommittedSkins; public string BodyName; public GameObject Model; public ModelSkinController Controller; public SkinDef Skin; public Mesh Mesh; public Mesh Reference; public Material Material; } private sealed class Design { public string Slug; public string Name; public Color32[] Colors; public Design(string slug, string name, Color32[] colors) { Slug = slug; Name = name; Colors = colors; } } private sealed class MeshBasis { public Mesh Reference; public Mesh Authored; } public sealed class UnionVisuals : MonoBehaviour { private sealed class Saved { public Renderer Renderer; public Mesh Mesh; public Material[] Materials; public Bounds Bounds; public bool Offscreen; public bool ChangeMesh; public bool ChangeMaterial; public Mesh AssignedMesh; public Material[] AssignedMaterials; public bool ChangeBounds; public Bounds AssignedBounds; public bool ChangeOffscreen; public bool AssignedOffscreen; } private readonly Dictionary<Renderer, Saved> changed = new Dictionary<Renderer, Saved>(); private ModelSkinController controller; private CharacterBody body; private EntityStateMachine[] machines; private bool lobbyDirty = true; private static readonly FieldInfo Blueprint = typeof(PlaceTurret).GetField("blueprints", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo Wrist = typeof(PlaceTurret).GetField("wristDisplayObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private void Applied(int index) { if (!OwnSkin() && changed.Count > 0) { Restore(); } lobbyDirty = true; } private void Start() { controller = ((Component)this).GetComponentInChildren<ModelSkinController>(true); body = ((Component)this).GetComponentInParent<CharacterBody>(); machines = (EntityStateMachine[])(Object.op_Implicit((Object)(object)body) ? ((Array)((Component)body).GetComponents<EntityStateMachine>()) : ((Array)new EntityStateMachine[0])); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; } } private bool OwnSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length && Object.op_Implicit((Object)(object)controller.skins[currentSkinIndex])) { return ((Object)controller.skins[currentSkinIndex]).name.StartsWith("skinEclipsePlaytestEngineerE1_", StringComparison.Ordinal); } return false; } private Saved Save(Renderer r) { //IL_0074: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (changed.TryGetValue(r, out var value)) { return value; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((r is SkinnedMeshRenderer) ? r : null); MeshFilter component = ((Component)r).GetComponent<MeshFilter>(); value = new Saved { Renderer = r, Materials = r.sharedMaterials, Mesh = (Object.op_Implicit((Object)(object)val) ? val.sharedMesh : (Object.op_Implicit((Object)(object)component) ? component.sharedMesh : null)), Bounds = (Bounds)(Object.op_Implicit((Object)(object)val) ? ((Renderer)val).localBounds : default(Bounds)), Offscreen = (Object.op_Implicit((Object)(object)val) && val.updateWhenOffscreen) }; changed.Add(r, value); return value; } private void ApplySkinned(SkinnedMeshRenderer r, string asset, bool keepMaterial) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) Saved saved = Save((Renderer)(object)r); saved.ChangeMesh = true; saved.ChangeMaterial = !keepMaterial; Mesh val = (saved.AssignedMesh = instance.MeshFor(asset, r, saved.Mesh)); if ((Object)(object)r.sharedMesh != (Object)(object)val) { r.sharedMesh = val; Mesh val2 = new Mesh(); r.BakeMesh(val2); Bounds bounds = saved.Bounds; Bounds bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).min); bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).max); ((Bounds)(ref bounds)).Expand(((Bounds)(ref bounds)).size * 0.5f); ((Renderer)r).localBounds = bounds; saved.ChangeBounds = true; saved.AssignedBounds = bounds; Object.Destroy((Object)(object)val2); } r.updateWhenOffscreen = true; saved.ChangeOffscreen = true; saved.AssignedOffscreen = true; if (!keepMaterial) { ((Renderer)r).sharedMaterial = instance.assetMaterials[asset]; saved.AssignedMaterials = ((Renderer)r).sharedMaterials; } } private void Restore() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) foreach (Saved value in changed.Values) { if (!Object.op_Implicit((Object)(object)value.Renderer)) { continue; } Renderer renderer = value.Renderer; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); MeshFilter component = ((Component)value.Renderer).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)val)) { if (value.ChangeMesh && (Object)(object)val.sharedMesh == (Object)(object)value.AssignedMesh) { if (value.ChangeBounds && ((Renderer)val).localBounds == value.AssignedBounds) { ((Renderer)val).localBounds = value.Bounds; } if (value.ChangeOffscreen && val.updateWhenOffscreen == value.AssignedOffscreen) { val.updateWhenOffscreen = value.Offscreen; } val.sharedMesh = value.Mesh; } } else if (Object.op_Implicit((Object)(object)component) && value.ChangeMesh && (Object)(object)component.sharedMesh == (Object)(object)value.AssignedMesh) { component.sharedMesh = value.Mesh; } if (value.ChangeMaterial && value.AssignedMaterials != null && value.Renderer.sharedMaterials.SequenceEqual(value.AssignedMaterials)) { value.Renderer.sharedMaterials = value.Materials; } } changed.Clear(); } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)instance) || !instance.registered) { return; } Renderer[] array = changed.Keys.Where((Renderer r) => !Object.op_Implicit((Object)(object)r)).ToArray(); foreach (Renderer key in array) { changed.Remove(key); } if (!OwnSkin()) { if (changed.Count > 0) { Restore(); } lobbyDirty = true; return; } if (lobbyDirty) { SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { string text = MineAsset((Renderer)(object)val); if (text != null) { ApplySkinned(val, text, keepMaterial: false); } else if (!Object.op_Implicit((Object)(object)body) && val.bones.Length == 15 && Object.op_Implicit((Object)(object)((Component)this).transform.Find("TurretHolder")) && ((Component)val).transform.IsChildOf(((Component)this).transform.Find("TurretHolder"))) { ApplySkinned(val, "turret", keepMaterial: false); } } MeshRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren2) { string text2 = MineAsset((Renderer)(object)val2); if (text2 != null) { MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)component)) { Saved saved = Save((Renderer)(object)val2); saved.ChangeMesh = true; component.sharedMesh = instance.StaticMeshFor(text2, saved.Mesh); saved.AssignedMesh = component.sharedMesh; saved.ChangeMaterial = true; ((Renderer)val2).sharedMaterial = instance.assetMaterials[text2]; saved.AssignedMaterials = ((Renderer)val2).sharedMaterials; } } } lobbyDirty = false; } if (!Object.op_Implicit((Object)(object)body)) { return; } EntityStateMachine[] array2 = machines; for (int num = 0; num < array2.Length; num++) { EntityState state = array2[num].state; PlaceTurret val3 = (PlaceTurret)(object)((state is PlaceTurret) ? state : null); if (val3 == null) { continue; } string asset = ((val3 is PlaceWalkerTurret) ? "walker" : "turret"); object? obj = Blueprint?.GetValue(val3); BlueprintController val4 = (BlueprintController)((obj is BlueprintController) ? obj : null); if (Object.op_Implicit((Object)(object)val4)) { SkinnedMeshRenderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val5 in componentsInChildren) { if (val5.bones.Length == 15) { ApplySkinned(val5, asset, keepMaterial: true); } } } object? obj2 = Wrist?.GetValue(val3); GameObject val6 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (!Object.op_Implicit((Object)(object)val6)) { continue; } MeshFilter[] componentsInChildren3 = val6.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val7 in componentsInChildren3) { if (((Object)val7).name == "EngiTurretMesh") { Renderer component2 = ((Component)val7).GetComponent<Renderer>(); Saved saved2 = Save(component2); saved2.ChangeMesh = true; val7.sharedMesh = instance.StaticMeshFor(asset, saved2.Mesh); saved2.AssignedMesh = val7.sharedMesh; } } } } private void OnDisable() { Restore(); lobbyDirty = true; } private void OnDestroy() { if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } } } public const string Guid = "eclipseplaytest.engineer.e1"; public const string Version = "0.2.1"; private static EngineerUnionBuilder instance; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private float registrationDeadline; private string folder; private SkinDef skin; private GameObject modelPrefab; private string startupStage = "awake"; private readonly List<UnionVisuals> startupVisuals = new List<UnionVisuals>(); private readonly List<Prepared> prepared = new List<Prepared>(); private bool registered; private static readonly Design[] Designs = new Design[1] { new Design("union-builder", "Union Builder (Playtest)", (Color32[])(object)new Color32[4] { new Color32((byte)248, (byte)199, (byte)38, byte.MaxValue), new Color32((byte)177, (byte)67, (byte)49, byte.MaxValue), new Color32((byte)95, (byte)73, (byte)48, byte.MaxValue), new Color32((byte)52, (byte)62, (byte)62, byte.MaxValue) }) }; private GameObject cosmeticStorage; private readonly Dictionary<string, MeshBasis> canonicalBases = new Dictionary<string, MeshBasis>(); private readonly Dictionary<string, Material> assetMaterials = new Dictionary<string, Material>(); private readonly Dictionary<string, Mesh> remappedMeshes = new Dictionary<string, Mesh>(); private readonly Dictionary<string, Mesh> staticMeshes = new Dictionary<string, Mesh>(); private void Awake() { folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); instance = this; SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(EngineerUnionBuilder)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; } [SystemInitializer(new Type[] { typeof(BodyCatalog), typeof(ProjectileCatalog), typeof(SurvivorCatalog) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { return EmptyStartup(); } instance.registrationDeadline = Time.realtimeSinceStartup + 60f; return StartupGuard.Run(instance.RegisterAsync, () => Time.realtimeSinceStartup > instance.registrationDeadline, delegate(Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E1_STARTUP_DISABLED version=0.2.1 stage=" + instance.startupStage + " " + ex)); try { instance.RollbackRegistration(); ((BaseUnityPlugin)instance).Logger.LogWarning((object)"ENGINEER_E1_ROLLBACK_OK existing skin arrays retained."); } catch (Exception ex2) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E1_ROLLBACK_FAILED " + ex2)); } }); } private static IEnumerator EmptyStartup() { yield break; } private void Stage(string value) { startupStage = value; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E1_STARTUP_STAGE version=0.2.1 stage=" + value)); } private void RollbackRegistration() { registered = false; foreach (Prepared item in prepared) { if (Object.op_Implicit((Object)(object)item.Controller) && item.CommittedSkins != null && item.Controller.skins == item.CommittedSkins) { item.Controller.skins = item.OriginalSkins; } } foreach (UnionVisuals startupVisual in startupVisuals) { if (Object.op_Implicit((Object)(object)startupVisual)) { Object.Destroy((Object)(object)startupVisual); } } startupVisuals.Clear(); if (Object.op_Implicit((Object)(object)cosmeticStorage)) { Object.Destroy((Object)(object)cosmeticStorage); cosmeticStorage = null; } } private void ValidateAndCommit() { foreach (Prepared p in prepared) { if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Private bake produced no runtime skin: " + p.BodyName); } if (p.Controller.skins != p.OriginalSkins) { throw new InvalidOperationException("Skin list changed during startup: " + p.BodyName); } if (p.OriginalSkins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == ((Object)p.Skin).name)) { throw new InvalidOperationException("Duplicate Union Builder skin: " + ((Object)p.Skin).name); } p.CommittedSkins = p.OriginalSkins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { p.Skin }).ToArray(); } foreach (Prepared item in prepared) { item.Controller.skins = item.CommittedSkins; } } private IEnumerator RegisterAsync() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E1_REGISTRATION_BEGIN 0.2.1"); string[][] array = new string[3][] { new string[4] { "EngiTurretBody", "turret", "15", "skinEngiTurretDefault" }, new string[4] { "EngiWalkerTurretBody", "walker", "15", "skinEngiWalkerTurretDefault" }, new string[4] { "EngiBody", "union-builder", "83", "skinEngiDefault" } }; foreach (string[] array2 in array) { Stage("prepare:" + array2[0]); yield return Prepare(array2[0], array2[1], int.Parse(array2[2]), array2[3]); } Prepared bodySkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiBody"); bodySkin.Skin.skinDefParams.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[2] { new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiTurretBody").Skin }, new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiWalkerTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiWalkerTurretBody").Skin } }; Stage("prepare:mine-ghosts"); yield return PrepareMineGhosts(bodySkin.Skin); foreach (Prepared p in prepared) { Stage("private-bake:" + p.BodyName); ValidateSkin(p); yield return p.Skin.BakeAsync(); if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Bake returned without runtime skin: " + p.BodyName); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E1_PRIVATE_BAKE_OK body=" + p.BodyName)); } Stage("commit"); ValidateAndCommit(); modelPrefab = bodySkin.Model; skin = bodySkin.Skin; foreach (Prepared item in prepared) { if (!Object.op_Implicit((Object)(object)item.Model.GetComponent<UnionVisuals>())) { startupVisuals.Add(item.Model.AddComponent<UnionVisuals>()); } } registered = true; Stage("registered"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E1_REGISTERED Union Builder body, both turrets, pressure and spider mines; native Animator retained; unlocked=true version=0.2.1"); } private IEnumerator Prepare(string bodyName, string assetName, int boneCount, string defaultName) { GameObject val = BodyCatalog.FindBodyPrefab(bodyName); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing body " + bodyName); } GameObject model = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = model.GetComponent<ModelSkinController>(); SkinDef baseSkin = null; if (Object.op_Implicit((Object)(object)controller) && controller.skins != null && controller.skins.Length != 0) { baseSkin = controller.skins[0]; } if (!Object.op_Implicit((Object)(object)baseSkin)) { AsyncOperationHandle<SkinDef> h = Addressables.LoadAssetAsync<SkinDef>((object)("RoR2/Base/Engi/" + defaultName + ".asset")); retainedAssets.Add(AsyncOperationHandle<SkinDef>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline("default skin " + bodyName); yield return null; } baseSkin = h.Result; } if (!Object.op_Implicit((Object)(object)baseSkin)) { throw new InvalidOperationException("Missing default skin " + bodyName); } SkinDefParams bp = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)bp) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> h2 = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(h2)); while (!h2.IsDone) { CheckLoadDeadline("parameters " + bodyName); yield return null; } bp = h2.Result; } if (!Object.op_Implicit((Object)(object)bp)) { throw new InvalidOperationException("Missing parameters " + bodyName); } SkinnedMeshRenderer target = model.GetComponentsInChildren<SkinnedMeshRenderer>(true).Single((SkinnedMeshRenderer r) => r.bones.Length == boneCount); Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = bp.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference)) { AsyncOperationHandle<Mesh> h3 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(h3)); while (!h3.IsDone) { CheckLoadDeadline("mesh " + bodyName); yield return null; } reference = h3.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != target.bones.Length) { throw new InvalidOperationException("Bind pose mismatch " + bodyName); } RendererInfo ri = bp.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = ri.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && ri.defaultMaterialAddress != null && ((AssetReference)ri.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> h4 = Addressables.LoadAssetAsync<Material>(((AssetReference)ri.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(h4)); while (!h4.IsDone) { CheckLoadDeadline("material " + bodyName); yield return null; } val3 = h4.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Missing native material " + bodyName); } Mesh val4 = ReadMesh(Path.Combine(folder, assetName + ".meshbin"), target, reference); ((Object)val4).name = "EclipsePlaytest_EngineerE1_" + assetName; Material val5 = MakeMaterial(assetName, val3); canonicalBases[assetName] = new MeshBasis { Reference = reference, Authored = val4 }; ri.defaultMaterial = val5; ri.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { ri }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = val4, meshAddress = new AssetReferenceT<Mesh>("") } }; SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>(); ((Object)val7).name = "skinEclipsePlaytestEngineerE1_" + assetName; val7.nameToken = "ECLIPSEPLAYTEST_ENGINEER_E1_" + assetName.ToUpperInvariant().Replace('-', '_'); LanguageAPI.Add(val7.nameToken, (bodyName == "EngiBody") ? "Union Builder (Playtest)" : ("Union Builder " + assetName)); val7.icon = CreateIcon(Designs[0].Colors); val7.unlockableDef = null; val7.rootObject = model; val7.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; val7.skinDefParams = val6; if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { throw new InvalidOperationException("Missing native skin controller/list: " + bodyName); } prepared.Add(new Prepared { BodyName = bodyName, Model = model, Controller = controller, Skin = val7, Mesh = val4, Reference = reference, Material = val5, OriginalSkins = controller.skins }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E1_PREPARED body=" + bodyName + " vertices=" + val4.vertexCount + " unlocked=true")); } private static void ValidateSkin(Prepared p) { //IL_00ee: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) SkinDef skin = p.Skin; SkinDefParams skinDefParams = skin.skinDefParams; if (!Object.op_Implicit((Object)(object)skin.rootObject) || !Object.op_Implicit((Object)(object)skinDefParams) || skin.baseSkins == null || skin.baseSkins.Any((SkinDef s) => !Object.op_Implicit((Object)(object)s) || s == skin)) { throw new InvalidOperationException("Invalid skin graph: " + p.BodyName); } if (skin.skinDefParamsAddress == null) { skin.skinDefParamsAddress = new AssetReferenceT<SkinDefParams>(""); } if (skinDefParams.rendererInfos == null || skinDefParams.meshReplacements == null || skinDefParams.gameObjectActivations == null || skinDefParams.lightReplacements == null || skinDefParams.projectileGhostReplacements == null || skinDefParams.minionSkinReplacements == null) { throw new InvalidOperationException("Null parameter collection: " + p.BodyName); } RendererInfo[] rendererInfos = skinDefParams.rendererInfos; foreach (RendererInfo val in rendererInfos) { if (!Object.op_Implicit((Object)(object)val.renderer) || !Object.op_Implicit((Object)(object)val.defaultMaterial) || !((Component)val.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid material/renderer root: " + p.BodyName); } } MeshReplacement[] meshReplacements = skinDefParams.meshReplacements; foreach (MeshReplacement val2 in meshReplacements) { if (!Object.op_Implicit((Object)(object)val2.renderer) || !Object.op_Implicit((Object)(object)val2.mesh) || !((Component)val2.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid mesh/renderer root: " + p.BodyName); } } ProjectileGhostReplacement[] projectileGhostReplacements = skinDefParams.projectileGhostReplacements; foreach (ProjectileGhostReplacement val3 in projectileGhostReplacements) { if (!Object.op_Implicit((Object)(object)val3.projectilePrefab) || !Object.op_Implicit((Object)(object)val3.projectileGhostReplacementPrefab) || ProjectileCatalog.GetProjectileIndex(val3.projectilePrefab) < 0) { throw new InvalidOperationException("Unregistered mine projectile: " + p.BodyName); } } MinionSkinReplacement[] minionSkinReplacements = skinDefParams.minionSkinReplacements; foreach (MinionSkinReplacement val4 in minionSkinReplacements) { if (!Object.op_Implicit((Object)(object)val4.minionBodyPrefab) || !Object.op_Implicit((Object)(object)val4.minionSkin) || val4.minionSkin.runtimeSkin == null) { throw new InvalidOperationException("Unbaked turret skin: " + p.BodyName); } } } private static Sprite CreateIcon(Color32[] colors) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00c6: 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_0083: 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_0071: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : colors[num]); } } val.SetPixels32(array); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private void CheckLoadDeadline(string asset) { if (Time.realtimeSinceStartup > registrationDeadline) { throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin."); } } private void SyncDisplaySkins() { if (!registered) { return; } try { SyncDisplaySkinsChecked(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("ENGINEER_E1_DISPLAY_SYNC_FAILED version=0.2.1 " + ex)); } } private void SyncDisplaySkinsChecked() { SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "EngiBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)val.displayPrefab.GetComponent<UnionVisuals>())) { val.displayPrefab.AddComponent<UnionVisuals>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E1_DISPLAY_READY version=0.2.1 skins=" + val2.skins.Length + " catalogSkins=" + SkinCatalog.skinCount)); } } private Texture2D ReadTexture(string name, bool linear) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0037: Expected O, but got Unknown //IL_004b: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear) { name = name, anisoLevel = 4, filterMode = (FilterMode)2 }; if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(folder, name)), false)) { throw new InvalidDataException("Cannot decode " + name); } return val; } private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_0592: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (new string(binaryReader.ReadChars(4)) != "PWE2") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0 || !hashSet.Add(array[i])) { throw new InvalidDataException("Missing/duplicate reference bone: " + name); } } Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num3]; for (int num5 = 0; num5 < num3; num5++) { Matrix4x4 val = default(Matrix4x4); for (int num6 = 0; num6 < 4; num6++) { for (int num7 = 0; num7 < 4; num7++) { float num8 = binaryReader.ReadSingle(); if (float.IsNaN(num8) || float.IsInfinity(num8)) { throw new InvalidDataException("Invalid bind matrix."); } ((Matrix4x4)(ref val))[num6, num7] = num8; } } if (Math.Abs(((Matrix4x4)(ref val)).determinant) < 1E-05f) { throw new InvalidDataException("Singular bind matrix."); } array2[array[num5]] = val; } Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector3[] array4 = (Vector3[])(object)new Vector3[num]; Vector2[] array5 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array6 = (BoneWeight[])(object)new BoneWeight[num]; for (int num9 = 0; num9 < num; num9++) { array3[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array5[num9] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); int[] array7 = new int[4]; for (int num10 = 0; num10 < 4; num10++) { int num11 = binaryReader.ReadInt32(); if (num11 < 0 || num11 >= num3) { throw new InvalidDataException("Bone out of range."); } array7[num10] = array[num11]; } float[] array8 = new float[4]; for (int num12 = 0; num12 < 4; num12++) { array8[num12] = binaryReader.ReadSingle(); } if (array8.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array8.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } if (!Finite(array3[num9]) || !Finite(array4[num9])) { throw new InvalidDataException("Non-finite vertex."); } int num13 = num9; BoneWeight val2 = default(BoneWeight); ((BoneWeight)(ref val2)).boneIndex0 = array7[0]; ((BoneWeight)(ref val2)).boneIndex1 = array7[1]; ((BoneWeight)(ref val2)).boneIndex2 = array7[2]; ((BoneWeight)(ref val2)).boneIndex3 = array7[3]; ((BoneWeight)(ref val2)).weight0 = array8[0]; ((BoneWeight)(ref val2)).weight1 = array8[1]; ((BoneWeight)(ref val2)).weight2 = array8[2]; ((BoneWeight)(ref val2)).weight3 = array8[3]; array6[num13] = val2; } int[] array9 = new int[num2]; for (int num14 = 0; num14 < num2; num14++) { array9[num14] = binaryReader.ReadInt32(); if (array9[num14] < 0 || array9[num14] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } if (Object.op_Implicit((Object)(object)reference) && reference.bindposes.Length == num3) { Matrix4x4[] bindposes = reference.bindposes; int num15 = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Base"); if (num15 < 0) { num15 = 0; } Matrix4x4 b = ((Matrix4x4)(ref bindposes[num15])).inverse * array2[num15]; bool flag = true; for (int num16 = 0; num16 < num3; num16++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[num16])).inverse * array2[num16], b, 0.0002f)) { flag = false; } } if (!flag) { if (num3 != 2 && (num3 != 14 || !renderer.bones.Any((Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Screw"))) { throw new InvalidDataException("Unsupported nonuniform bind variant: " + ((Object)renderer).name); } Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int num17 = 0; num17 < num; num17++) { array3[num17] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(array3[num17]); int num18 = num17; Vector3 val3 = ((Matrix4x4)(ref transpose)).MultiplyVector(array4[num17]); array4[num18] = ((Vector3)(ref val3)).normalized; } array2 = bindposes; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E1_MINE_BIND_VARIANT renderer=" + ((Object)renderer).name + " reference=" + ((Object)reference).name)); } } Mesh val4 = new Mesh { name = "EclipsePlaytestEngineerUnionBuilder", indexFormat = (IndexFormat)(num > 65535), vertices = array3, normals = array4, uv = array5, boneWeights = array6, bindposes = array2, triangles = array9 }; val4.RecalculateBounds(); val4.RecalculateTangents(); return val4; } private Material MakeMaterial(string asset, Material source) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (assetMaterials.TryGetValue(asset, out var value)) { return value; } if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader)) { throw new InvalidOperationException("Missing shader for " + asset); } value = new Material(source) { name = "matEclipsePlaytest_EngineerE1_" + asset }; value.SetTexture("_MainTex", (Texture)(object)ReadTexture(asset + "-albedo-spec.png", linear: false)); value.SetTexture("_NormalTex", (Texture)(object)ReadTexture(asset + "-normal.png", linear: true)); value.SetTexture("_EmTex", (Texture)(object)ReadTexture(asset + "-emission.png", linear: false)); value.SetColor("_Color", Color.white); value.SetFloat("_NormalStrength", 0.3f); value.SetFloat("_Smoothness", 0.28f); value.SetFloat("_SpecularStrength", 0.35f); value.SetFloat("_SpecularExponent", 8f); value.SetFloat("_EmPower", asset.EndsWith("mine", StringComparison.Ordinal) ? 0.4f : 0f); value.DisableKeyword("LIMBREMOVAL"); value.SetFloat("_LimbRemovalOn", 0f); assetMaterials.Add(asset, value); return value; } private static string MineAsset(Renderer r) { if (((Object)r).name == "EngiMineMesh") { return "pressure-mine"; } if (((Object)r).name == "EngiSpiderMineMesh") { return "spider-mine"; } return null; } private IEnumerator PrepareMineGhosts(SkinDef bodySkin) { cosmeticStorage = new GameObject("UnionBuilderCosmeticPrefabs"); cosmeticStorage.SetActive(false); Object.DontDestroyOnLoad((Object)(object)cosmeticStorage); List<ProjectileGhostReplacement> replacements = new List<ProjectileGhostReplacement>(); string[] array = new string[2] { "EngiMine", "SpiderMine" }; foreach (string name in array) { AsyncOperationHandle<GameObject> h = Addressables.LoadAssetAsync<GameObject>((object)("RoR2/Base/Engi/" + name + ".prefab")); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline(name); yield return null; } if (!Object.op_Implicit((Object)(object)h.Result)) { throw new InvalidOperationException("Missing projectile " + name); } ProjectileController component = h.Result.GetComponent<ProjectileController>(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("Missing ProjectileController " + name); } GameObject val = component.ghostPrefab; if (!Object.op_Implicit((Object)(object)val) && component.ghostPrefabAddress != null && ((AssetReference)component.ghostPrefabAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<GameObject> gh = Addressables.LoadAssetAsync<GameObject>(((AssetReference)component.ghostPrefabAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(gh)); while (!gh.IsDone) { CheckLoadDeadline(name + " ghost"); yield return null; } val = gh.Result; } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing mine ghost " + name); } GameObject val2 = Object.Instantiate<GameObject>(val, cosmeticStorage.transform); ((Object)val2).name = "EclipseUnionBuilder_" + name + "Ghost"; string asset = ((name == "EngiMine") ? "pressure-mine" : "spider-mine"); SkinnedMeshRenderer[] array2 = (from r in val2.GetComponentsInChildren<SkinnedMeshRenderer>(true) where MineAsset((Renderer)(object)r) == asset select r).ToArray(); if (array2.Length != 1) { throw new InvalidOperationException("Ambiguous mine renderer " + name + ": " + array2.Length); } SkinnedMeshRenderer val3 = array2[0]; int num = ((asset == "pressure-mine") ? 2 : 14); if (val3.bones.Length != num || !Object.op_Implicit((Object)(object)val3.sharedMesh)) { throw new InvalidOperationException("Missing native mine rig " + name); } Mesh sharedMesh = val3.sharedMesh; Mesh val4 = MeshFor(asset, val3); Material sharedMaterial = MakeMaterial(asset, ((Renderer)val3).sharedMaterial); canonicalBases[asset] = new MeshBasis { Reference = sharedMesh, Authored = val4 }; val3.sharedMesh = val4; ((Renderer)val3).sharedMaterial = sharedMaterial; Mesh val5 = new Mesh(); val3.BakeMesh(val5); Bounds localBounds = ((Renderer)val3).localBounds; Bounds bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).min); bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).max); ((Bounds)(ref localBounds)).Expand(((Bounds)(ref localBounds)).size * 0.5f); ((Renderer)val3).localBounds = localBounds; Object.Destroy((Object)(object)val5); val3.updateWhenOffscreen = true; val2.SetActive(true); replacements.Add(new ProjectileGhostReplacement { projectilePrefab = h.Result, projectileGhostReplacementPrefab = val2, ghostReplacementAddress = new AssetReferenceT<GameObject>("") }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E1_MINE_READY asset=" + asset + " vertices=" + val4.vertexCount + " native effects/controller preserved")); } bodySkin.skinDefParams.projectileGhostReplacements = replacements.ToArray(); } private Mesh MeshFor(string asset, SkinnedMeshRenderer target, Mesh nativeReference = null) { if (!Object.op_Implicit((Object)(object)nativeReference)) { nativeReference = target.sharedMesh; } string key = asset + "|" + (Object.op_Implicit((Object)(object)nativeReference) ? ((Object)nativeReference).GetInstanceID() : 0) + "|" + string.Join("|", target.bones.Select((Transform b) => (!Object.op_Implicit((Object)(object)b)) ? "<null>" : ((Object)b).name)); if (!remappedMeshes.TryGetValue(key, out var value)) { value = ReadMesh(Path.Combine(folder, asset + ".meshbin"), target, nativeReference); remappedMeshes.Add(key, value); } return value; } private static bool SameMatrix(Matrix4x4 a, Matrix4x4 b, float tolerance) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (Math.Abs(((Matrix4x4)(ref a))[i, j] - ((Matrix4x4)(ref b))[i, j]) > tolerance) { return false; } } } return true; } private Mesh StaticMeshFor(string asset, Mesh reference) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)reference)) { throw new InvalidOperationException("Missing static reference " + asset); } string key = asset + "|" + ((Object)reference).GetInstanceID(); if (staticMeshes.TryGetValue(key, out var value)) { return value; } if (!canonicalBases.TryGetValue(asset, out var value2)) { throw new InvalidOperationException("Missing canonical rig " + asset); } Matrix4x4[] bindposes = reference.bindposes; Matrix4x4[] bindposes2 = value2.Authored.bindposes; if (bindposes.Length != bindposes2.Length || bindposes.Length == 0) { throw new InvalidOperationException("Static bind count " + asset); } Matrix4x4 b = ((Matrix4x4)(ref bindposes[0])).inverse * bindposes2[0]; for (int i = 1; i < bindposes.Length; i++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[i])).inverse * bindposes2[i], b, 0.0002f)) { if (asset != "pressure-mine" && asset != "spider-mine") { throw new InvalidOperationException("Nonuniform static bind conversion " + asset + " bone " + i); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E1_STATIC_MINE_BIND_VARIANT " + asset + " uses canonical assembled rest shape")); break; } } value = Object.Instantiate<Mesh>(value2.Authored); ((Object)value).name = "EclipseEngineerE1Static_" + asset; Vector3[] vertices = value.vertices; Vector3[] normals = value.normals; Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int j = 0; j < vertices.Length; j++) { vertices[j] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(vertices[j]); int num = j; Vector3 val = ((Matrix4x4)(ref transpose)).MultiplyVector(normals[j]); normals[num] = ((Vector3)(ref val)).normalized; } value.vertices = vertices; value.normals = normals; value.boneWeights = (BoneWeight[])(object)new BoneWeight[0]; value.bindposes = (Matrix4x4[])(object)new Matrix4x4[0]; value.RecalculateBounds(); value.RecalculateTangents(); staticMeshes.Add(key, value); return value; } private static bool Finite(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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_0028: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(v.x + v.y + v.z)) { return !float.IsInfinity(v.x + v.y + v.z); } return false; } } internal static class StartupGuard { internal static IEnumerator Run(Func<IEnumerator> create, Func<bool> expired, Action<Exception> failed) { Stack<IEnumerator> stack = new Stack<IEnumerator>(); Exception failure = null; try { stack.Push(create()); } catch (Exception ex) { failure = ex; } try { while (failure == null && stack.Count > 0) { bool flag = false; object obj = null; try { if (expired()) { throw new TimeoutException("Union Builder startup deadline exceeded."); } IEnumerator enumerator = stack.Peek(); flag = enumerator.MoveNext(); if (flag) { obj = enumerator.Current; } else { stack.Pop(); (enumerator as IDisposable)?.Dispose(); } } catch (Exception ex2) { failure = ex2; } if (failure != null) { break; } if (flag) { if (obj is IEnumerator item) { stack.Push(item); } else { yield return obj; } } } } finally { if (stack.Count > 0 && failure == null) { failure = new OperationCanceledException("Union Builder startup iterator was cancelled."); } while (stack.Count > 0) { try { (stack.Pop() as IDisposable)?.Dispose(); } catch (Exception ex3) { if (failure == null) { failure = ex3; } } } if (failure != null) { try { failed(failure); } catch { } } } } }
BepInEx/plugins/RodaniusSkins/engineer-bubble-works/EngineerBubbleWorks.dll
Decompiled a week agousing 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.Security.Cryptography; using System.Text; using BepInEx; using EngineerTrafficControlPlaytest; using EntityStates; using EntityStates.Engi.EngiWeapon; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.Projectile; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EngineerBubbleWorksPlaytest; [BepInPlugin("eclipseplaytest.engineer.e6", "Engineer - Bubble Works (Playtest)", "0.3.1")] [BepInDependency("eclipseplaytest.engineer.e5", "0.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EngineerBubbleWorks : BaseUnityPlugin { private sealed class Prepared { public SkinDef[] OriginalSkins; public SkinDef[] CommittedSkins; public string BodyName; public GameObject Model; public ModelSkinController Controller; public SkinDef Skin; public Mesh Mesh; public Mesh Reference; public Material Material; } private sealed class Design { public string Slug; public string Name; public Color32[] Colors; public Design(string slug, string name, Color32[] colors) { Slug = slug; Name = name; Colors = colors; } } private sealed class MeshBasis { public Mesh Reference; public Mesh Authored; } public sealed class BandVisuals : MonoBehaviour { private sealed class Saved { public Renderer Renderer; public Mesh Mesh; public Material[] Materials; public Bounds Bounds; public bool Offscreen; public bool ChangeMesh; public bool ChangeMaterial; public Mesh AssignedMesh; public Material[] AssignedMaterials; public bool ChangeBounds; public Bounds AssignedBounds; public bool ChangeOffscreen; public bool AssignedOffscreen; } private readonly Dictionary<Renderer, Saved> changed = new Dictionary<Renderer, Saved>(); private ModelSkinController controller; private CharacterBody body; private EntityStateMachine[] machines; private bool lobbyDirty = true; private static readonly FieldInfo Blueprint = typeof(PlaceTurret).GetField("blueprints", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo Wrist = typeof(PlaceTurret).GetField("wristDisplayObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private void Applied(int index) { if (!OwnSkin() && changed.Count > 0) { Restore(); } lobbyDirty = true; } private void Start() { controller = ((Component)this).GetComponentInChildren<ModelSkinController>(true); body = ((Component)this).GetComponentInParent<CharacterBody>(); machines = (EntityStateMachine[])(Object.op_Implicit((Object)(object)body) ? ((Array)((Component)body).GetComponents<EntityStateMachine>()) : ((Array)new EntityStateMachine[0])); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; } } private bool OwnSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length && Object.op_Implicit((Object)(object)controller.skins[currentSkinIndex])) { return ((Object)controller.skins[currentSkinIndex]).name.StartsWith("skinEclipsePlaytestEngineerE6_", StringComparison.Ordinal); } return false; } private Saved Save(Renderer r) { //IL_0074: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (changed.TryGetValue(r, out var value)) { return value; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((r is SkinnedMeshRenderer) ? r : null); MeshFilter component = ((Component)r).GetComponent<MeshFilter>(); value = new Saved { Renderer = r, Materials = r.sharedMaterials, Mesh = (Object.op_Implicit((Object)(object)val) ? val.sharedMesh : (Object.op_Implicit((Object)(object)component) ? component.sharedMesh : null)), Bounds = (Bounds)(Object.op_Implicit((Object)(object)val) ? ((Renderer)val).localBounds : default(Bounds)), Offscreen = (Object.op_Implicit((Object)(object)val) && val.updateWhenOffscreen) }; changed.Add(r, value); return value; } private void ApplySkinned(SkinnedMeshRenderer r, string asset, bool keepMaterial) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) Saved saved = Save((Renderer)(object)r); saved.ChangeMesh = true; saved.ChangeMaterial = !keepMaterial; Mesh val = (saved.AssignedMesh = instance.MeshFor(asset, r, saved.Mesh)); if ((Object)(object)r.sharedMesh != (Object)(object)val) { r.sharedMesh = val; Mesh val2 = new Mesh(); r.BakeMesh(val2); Bounds bounds = saved.Bounds; Bounds bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).min); bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).max); ((Bounds)(ref bounds)).Expand(((Bounds)(ref bounds)).size * 0.5f); ((Renderer)r).localBounds = bounds; saved.ChangeBounds = true; saved.AssignedBounds = bounds; Object.Destroy((Object)(object)val2); } r.updateWhenOffscreen = true; saved.ChangeOffscreen = true; saved.AssignedOffscreen = true; if (!keepMaterial) { ((Renderer)r).sharedMaterial = instance.assetMaterials[asset]; saved.AssignedMaterials = ((Renderer)r).sharedMaterials; } } private void Restore() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) foreach (Saved value in changed.Values) { if (!Object.op_Implicit((Object)(object)value.Renderer)) { continue; } Renderer renderer = value.Renderer; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); MeshFilter component = ((Component)value.Renderer).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)val)) { if (value.ChangeMesh && (Object)(object)val.sharedMesh == (Object)(object)value.AssignedMesh) { if (value.ChangeBounds && ((Renderer)val).localBounds == value.AssignedBounds) { ((Renderer)val).localBounds = value.Bounds; } if (value.ChangeOffscreen && val.updateWhenOffscreen == value.AssignedOffscreen) { val.updateWhenOffscreen = value.Offscreen; } val.sharedMesh = value.Mesh; } } else if (Object.op_Implicit((Object)(object)component) && value.ChangeMesh && (Object)(object)component.sharedMesh == (Object)(object)value.AssignedMesh) { component.sharedMesh = value.Mesh; } if (value.ChangeMaterial && value.AssignedMaterials != null && value.Renderer.sharedMaterials.SequenceEqual(value.AssignedMaterials)) { value.Renderer.sharedMaterials = value.Materials; } } changed.Clear(); } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)instance) || !instance.registered) { return; } Renderer[] array = changed.Keys.Where((Renderer r) => !Object.op_Implicit((Object)(object)r)).ToArray(); foreach (Renderer key in array) { changed.Remove(key); } if (!OwnSkin()) { if (changed.Count > 0) { Restore(); } lobbyDirty = true; return; } if (lobbyDirty) { SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { string text = MineAsset((Renderer)(object)val); if (text != null) { ApplySkinned(val, text, keepMaterial: false); } else if (!Object.op_Implicit((Object)(object)body) && val.bones.Length == 15 && Object.op_Implicit((Object)(object)((Component)this).transform.Find("TurretHolder")) && ((Component)val).transform.IsChildOf(((Component)this).transform.Find("TurretHolder"))) { ApplySkinned(val, "turret", keepMaterial: false); } } MeshRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren2) { string text2 = MineAsset((Renderer)(object)val2); if (text2 != null) { MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)component)) { Saved saved = Save((Renderer)(object)val2); saved.ChangeMesh = true; component.sharedMesh = instance.StaticMeshFor(text2, saved.Mesh); saved.AssignedMesh = component.sharedMesh; saved.ChangeMaterial = true; ((Renderer)val2).sharedMaterial = instance.assetMaterials[text2]; saved.AssignedMaterials = ((Renderer)val2).sharedMaterials; } } } lobbyDirty = false; } if (!Object.op_Implicit((Object)(object)body)) { return; } EntityStateMachine[] array2 = machines; for (int num = 0; num < array2.Length; num++) { EntityState state = array2[num].state; PlaceTurret val3 = (PlaceTurret)(object)((state is PlaceTurret) ? state : null); if (val3 == null) { continue; } string asset = ((val3 is PlaceWalkerTurret) ? "walker" : "turret"); object? obj = Blueprint?.GetValue(val3); BlueprintController val4 = (BlueprintController)((obj is BlueprintController) ? obj : null); if (Object.op_Implicit((Object)(object)val4)) { SkinnedMeshRenderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val5 in componentsInChildren) { if (val5.bones.Length == 15) { ApplySkinned(val5, asset, keepMaterial: true); } } } object? obj2 = Wrist?.GetValue(val3); GameObject val6 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (!Object.op_Implicit((Object)(object)val6)) { continue; } MeshFilter[] componentsInChildren3 = val6.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val7 in componentsInChildren3) { if (((Object)val7).name == "EngiTurretMesh") { Renderer component2 = ((Component)val7).GetComponent<Renderer>(); Saved saved2 = Save(component2); saved2.ChangeMesh = true; val7.sharedMesh = instance.StaticMeshFor(asset, saved2.Mesh); saved2.AssignedMesh = val7.sharedMesh; } } } } private void OnDisable() { Restore(); lobbyDirty = true; } private void OnDestroy() { if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } } } public const string Guid = "eclipseplaytest.engineer.e6"; public const string Version = "0.3.1"; private static EngineerBubbleWorks instance; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private float registrationDeadline; private string folder; private SkinDef skin; private GameObject modelPrefab; private string startupStage = "awake"; private readonly List<BandVisuals> startupVisuals = new List<BandVisuals>(); private readonly List<Prepared> prepared = new List<Prepared>(); private bool registered; private static readonly Design[] Designs = new Design[1] { new Design("bubble-works", "Bubble Works (Playtest)", (Color32[])(object)new Color32[4] { new Color32((byte)245, (byte)198, (byte)33, byte.MaxValue), new Color32((byte)237, (byte)91, (byte)24, byte.MaxValue), new Color32((byte)45, (byte)135, (byte)181, byte.MaxValue), new Color32((byte)136, (byte)98, (byte)48, byte.MaxValue) }) }; private readonly TextureAssetCache textureCache = new TextureAssetCache(); private GameObject cosmeticStorage; private readonly Dictionary<string, MeshBasis> canonicalBases = new Dictionary<string, MeshBasis>(); private readonly Dictionary<string, Material> assetMaterials = new Dictionary<string, Material>(); private readonly Dictionary<string, Mesh> remappedMeshes = new Dictionary<string, Mesh>(); private readonly Dictionary<string, Mesh> staticMeshes = new Dictionary<string, Mesh>(); private void Awake() { folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); instance = this; SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(EngineerBubbleWorks)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; } [SystemInitializer(new Type[] { typeof(BodyCatalog), typeof(ProjectileCatalog), typeof(SurvivorCatalog), typeof(EngineerTrafficControl) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { return EmptyStartup(); } instance.registrationDeadline = Time.realtimeSinceStartup + 60f; return StartupGuard.Run(instance.RegisterAsync, () => Time.realtimeSinceStartup > instance.registrationDeadline, delegate(Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E6_STARTUP_DISABLED version=0.3.1 stage=" + instance.startupStage + " " + ex)); try { instance.RollbackRegistration(); ((BaseUnityPlugin)instance).Logger.LogWarning((object)"ENGINEER_E6_ROLLBACK_OK existing skin arrays retained."); } catch (Exception ex2) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E6_ROLLBACK_FAILED " + ex2)); } }); } private static IEnumerator EmptyStartup() { yield break; } private void Stage(string value) { startupStage = value; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E6_STARTUP_STAGE version=0.3.1 stage=" + value)); } private void RollbackRegistration() { registered = false; foreach (Prepared item in prepared) { if (Object.op_Implicit((Object)(object)item.Controller) && item.CommittedSkins != null && item.Controller.skins == item.CommittedSkins) { item.Controller.skins = item.OriginalSkins; } } foreach (BandVisuals startupVisual in startupVisuals) { if (Object.op_Implicit((Object)(object)startupVisual)) { Object.Destroy((Object)(object)startupVisual); } } startupVisuals.Clear(); if (Object.op_Implicit((Object)(object)cosmeticStorage)) { Object.Destroy((Object)(object)cosmeticStorage); cosmeticStorage = null; } } private void ValidateAndCommit() { foreach (Prepared p in prepared) { if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Private bake produced no runtime skin: " + p.BodyName); } if (p.Controller.skins != p.OriginalSkins) { throw new InvalidOperationException("Skin list changed during startup: " + p.BodyName); } if (p.OriginalSkins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == ((Object)p.Skin).name)) { throw new InvalidOperationException("Duplicate Bubble Works skin: " + ((Object)p.Skin).name); } p.CommittedSkins = p.OriginalSkins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { p.Skin }).ToArray(); } foreach (Prepared item in prepared) { item.Controller.skins = item.CommittedSkins; } } private IEnumerator RegisterAsync() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E6_REGISTRATION_BEGIN 0.3.1"); string[][] array = new string[3][] { new string[4] { "EngiTurretBody", "turret", "15", "skinEngiTurretDefault" }, new string[4] { "EngiWalkerTurretBody", "walker", "15", "skinEngiWalkerTurretDefault" }, new string[4] { "EngiBody", "bubble-works", "83", "skinEngiDefault" } }; foreach (string[] array2 in array) { Stage("prepare:" + array2[0]); yield return Prepare(array2[0], array2[1], int.Parse(array2[2]), array2[3]); } Prepared bodySkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiBody"); bodySkin.Skin.skinDefParams.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[2] { new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiTurretBody").Skin }, new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiWalkerTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiWalkerTurretBody").Skin } }; Stage("prepare:mine-ghosts"); yield return PrepareMineGhosts(bodySkin.Skin); foreach (Prepared p in prepared) { Stage("private-bake:" + p.BodyName); ValidateSkin(p); yield return p.Skin.BakeAsync(); if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Bake returned without runtime skin: " + p.BodyName); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E6_PRIVATE_BAKE_OK body=" + p.BodyName)); } Stage("commit"); ValidateAndCommit(); modelPrefab = bodySkin.Model; skin = bodySkin.Skin; foreach (Prepared item in prepared) { if (!Object.op_Implicit((Object)(object)item.Model.GetComponent<BandVisuals>())) { startupVisuals.Add(item.Model.AddComponent<BandVisuals>()); } } registered = true; Stage("registered"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E6_REGISTERED Bubble Works body, both turrets, pressure and spider mines; native Animator retained; unlocked=true version=0.3.1"); } private IEnumerator Prepare(string bodyName, string assetName, int boneCount, string defaultName) { GameObject val = BodyCatalog.FindBodyPrefab(bodyName); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing body " + bodyName); } GameObject model = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = model.GetComponent<ModelSkinController>(); SkinDef baseSkin = null; if (Object.op_Implicit((Object)(object)controller) && controller.skins != null && controller.skins.Length != 0) { baseSkin = controller.skins[0]; } if (!Object.op_Implicit((Object)(object)baseSkin)) { AsyncOperationHandle<SkinDef> h = Addressables.LoadAssetAsync<SkinDef>((object)("RoR2/Base/Engi/" + defaultName + ".asset")); retainedAssets.Add(AsyncOperationHandle<SkinDef>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline("default skin " + bodyName); yield return null; } baseSkin = h.Result; } if (!Object.op_Implicit((Object)(object)baseSkin)) { throw new InvalidOperationException("Missing default skin " + bodyName); } SkinDefParams bp = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)bp) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> h2 = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(h2)); while (!h2.IsDone) { CheckLoadDeadline("parameters " + bodyName); yield return null; } bp = h2.Result; } if (!Object.op_Implicit((Object)(object)bp)) { throw new InvalidOperationException("Missing parameters " + bodyName); } SkinnedMeshRenderer target = model.GetComponentsInChildren<SkinnedMeshRenderer>(true).Single((SkinnedMeshRenderer r) => r.bones.Length == boneCount); Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = bp.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference)) { AsyncOperationHandle<Mesh> h3 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(h3)); while (!h3.IsDone) { CheckLoadDeadline("mesh " + bodyName); yield return null; } reference = h3.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != target.bones.Length) { throw new InvalidOperationException("Bind pose mismatch " + bodyName); } RendererInfo ri = bp.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = ri.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && ri.defaultMaterialAddress != null && ((AssetReference)ri.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> h4 = Addressables.LoadAssetAsync<Material>(((AssetReference)ri.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(h4)); while (!h4.IsDone) { CheckLoadDeadline("material " + bodyName); yield return null; } val3 = h4.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Missing native material " + bodyName); } Mesh val4 = ReadMesh(Path.Combine(folder, assetName + ".meshbin"), target, reference); ((Object)val4).name = "EclipsePlaytest_EngineerE6_" + assetName; Material val5 = MakeMaterial(assetName, val3); canonicalBases[assetName] = new MeshBasis { Reference = reference, Authored = val4 }; ri.defaultMaterial = val5; ri.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { ri }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = val4, meshAddress = new AssetReferenceT<Mesh>("") } }; SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>(); ((Object)val7).name = "skinEclipsePlaytestEngineerE6_" + assetName; val7.nameToken = "ECLIPSEPLAYTEST_ENGINEER_E6_" + assetName.ToUpperInvariant().Replace('-', '_'); LanguageAPI.Add(val7.nameToken, (bodyName == "EngiBody") ? "Bubble Works (Playtest)" : ("Bubble Works " + assetName)); val7.icon = CreateIcon(Designs[0].Colors); val7.unlockableDef = null; val7.rootObject = model; val7.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; val7.skinDefParams = val6; if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { throw new InvalidOperationException("Missing native skin controller/list: " + bodyName); } prepared.Add(new Prepared { BodyName = bodyName, Model = model, Controller = controller, Skin = val7, Mesh = val4, Reference = reference, Material = val5, OriginalSkins = controller.skins }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E6_PREPARED body=" + bodyName + " vertices=" + val4.vertexCount + " unlocked=true")); } private static void ValidateSkin(Prepared p) { //IL_00ee: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) SkinDef skin = p.Skin; SkinDefParams skinDefParams = skin.skinDefParams; if (!Object.op_Implicit((Object)(object)skin.rootObject) || !Object.op_Implicit((Object)(object)skinDefParams) || skin.baseSkins == null || skin.baseSkins.Any((SkinDef s) => !Object.op_Implicit((Object)(object)s) || s == skin)) { throw new InvalidOperationException("Invalid skin graph: " + p.BodyName); } if (skin.skinDefParamsAddress == null) { skin.skinDefParamsAddress = new AssetReferenceT<SkinDefParams>(""); } if (skinDefParams.rendererInfos == null || skinDefParams.meshReplacements == null || skinDefParams.gameObjectActivations == null || skinDefParams.lightReplacements == null || skinDefParams.projectileGhostReplacements == null || skinDefParams.minionSkinReplacements == null) { throw new InvalidOperationException("Null parameter collection: " + p.BodyName); } RendererInfo[] rendererInfos = skinDefParams.rendererInfos; foreach (RendererInfo val in rendererInfos) { if (!Object.op_Implicit((Object)(object)val.renderer) || !Object.op_Implicit((Object)(object)val.defaultMaterial) || !((Component)val.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid material/renderer root: " + p.BodyName); } } MeshReplacement[] meshReplacements = skinDefParams.meshReplacements; foreach (MeshReplacement val2 in meshReplacements) { if (!Object.op_Implicit((Object)(object)val2.renderer) || !Object.op_Implicit((Object)(object)val2.mesh) || !((Component)val2.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid mesh/renderer root: " + p.BodyName); } } ProjectileGhostReplacement[] projectileGhostReplacements = skinDefParams.projectileGhostReplacements; foreach (ProjectileGhostReplacement val3 in projectileGhostReplacements) { if (!Object.op_Implicit((Object)(object)val3.projectilePrefab) || !Object.op_Implicit((Object)(object)val3.projectileGhostReplacementPrefab) || ProjectileCatalog.GetProjectileIndex(val3.projectilePrefab) < 0) { throw new InvalidOperationException("Unregistered mine projectile: " + p.BodyName); } } MinionSkinReplacement[] minionSkinReplacements = skinDefParams.minionSkinReplacements; foreach (MinionSkinReplacement val4 in minionSkinReplacements) { if (!Object.op_Implicit((Object)(object)val4.minionBodyPrefab) || !Object.op_Implicit((Object)(object)val4.minionSkin) || val4.minionSkin.runtimeSkin == null) { throw new InvalidOperationException("Unbaked turret skin: " + p.BodyName); } } } private static Sprite CreateIcon(Color32[] colors) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00c6: 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_0083: 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_0071: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : colors[num]); } } val.SetPixels32(array); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private void CheckLoadDeadline(string asset) { if (Time.realtimeSinceStartup > registrationDeadline) { throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin."); } } private void SyncDisplaySkins() { if (!registered) { return; } try { SyncDisplaySkinsChecked(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("ENGINEER_E6_DISPLAY_SYNC_FAILED version=0.3.1 " + ex)); } } private void SyncDisplaySkinsChecked() { SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "EngiBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)val.displayPrefab.GetComponent<BandVisuals>())) { val.displayPrefab.AddComponent<BandVisuals>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E6_DISPLAY_READY version=0.3.1 skins=" + val2.skins.Length + " catalogSkins=" + SkinCatalog.skinCount)); } } private Texture2D ReadTexture(string name, bool linear) { return textureCache.Load(Path.Combine(folder, name), linear); } private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_0592: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (new string(binaryReader.ReadChars(4)) != "PWE2") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0 || !hashSet.Add(array[i])) { throw new InvalidDataException("Missing/duplicate reference bone: " + name); } } Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num3]; for (int num5 = 0; num5 < num3; num5++) { Matrix4x4 val = default(Matrix4x4); for (int num6 = 0; num6 < 4; num6++) { for (int num7 = 0; num7 < 4; num7++) { float num8 = binaryReader.ReadSingle(); if (float.IsNaN(num8) || float.IsInfinity(num8)) { throw new InvalidDataException("Invalid bind matrix."); } ((Matrix4x4)(ref val))[num6, num7] = num8; } } if (Math.Abs(((Matrix4x4)(ref val)).determinant) < 1E-05f) { throw new InvalidDataException("Singular bind matrix."); } array2[array[num5]] = val; } Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector3[] array4 = (Vector3[])(object)new Vector3[num]; Vector2[] array5 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array6 = (BoneWeight[])(object)new BoneWeight[num]; for (int num9 = 0; num9 < num; num9++) { array3[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array5[num9] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); int[] array7 = new int[4]; for (int num10 = 0; num10 < 4; num10++) { int num11 = binaryReader.ReadInt32(); if (num11 < 0 || num11 >= num3) { throw new InvalidDataException("Bone out of range."); } array7[num10] = array[num11]; } float[] array8 = new float[4]; for (int num12 = 0; num12 < 4; num12++) { array8[num12] = binaryReader.ReadSingle(); } if (array8.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array8.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } if (!Finite(array3[num9]) || !Finite(array4[num9])) { throw new InvalidDataException("Non-finite vertex."); } int num13 = num9; BoneWeight val2 = default(BoneWeight); ((BoneWeight)(ref val2)).boneIndex0 = array7[0]; ((BoneWeight)(ref val2)).boneIndex1 = array7[1]; ((BoneWeight)(ref val2)).boneIndex2 = array7[2]; ((BoneWeight)(ref val2)).boneIndex3 = array7[3]; ((BoneWeight)(ref val2)).weight0 = array8[0]; ((BoneWeight)(ref val2)).weight1 = array8[1]; ((BoneWeight)(ref val2)).weight2 = array8[2]; ((BoneWeight)(ref val2)).weight3 = array8[3]; array6[num13] = val2; } int[] array9 = new int[num2]; for (int num14 = 0; num14 < num2; num14++) { array9[num14] = binaryReader.ReadInt32(); if (array9[num14] < 0 || array9[num14] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } if (Object.op_Implicit((Object)(object)reference) && reference.bindposes.Length == num3) { Matrix4x4[] bindposes = reference.bindposes; int num15 = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Base"); if (num15 < 0) { num15 = 0; } Matrix4x4 b = ((Matrix4x4)(ref bindposes[num15])).inverse * array2[num15]; bool flag = true; for (int num16 = 0; num16 < num3; num16++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[num16])).inverse * array2[num16], b, 0.0002f)) { flag = false; } } if (!flag) { if (num3 != 2 && (num3 != 14 || !renderer.bones.Any((Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Screw"))) { throw new InvalidDataException("Unsupported nonuniform bind variant: " + ((Object)renderer).name); } Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int num17 = 0; num17 < num; num17++) { array3[num17] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(array3[num17]); int num18 = num17; Vector3 val3 = ((Matrix4x4)(ref transpose)).MultiplyVector(array4[num17]); array4[num18] = ((Vector3)(ref val3)).normalized; } array2 = bindposes; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E6_MINE_BIND_VARIANT renderer=" + ((Object)renderer).name + " reference=" + ((Object)reference).name)); } } Mesh val4 = new Mesh { name = "EclipsePlaytestEngineerBubbleWorks", indexFormat = (IndexFormat)(num > 65535), vertices = array3, normals = array4, uv = array5, boneWeights = array6, bindposes = array2, triangles = array9 }; val4.RecalculateBounds(); val4.RecalculateTangents(); return val4; } private Material MakeMaterial(string asset, Material source) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (assetMaterials.TryGetValue(asset, out var value)) { return value; } if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader)) { throw new InvalidOperationException("Missing shader for " + asset); } value = new Material(source) { name = "matEclipsePlaytest_EngineerE6_" + asset }; value.SetTexture("_MainTex", (Texture)(object)ReadTexture(asset + "-albedo-spec.png", linear: false)); value.SetTexture("_NormalTex", (Texture)(object)ReadTexture(asset + "-normal.png", linear: true)); value.SetTexture("_EmTex", (Texture)(object)ReadTexture(asset + "-emission.png", linear: false)); value.SetColor("_Color", Color.white); value.SetFloat("_NormalStrength", 0.3f); value.SetFloat("_Smoothness", 0.28f); value.SetFloat("_SpecularStrength", 0.35f); value.SetFloat("_SpecularExponent", 8f); value.SetFloat("_EmPower", asset.EndsWith("mine", StringComparison.Ordinal) ? 0.4f : 0f); value.DisableKeyword("LIMBREMOVAL"); value.SetFloat("_LimbRemovalOn", 0f); assetMaterials.Add(asset, value); return value; } private static string MineAsset(Renderer r) { if (((Object)r).name == "EngiMineMesh") { return "pressure-mine"; } if (((Object)r).name == "EngiSpiderMineMesh") { return "spider-mine"; } return null; } private IEnumerator PrepareMineGhosts(SkinDef bodySkin) { cosmeticStorage = new GameObject("BubbleWorksCosmeticPrefabs"); cosmeticStorage.SetActive(false); Object.DontDestroyOnLoad((Object)(object)cosmeticStorage); List<ProjectileGhostReplacement> replacements = new List<ProjectileGhostReplacement>(); string[] array = new string[2] { "EngiMine", "SpiderMine" }; foreach (string name in array) { AsyncOperationHandle<GameObject> h = Addressables.LoadAssetAsync<GameObject>((object)("RoR2/Base/Engi/" + name + ".prefab")); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline(name); yield return null; } if (!Object.op_Implicit((Object)(object)h.Result)) { throw new InvalidOperationException("Missing projectile " + name); } ProjectileController component = h.Result.GetComponent<ProjectileController>(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("Missing ProjectileController " + name); } GameObject val = component.ghostPrefab; if (!Object.op_Implicit((Object)(object)val) && component.ghostPrefabAddress != null && ((AssetReference)component.ghostPrefabAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<GameObject> gh = Addressables.LoadAssetAsync<GameObject>(((AssetReference)component.ghostPrefabAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(gh)); while (!gh.IsDone) { CheckLoadDeadline(name + " ghost"); yield return null; } val = gh.Result; } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing mine ghost " + name); } GameObject val2 = Object.Instantiate<GameObject>(val, cosmeticStorage.transform); ((Object)val2).name = "EclipseBubbleWorks_" + name + "Ghost"; string asset = ((name == "EngiMine") ? "pressure-mine" : "spider-mine"); SkinnedMeshRenderer[] array2 = (from r in val2.GetComponentsInChildren<SkinnedMeshRenderer>(true) where MineAsset((Renderer)(object)r) == asset select r).ToArray(); if (array2.Length != 1) { throw new InvalidOperationException("Ambiguous mine renderer " + name + ": " + array2.Length); } SkinnedMeshRenderer val3 = array2[0]; int num = ((asset == "pressure-mine") ? 2 : 14); if (val3.bones.Length != num || !Object.op_Implicit((Object)(object)val3.sharedMesh)) { throw new InvalidOperationException("Missing native mine rig " + name); } Mesh sharedMesh = val3.sharedMesh; Mesh val4 = MeshFor(asset, val3); Material sharedMaterial = MakeMaterial(asset, ((Renderer)val3).sharedMaterial); canonicalBases[asset] = new MeshBasis { Reference = sharedMesh, Authored = val4 }; val3.sharedMesh = val4; ((Renderer)val3).sharedMaterial = sharedMaterial; Mesh val5 = new Mesh(); val3.BakeMesh(val5); Bounds localBounds = ((Renderer)val3).localBounds; Bounds bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).min); bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).max); ((Bounds)(ref localBounds)).Expand(((Bounds)(ref localBounds)).size * 0.5f); ((Renderer)val3).localBounds = localBounds; Object.Destroy((Object)(object)val5); val3.updateWhenOffscreen = true; val2.SetActive(true); replacements.Add(new ProjectileGhostReplacement { projectilePrefab = h.Result, projectileGhostReplacementPrefab = val2, ghostReplacementAddress = new AssetReferenceT<GameObject>("") }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E6_MINE_READY asset=" + asset + " vertices=" + val4.vertexCount + " native effects/controller preserved")); } bodySkin.skinDefParams.projectileGhostReplacements = replacements.ToArray(); } private Mesh MeshFor(string asset, SkinnedMeshRenderer target, Mesh nativeReference = null) { if (!Object.op_Implicit((Object)(object)nativeReference)) { nativeReference = target.sharedMesh; } string key = asset + "|" + (Object.op_Implicit((Object)(object)nativeReference) ? ((Object)nativeReference).GetInstanceID() : 0) + "|" + string.Join("|", target.bones.Select((Transform b) => (!Object.op_Implicit((Object)(object)b)) ? "<null>" : ((Object)b).name)); if (!remappedMeshes.TryGetValue(key, out var value)) { value = ReadMesh(Path.Combine(folder, asset + ".meshbin"), target, nativeReference); remappedMeshes.Add(key, value); } return value; } private static bool SameMatrix(Matrix4x4 a, Matrix4x4 b, float tolerance) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (Math.Abs(((Matrix4x4)(ref a))[i, j] - ((Matrix4x4)(ref b))[i, j]) > tolerance) { return false; } } } return true; } private Mesh StaticMeshFor(string asset, Mesh reference) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)reference)) { throw new InvalidOperationException("Missing static reference " + asset); } string key = asset + "|" + ((Object)reference).GetInstanceID(); if (staticMeshes.TryGetValue(key, out var value)) { return value; } if (!canonicalBases.TryGetValue(asset, out var value2)) { throw new InvalidOperationException("Missing canonical rig " + asset); } Matrix4x4[] bindposes = reference.bindposes; Matrix4x4[] bindposes2 = value2.Authored.bindposes; if (bindposes.Length != bindposes2.Length || bindposes.Length == 0) { throw new InvalidOperationException("Static bind count " + asset); } Matrix4x4 b = ((Matrix4x4)(ref bindposes[0])).inverse * bindposes2[0]; for (int i = 1; i < bindposes.Length; i++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[i])).inverse * bindposes2[i], b, 0.0002f)) { if (asset != "pressure-mine" && asset != "spider-mine") { throw new InvalidOperationException("Nonuniform static bind conversion " + asset + " bone " + i); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E6_STATIC_MINE_BIND_VARIANT " + asset + " uses canonical assembled rest shape")); break; } } value = Object.Instantiate<Mesh>(value2.Authored); ((Object)value).name = "EclipseEngineerE6Static_" + asset; Vector3[] vertices = value.vertices; Vector3[] normals = value.normals; Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int j = 0; j < vertices.Length; j++) { vertices[j] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(vertices[j]); int num = j; Vector3 val = ((Matrix4x4)(ref transpose)).MultiplyVector(normals[j]); normals[num] = ((Vector3)(ref val)).normalized; } value.vertices = vertices; value.normals = normals; value.boneWeights = (BoneWeight[])(object)new BoneWeight[0]; value.bindposes = (Matrix4x4[])(object)new Matrix4x4[0]; value.RecalculateBounds(); value.RecalculateTangents(); staticMeshes.Add(key, value); return value; } private static bool Finite(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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_0028: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(v.x + v.y + v.z)) { return !float.IsInfinity(v.x + v.y + v.z); } return false; } } internal static class StartupGuard { internal static IEnumerator Run(Func<IEnumerator> create, Func<bool> expired, Action<Exception> failed) { Stack<IEnumerator> stack = new Stack<IEnumerator>(); Exception failure = null; try { stack.Push(create()); } catch (Exception ex) { failure = ex; } try { while (failure == null && stack.Count > 0) { bool flag = false; object obj = null; try { if (expired()) { throw new TimeoutException("Bubble Works startup deadline exceeded."); } IEnumerator enumerator = stack.Peek(); flag = enumerator.MoveNext(); if (flag) { obj = enumerator.Current; } else { stack.Pop(); (enumerator as IDisposable)?.Dispose(); } } catch (Exception ex2) { failure = ex2; } if (failure != null) { break; } if (flag) { if (obj is IEnumerator item) { stack.Push(item); } else { yield return obj; } } } } finally { if (stack.Count > 0 && failure == null) { failure = new OperationCanceledException("Bubble Works startup iterator was cancelled."); } while (stack.Count > 0) { try { (stack.Pop() as IDisposable)?.Dispose(); } catch (Exception ex3) { if (failure == null) { failure = ex3; } } } if (failure != null) { try { failed(failure); } catch { } } } } } internal sealed class TextureAssetCache { private readonly Dictionary<string, Texture2D> values = new Dictionary<string, Texture2D>(); internal Texture2D Load(string path, bool linear) { //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_006f: 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_007e: Expected O, but got Unknown byte[] array = File.ReadAllBytes(path); string key; using (SHA256 sHA = SHA256.Create()) { key = (linear ? "linear:" : "srgb:") + Convert.ToBase64String(sHA.ComputeHash(array)); } if (values.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear) { name = Path.GetFileName(path), anisoLevel = 4, filterMode = (FilterMode)2 }; try { if (!ImageConversion.LoadImage(val, array, true)) { throw new InvalidDataException("Cannot decode " + Path.GetFileName(path)); } values[key] = val; return val; } catch { Object.Destroy((Object)(object)val); throw; } } }
BepInEx/plugins/RodaniusSkins/engineer-castle-doctrine/EngineerCastleDoctrine.dll
Decompiled a week agousing 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.Security.Cryptography; using System.Text; using BepInEx; using EngineerOneManBandPlaytest; using EntityStates; using EntityStates.Engi.EngiWeapon; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.Projectile; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EngineerCastleDoctrinePlaytest; [BepInPlugin("eclipseplaytest.engineer.e4", "Engineer - Castle Doctrine (Playtest)", "0.3.1")] [BepInDependency("eclipseplaytest.engineer.e3", "0.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EngineerCastleDoctrine : BaseUnityPlugin { private sealed class Prepared { public SkinDef[] OriginalSkins; public SkinDef[] CommittedSkins; public string BodyName; public GameObject Model; public ModelSkinController Controller; public SkinDef Skin; public Mesh Mesh; public Mesh Reference; public Material Material; } private sealed class Design { public string Slug; public string Name; public Color32[] Colors; public Design(string slug, string name, Color32[] colors) { Slug = slug; Name = name; Colors = colors; } } private sealed class MeshBasis { public Mesh Reference; public Mesh Authored; } public sealed class BandVisuals : MonoBehaviour { private sealed class Saved { public Renderer Renderer; public Mesh Mesh; public Material[] Materials; public Bounds Bounds; public bool Offscreen; public bool ChangeMesh; public bool ChangeMaterial; public Mesh AssignedMesh; public Material[] AssignedMaterials; public bool ChangeBounds; public Bounds AssignedBounds; public bool ChangeOffscreen; public bool AssignedOffscreen; } private readonly Dictionary<Renderer, Saved> changed = new Dictionary<Renderer, Saved>(); private ModelSkinController controller; private CharacterBody body; private EntityStateMachine[] machines; private bool lobbyDirty = true; private static readonly FieldInfo Blueprint = typeof(PlaceTurret).GetField("blueprints", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo Wrist = typeof(PlaceTurret).GetField("wristDisplayObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private void Applied(int index) { if (!OwnSkin() && changed.Count > 0) { Restore(); } lobbyDirty = true; } private void Start() { controller = ((Component)this).GetComponentInChildren<ModelSkinController>(true); body = ((Component)this).GetComponentInParent<CharacterBody>(); machines = (EntityStateMachine[])(Object.op_Implicit((Object)(object)body) ? ((Array)((Component)body).GetComponents<EntityStateMachine>()) : ((Array)new EntityStateMachine[0])); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; } } private bool OwnSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length && Object.op_Implicit((Object)(object)controller.skins[currentSkinIndex])) { return ((Object)controller.skins[currentSkinIndex]).name.StartsWith("skinEclipsePlaytestEngineerE4_", StringComparison.Ordinal); } return false; } private Saved Save(Renderer r) { //IL_0074: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (changed.TryGetValue(r, out var value)) { return value; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((r is SkinnedMeshRenderer) ? r : null); MeshFilter component = ((Component)r).GetComponent<MeshFilter>(); value = new Saved { Renderer = r, Materials = r.sharedMaterials, Mesh = (Object.op_Implicit((Object)(object)val) ? val.sharedMesh : (Object.op_Implicit((Object)(object)component) ? component.sharedMesh : null)), Bounds = (Bounds)(Object.op_Implicit((Object)(object)val) ? ((Renderer)val).localBounds : default(Bounds)), Offscreen = (Object.op_Implicit((Object)(object)val) && val.updateWhenOffscreen) }; changed.Add(r, value); return value; } private void ApplySkinned(SkinnedMeshRenderer r, string asset, bool keepMaterial) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) Saved saved = Save((Renderer)(object)r); saved.ChangeMesh = true; saved.ChangeMaterial = !keepMaterial; Mesh val = (saved.AssignedMesh = instance.MeshFor(asset, r, saved.Mesh)); if ((Object)(object)r.sharedMesh != (Object)(object)val) { r.sharedMesh = val; Mesh val2 = new Mesh(); r.BakeMesh(val2); Bounds bounds = saved.Bounds; Bounds bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).min); bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).max); ((Bounds)(ref bounds)).Expand(((Bounds)(ref bounds)).size * 0.5f); ((Renderer)r).localBounds = bounds; saved.ChangeBounds = true; saved.AssignedBounds = bounds; Object.Destroy((Object)(object)val2); } r.updateWhenOffscreen = true; saved.ChangeOffscreen = true; saved.AssignedOffscreen = true; if (!keepMaterial) { ((Renderer)r).sharedMaterial = instance.assetMaterials[asset]; saved.AssignedMaterials = ((Renderer)r).sharedMaterials; } } private void Restore() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) foreach (Saved value in changed.Values) { if (!Object.op_Implicit((Object)(object)value.Renderer)) { continue; } Renderer renderer = value.Renderer; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); MeshFilter component = ((Component)value.Renderer).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)val)) { if (value.ChangeMesh && (Object)(object)val.sharedMesh == (Object)(object)value.AssignedMesh) { if (value.ChangeBounds && ((Renderer)val).localBounds == value.AssignedBounds) { ((Renderer)val).localBounds = value.Bounds; } if (value.ChangeOffscreen && val.updateWhenOffscreen == value.AssignedOffscreen) { val.updateWhenOffscreen = value.Offscreen; } val.sharedMesh = value.Mesh; } } else if (Object.op_Implicit((Object)(object)component) && value.ChangeMesh && (Object)(object)component.sharedMesh == (Object)(object)value.AssignedMesh) { component.sharedMesh = value.Mesh; } if (value.ChangeMaterial && value.AssignedMaterials != null && value.Renderer.sharedMaterials.SequenceEqual(value.AssignedMaterials)) { value.Renderer.sharedMaterials = value.Materials; } } changed.Clear(); } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)instance) || !instance.registered) { return; } Renderer[] array = changed.Keys.Where((Renderer r) => !Object.op_Implicit((Object)(object)r)).ToArray(); foreach (Renderer key in array) { changed.Remove(key); } if (!OwnSkin()) { if (changed.Count > 0) { Restore(); } lobbyDirty = true; return; } if (lobbyDirty) { SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { string text = MineAsset((Renderer)(object)val); if (text != null) { ApplySkinned(val, text, keepMaterial: false); } else if (!Object.op_Implicit((Object)(object)body) && val.bones.Length == 15 && Object.op_Implicit((Object)(object)((Component)this).transform.Find("TurretHolder")) && ((Component)val).transform.IsChildOf(((Component)this).transform.Find("TurretHolder"))) { ApplySkinned(val, "turret", keepMaterial: false); } } MeshRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren2) { string text2 = MineAsset((Renderer)(object)val2); if (text2 != null) { MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)component)) { Saved saved = Save((Renderer)(object)val2); saved.ChangeMesh = true; component.sharedMesh = instance.StaticMeshFor(text2, saved.Mesh); saved.AssignedMesh = component.sharedMesh; saved.ChangeMaterial = true; ((Renderer)val2).sharedMaterial = instance.assetMaterials[text2]; saved.AssignedMaterials = ((Renderer)val2).sharedMaterials; } } } lobbyDirty = false; } if (!Object.op_Implicit((Object)(object)body)) { return; } EntityStateMachine[] array2 = machines; for (int num = 0; num < array2.Length; num++) { EntityState state = array2[num].state; PlaceTurret val3 = (PlaceTurret)(object)((state is PlaceTurret) ? state : null); if (val3 == null) { continue; } string asset = ((val3 is PlaceWalkerTurret) ? "walker" : "turret"); object? obj = Blueprint?.GetValue(val3); BlueprintController val4 = (BlueprintController)((obj is BlueprintController) ? obj : null); if (Object.op_Implicit((Object)(object)val4)) { SkinnedMeshRenderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val5 in componentsInChildren) { if (val5.bones.Length == 15) { ApplySkinned(val5, asset, keepMaterial: true); } } } object? obj2 = Wrist?.GetValue(val3); GameObject val6 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (!Object.op_Implicit((Object)(object)val6)) { continue; } MeshFilter[] componentsInChildren3 = val6.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val7 in componentsInChildren3) { if (((Object)val7).name == "EngiTurretMesh") { Renderer component2 = ((Component)val7).GetComponent<Renderer>(); Saved saved2 = Save(component2); saved2.ChangeMesh = true; val7.sharedMesh = instance.StaticMeshFor(asset, saved2.Mesh); saved2.AssignedMesh = val7.sharedMesh; } } } } private void OnDisable() { Restore(); lobbyDirty = true; } private void OnDestroy() { if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } } } public const string Guid = "eclipseplaytest.engineer.e4"; public const string Version = "0.3.1"; private static EngineerCastleDoctrine instance; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private float registrationDeadline; private string folder; private SkinDef skin; private GameObject modelPrefab; private string startupStage = "awake"; private readonly List<BandVisuals> startupVisuals = new List<BandVisuals>(); private readonly List<Prepared> prepared = new List<Prepared>(); private bool registered; private static readonly Design[] Designs = new Design[1] { new Design("castle-doctrine", "Castle Doctrine (Playtest)", (Color32[])(object)new Color32[4] { new Color32((byte)216, (byte)209, (byte)181, byte.MaxValue), new Color32((byte)141, (byte)43, (byte)38, byte.MaxValue), new Color32((byte)61, (byte)65, (byte)65, byte.MaxValue), new Color32((byte)161, (byte)143, (byte)95, byte.MaxValue) }) }; private readonly TextureAssetCache textureCache = new TextureAssetCache(); private GameObject cosmeticStorage; private readonly Dictionary<string, MeshBasis> canonicalBases = new Dictionary<string, MeshBasis>(); private readonly Dictionary<string, Material> assetMaterials = new Dictionary<string, Material>(); private readonly Dictionary<string, Mesh> remappedMeshes = new Dictionary<string, Mesh>(); private readonly Dictionary<string, Mesh> staticMeshes = new Dictionary<string, Mesh>(); private void Awake() { folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); instance = this; SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(EngineerCastleDoctrine)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; } [SystemInitializer(new Type[] { typeof(BodyCatalog), typeof(ProjectileCatalog), typeof(SurvivorCatalog), typeof(EngineerOneManBand) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { return EmptyStartup(); } instance.registrationDeadline = Time.realtimeSinceStartup + 60f; return StartupGuard.Run(instance.RegisterAsync, () => Time.realtimeSinceStartup > instance.registrationDeadline, delegate(Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E4_STARTUP_DISABLED version=0.3.1 stage=" + instance.startupStage + " " + ex)); try { instance.RollbackRegistration(); ((BaseUnityPlugin)instance).Logger.LogWarning((object)"ENGINEER_E4_ROLLBACK_OK existing skin arrays retained."); } catch (Exception ex2) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E4_ROLLBACK_FAILED " + ex2)); } }); } private static IEnumerator EmptyStartup() { yield break; } private void Stage(string value) { startupStage = value; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E4_STARTUP_STAGE version=0.3.1 stage=" + value)); } private void RollbackRegistration() { registered = false; foreach (Prepared item in prepared) { if (Object.op_Implicit((Object)(object)item.Controller) && item.CommittedSkins != null && item.Controller.skins == item.CommittedSkins) { item.Controller.skins = item.OriginalSkins; } } foreach (BandVisuals startupVisual in startupVisuals) { if (Object.op_Implicit((Object)(object)startupVisual)) { Object.Destroy((Object)(object)startupVisual); } } startupVisuals.Clear(); if (Object.op_Implicit((Object)(object)cosmeticStorage)) { Object.Destroy((Object)(object)cosmeticStorage); cosmeticStorage = null; } } private void ValidateAndCommit() { foreach (Prepared p in prepared) { if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Private bake produced no runtime skin: " + p.BodyName); } if (p.Controller.skins != p.OriginalSkins) { throw new InvalidOperationException("Skin list changed during startup: " + p.BodyName); } if (p.OriginalSkins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == ((Object)p.Skin).name)) { throw new InvalidOperationException("Duplicate Castle Doctrine skin: " + ((Object)p.Skin).name); } p.CommittedSkins = p.OriginalSkins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { p.Skin }).ToArray(); } foreach (Prepared item in prepared) { item.Controller.skins = item.CommittedSkins; } } private IEnumerator RegisterAsync() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E4_REGISTRATION_BEGIN 0.3.1"); string[][] array = new string[3][] { new string[4] { "EngiTurretBody", "turret", "15", "skinEngiTurretDefault" }, new string[4] { "EngiWalkerTurretBody", "walker", "15", "skinEngiWalkerTurretDefault" }, new string[4] { "EngiBody", "castle-doctrine", "83", "skinEngiDefault" } }; foreach (string[] array2 in array) { Stage("prepare:" + array2[0]); yield return Prepare(array2[0], array2[1], int.Parse(array2[2]), array2[3]); } Prepared bodySkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiBody"); bodySkin.Skin.skinDefParams.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[2] { new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiTurretBody").Skin }, new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiWalkerTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiWalkerTurretBody").Skin } }; Stage("prepare:mine-ghosts"); yield return PrepareMineGhosts(bodySkin.Skin); foreach (Prepared p in prepared) { Stage("private-bake:" + p.BodyName); ValidateSkin(p); yield return p.Skin.BakeAsync(); if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Bake returned without runtime skin: " + p.BodyName); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E4_PRIVATE_BAKE_OK body=" + p.BodyName)); } Stage("commit"); ValidateAndCommit(); modelPrefab = bodySkin.Model; skin = bodySkin.Skin; foreach (Prepared item in prepared) { if (!Object.op_Implicit((Object)(object)item.Model.GetComponent<BandVisuals>())) { startupVisuals.Add(item.Model.AddComponent<BandVisuals>()); } } registered = true; Stage("registered"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E4_REGISTERED Castle Doctrine body, both turrets, pressure and spider mines; native Animator retained; unlocked=true version=0.3.1"); } private IEnumerator Prepare(string bodyName, string assetName, int boneCount, string defaultName) { GameObject val = BodyCatalog.FindBodyPrefab(bodyName); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing body " + bodyName); } GameObject model = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = model.GetComponent<ModelSkinController>(); SkinDef baseSkin = null; if (Object.op_Implicit((Object)(object)controller) && controller.skins != null && controller.skins.Length != 0) { baseSkin = controller.skins[0]; } if (!Object.op_Implicit((Object)(object)baseSkin)) { AsyncOperationHandle<SkinDef> h = Addressables.LoadAssetAsync<SkinDef>((object)("RoR2/Base/Engi/" + defaultName + ".asset")); retainedAssets.Add(AsyncOperationHandle<SkinDef>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline("default skin " + bodyName); yield return null; } baseSkin = h.Result; } if (!Object.op_Implicit((Object)(object)baseSkin)) { throw new InvalidOperationException("Missing default skin " + bodyName); } SkinDefParams bp = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)bp) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> h2 = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(h2)); while (!h2.IsDone) { CheckLoadDeadline("parameters " + bodyName); yield return null; } bp = h2.Result; } if (!Object.op_Implicit((Object)(object)bp)) { throw new InvalidOperationException("Missing parameters " + bodyName); } SkinnedMeshRenderer target = model.GetComponentsInChildren<SkinnedMeshRenderer>(true).Single((SkinnedMeshRenderer r) => r.bones.Length == boneCount); Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = bp.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference)) { AsyncOperationHandle<Mesh> h3 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(h3)); while (!h3.IsDone) { CheckLoadDeadline("mesh " + bodyName); yield return null; } reference = h3.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != target.bones.Length) { throw new InvalidOperationException("Bind pose mismatch " + bodyName); } RendererInfo ri = bp.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = ri.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && ri.defaultMaterialAddress != null && ((AssetReference)ri.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> h4 = Addressables.LoadAssetAsync<Material>(((AssetReference)ri.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(h4)); while (!h4.IsDone) { CheckLoadDeadline("material " + bodyName); yield return null; } val3 = h4.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Missing native material " + bodyName); } Mesh val4 = ReadMesh(Path.Combine(folder, assetName + ".meshbin"), target, reference); ((Object)val4).name = "EclipsePlaytest_EngineerE4_" + assetName; Material val5 = MakeMaterial(assetName, val3); canonicalBases[assetName] = new MeshBasis { Reference = reference, Authored = val4 }; ri.defaultMaterial = val5; ri.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { ri }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = val4, meshAddress = new AssetReferenceT<Mesh>("") } }; SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>(); ((Object)val7).name = "skinEclipsePlaytestEngineerE4_" + assetName; val7.nameToken = "ECLIPSEPLAYTEST_ENGINEER_E4_" + assetName.ToUpperInvariant().Replace('-', '_'); LanguageAPI.Add(val7.nameToken, (bodyName == "EngiBody") ? "Castle Doctrine (Playtest)" : ("Castle Doctrine " + assetName)); val7.icon = CreateIcon(Designs[0].Colors); val7.unlockableDef = null; val7.rootObject = model; val7.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; val7.skinDefParams = val6; if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { throw new InvalidOperationException("Missing native skin controller/list: " + bodyName); } prepared.Add(new Prepared { BodyName = bodyName, Model = model, Controller = controller, Skin = val7, Mesh = val4, Reference = reference, Material = val5, OriginalSkins = controller.skins }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E4_PREPARED body=" + bodyName + " vertices=" + val4.vertexCount + " unlocked=true")); } private static void ValidateSkin(Prepared p) { //IL_00ee: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) SkinDef skin = p.Skin; SkinDefParams skinDefParams = skin.skinDefParams; if (!Object.op_Implicit((Object)(object)skin.rootObject) || !Object.op_Implicit((Object)(object)skinDefParams) || skin.baseSkins == null || skin.baseSkins.Any((SkinDef s) => !Object.op_Implicit((Object)(object)s) || s == skin)) { throw new InvalidOperationException("Invalid skin graph: " + p.BodyName); } if (skin.skinDefParamsAddress == null) { skin.skinDefParamsAddress = new AssetReferenceT<SkinDefParams>(""); } if (skinDefParams.rendererInfos == null || skinDefParams.meshReplacements == null || skinDefParams.gameObjectActivations == null || skinDefParams.lightReplacements == null || skinDefParams.projectileGhostReplacements == null || skinDefParams.minionSkinReplacements == null) { throw new InvalidOperationException("Null parameter collection: " + p.BodyName); } RendererInfo[] rendererInfos = skinDefParams.rendererInfos; foreach (RendererInfo val in rendererInfos) { if (!Object.op_Implicit((Object)(object)val.renderer) || !Object.op_Implicit((Object)(object)val.defaultMaterial) || !((Component)val.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid material/renderer root: " + p.BodyName); } } MeshReplacement[] meshReplacements = skinDefParams.meshReplacements; foreach (MeshReplacement val2 in meshReplacements) { if (!Object.op_Implicit((Object)(object)val2.renderer) || !Object.op_Implicit((Object)(object)val2.mesh) || !((Component)val2.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid mesh/renderer root: " + p.BodyName); } } ProjectileGhostReplacement[] projectileGhostReplacements = skinDefParams.projectileGhostReplacements; foreach (ProjectileGhostReplacement val3 in projectileGhostReplacements) { if (!Object.op_Implicit((Object)(object)val3.projectilePrefab) || !Object.op_Implicit((Object)(object)val3.projectileGhostReplacementPrefab) || ProjectileCatalog.GetProjectileIndex(val3.projectilePrefab) < 0) { throw new InvalidOperationException("Unregistered mine projectile: " + p.BodyName); } } MinionSkinReplacement[] minionSkinReplacements = skinDefParams.minionSkinReplacements; foreach (MinionSkinReplacement val4 in minionSkinReplacements) { if (!Object.op_Implicit((Object)(object)val4.minionBodyPrefab) || !Object.op_Implicit((Object)(object)val4.minionSkin) || val4.minionSkin.runtimeSkin == null) { throw new InvalidOperationException("Unbaked turret skin: " + p.BodyName); } } } private static Sprite CreateIcon(Color32[] colors) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00c6: 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_0083: 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_0071: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : colors[num]); } } val.SetPixels32(array); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private void CheckLoadDeadline(string asset) { if (Time.realtimeSinceStartup > registrationDeadline) { throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin."); } } private void SyncDisplaySkins() { if (!registered) { return; } try { SyncDisplaySkinsChecked(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("ENGINEER_E4_DISPLAY_SYNC_FAILED version=0.3.1 " + ex)); } } private void SyncDisplaySkinsChecked() { SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "EngiBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)val.displayPrefab.GetComponent<BandVisuals>())) { val.displayPrefab.AddComponent<BandVisuals>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E4_DISPLAY_READY version=0.3.1 skins=" + val2.skins.Length + " catalogSkins=" + SkinCatalog.skinCount)); } } private Texture2D ReadTexture(string name, bool linear) { return textureCache.Load(Path.Combine(folder, name), linear); } private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_0592: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (new string(binaryReader.ReadChars(4)) != "PWE2") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0 || !hashSet.Add(array[i])) { throw new InvalidDataException("Missing/duplicate reference bone: " + name); } } Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num3]; for (int num5 = 0; num5 < num3; num5++) { Matrix4x4 val = default(Matrix4x4); for (int num6 = 0; num6 < 4; num6++) { for (int num7 = 0; num7 < 4; num7++) { float num8 = binaryReader.ReadSingle(); if (float.IsNaN(num8) || float.IsInfinity(num8)) { throw new InvalidDataException("Invalid bind matrix."); } ((Matrix4x4)(ref val))[num6, num7] = num8; } } if (Math.Abs(((Matrix4x4)(ref val)).determinant) < 1E-05f) { throw new InvalidDataException("Singular bind matrix."); } array2[array[num5]] = val; } Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector3[] array4 = (Vector3[])(object)new Vector3[num]; Vector2[] array5 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array6 = (BoneWeight[])(object)new BoneWeight[num]; for (int num9 = 0; num9 < num; num9++) { array3[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array5[num9] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); int[] array7 = new int[4]; for (int num10 = 0; num10 < 4; num10++) { int num11 = binaryReader.ReadInt32(); if (num11 < 0 || num11 >= num3) { throw new InvalidDataException("Bone out of range."); } array7[num10] = array[num11]; } float[] array8 = new float[4]; for (int num12 = 0; num12 < 4; num12++) { array8[num12] = binaryReader.ReadSingle(); } if (array8.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array8.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } if (!Finite(array3[num9]) || !Finite(array4[num9])) { throw new InvalidDataException("Non-finite vertex."); } int num13 = num9; BoneWeight val2 = default(BoneWeight); ((BoneWeight)(ref val2)).boneIndex0 = array7[0]; ((BoneWeight)(ref val2)).boneIndex1 = array7[1]; ((BoneWeight)(ref val2)).boneIndex2 = array7[2]; ((BoneWeight)(ref val2)).boneIndex3 = array7[3]; ((BoneWeight)(ref val2)).weight0 = array8[0]; ((BoneWeight)(ref val2)).weight1 = array8[1]; ((BoneWeight)(ref val2)).weight2 = array8[2]; ((BoneWeight)(ref val2)).weight3 = array8[3]; array6[num13] = val2; } int[] array9 = new int[num2]; for (int num14 = 0; num14 < num2; num14++) { array9[num14] = binaryReader.ReadInt32(); if (array9[num14] < 0 || array9[num14] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } if (Object.op_Implicit((Object)(object)reference) && reference.bindposes.Length == num3) { Matrix4x4[] bindposes = reference.bindposes; int num15 = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Base"); if (num15 < 0) { num15 = 0; } Matrix4x4 b = ((Matrix4x4)(ref bindposes[num15])).inverse * array2[num15]; bool flag = true; for (int num16 = 0; num16 < num3; num16++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[num16])).inverse * array2[num16], b, 0.0002f)) { flag = false; } } if (!flag) { if (num3 != 2 && (num3 != 14 || !renderer.bones.Any((Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Screw"))) { throw new InvalidDataException("Unsupported nonuniform bind variant: " + ((Object)renderer).name); } Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int num17 = 0; num17 < num; num17++) { array3[num17] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(array3[num17]); int num18 = num17; Vector3 val3 = ((Matrix4x4)(ref transpose)).MultiplyVector(array4[num17]); array4[num18] = ((Vector3)(ref val3)).normalized; } array2 = bindposes; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E4_MINE_BIND_VARIANT renderer=" + ((Object)renderer).name + " reference=" + ((Object)reference).name)); } } Mesh val4 = new Mesh { name = "EclipsePlaytestEngineerCastleDoctrine", indexFormat = (IndexFormat)(num > 65535), vertices = array3, normals = array4, uv = array5, boneWeights = array6, bindposes = array2, triangles = array9 }; val4.RecalculateBounds(); val4.RecalculateTangents(); return val4; } private Material MakeMaterial(string asset, Material source) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (assetMaterials.TryGetValue(asset, out var value)) { return value; } if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader)) { throw new InvalidOperationException("Missing shader for " + asset); } value = new Material(source) { name = "matEclipsePlaytest_EngineerE4_" + asset }; value.SetTexture("_MainTex", (Texture)(object)ReadTexture(asset + "-albedo-spec.png", linear: false)); value.SetTexture("_NormalTex", (Texture)(object)ReadTexture(asset + "-normal.png", linear: true)); value.SetTexture("_EmTex", (Texture)(object)ReadTexture(asset + "-emission.png", linear: false)); value.SetColor("_Color", Color.white); value.SetFloat("_NormalStrength", 0.3f); value.SetFloat("_Smoothness", 0.28f); value.SetFloat("_SpecularStrength", 0.35f); value.SetFloat("_SpecularExponent", 8f); value.SetFloat("_EmPower", asset.EndsWith("mine", StringComparison.Ordinal) ? 0.4f : 0f); value.DisableKeyword("LIMBREMOVAL"); value.SetFloat("_LimbRemovalOn", 0f); assetMaterials.Add(asset, value); return value; } private static string MineAsset(Renderer r) { if (((Object)r).name == "EngiMineMesh") { return "pressure-mine"; } if (((Object)r).name == "EngiSpiderMineMesh") { return "spider-mine"; } return null; } private IEnumerator PrepareMineGhosts(SkinDef bodySkin) { cosmeticStorage = new GameObject("CastleDoctrineCosmeticPrefabs"); cosmeticStorage.SetActive(false); Object.DontDestroyOnLoad((Object)(object)cosmeticStorage); List<ProjectileGhostReplacement> replacements = new List<ProjectileGhostReplacement>(); string[] array = new string[2] { "EngiMine", "SpiderMine" }; foreach (string name in array) { AsyncOperationHandle<GameObject> h = Addressables.LoadAssetAsync<GameObject>((object)("RoR2/Base/Engi/" + name + ".prefab")); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline(name); yield return null; } if (!Object.op_Implicit((Object)(object)h.Result)) { throw new InvalidOperationException("Missing projectile " + name); } ProjectileController component = h.Result.GetComponent<ProjectileController>(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("Missing ProjectileController " + name); } GameObject val = component.ghostPrefab; if (!Object.op_Implicit((Object)(object)val) && component.ghostPrefabAddress != null && ((AssetReference)component.ghostPrefabAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<GameObject> gh = Addressables.LoadAssetAsync<GameObject>(((AssetReference)component.ghostPrefabAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(gh)); while (!gh.IsDone) { CheckLoadDeadline(name + " ghost"); yield return null; } val = gh.Result; } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing mine ghost " + name); } GameObject val2 = Object.Instantiate<GameObject>(val, cosmeticStorage.transform); ((Object)val2).name = "EclipseCastleDoctrine_" + name + "Ghost"; string asset = ((name == "EngiMine") ? "pressure-mine" : "spider-mine"); SkinnedMeshRenderer[] array2 = (from r in val2.GetComponentsInChildren<SkinnedMeshRenderer>(true) where MineAsset((Renderer)(object)r) == asset select r).ToArray(); if (array2.Length != 1) { throw new InvalidOperationException("Ambiguous mine renderer " + name + ": " + array2.Length); } SkinnedMeshRenderer val3 = array2[0]; int num = ((asset == "pressure-mine") ? 2 : 14); if (val3.bones.Length != num || !Object.op_Implicit((Object)(object)val3.sharedMesh)) { throw new InvalidOperationException("Missing native mine rig " + name); } Mesh sharedMesh = val3.sharedMesh; Mesh val4 = MeshFor(asset, val3); Material sharedMaterial = MakeMaterial(asset, ((Renderer)val3).sharedMaterial); canonicalBases[asset] = new MeshBasis { Reference = sharedMesh, Authored = val4 }; val3.sharedMesh = val4; ((Renderer)val3).sharedMaterial = sharedMaterial; Mesh val5 = new Mesh(); val3.BakeMesh(val5); Bounds localBounds = ((Renderer)val3).localBounds; Bounds bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).min); bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).max); ((Bounds)(ref localBounds)).Expand(((Bounds)(ref localBounds)).size * 0.5f); ((Renderer)val3).localBounds = localBounds; Object.Destroy((Object)(object)val5); val3.updateWhenOffscreen = true; val2.SetActive(true); replacements.Add(new ProjectileGhostReplacement { projectilePrefab = h.Result, projectileGhostReplacementPrefab = val2, ghostReplacementAddress = new AssetReferenceT<GameObject>("") }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E4_MINE_READY asset=" + asset + " vertices=" + val4.vertexCount + " native effects/controller preserved")); } bodySkin.skinDefParams.projectileGhostReplacements = replacements.ToArray(); } private Mesh MeshFor(string asset, SkinnedMeshRenderer target, Mesh nativeReference = null) { if (!Object.op_Implicit((Object)(object)nativeReference)) { nativeReference = target.sharedMesh; } string key = asset + "|" + (Object.op_Implicit((Object)(object)nativeReference) ? ((Object)nativeReference).GetInstanceID() : 0) + "|" + string.Join("|", target.bones.Select((Transform b) => (!Object.op_Implicit((Object)(object)b)) ? "<null>" : ((Object)b).name)); if (!remappedMeshes.TryGetValue(key, out var value)) { value = ReadMesh(Path.Combine(folder, asset + ".meshbin"), target, nativeReference); remappedMeshes.Add(key, value); } return value; } private static bool SameMatrix(Matrix4x4 a, Matrix4x4 b, float tolerance) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (Math.Abs(((Matrix4x4)(ref a))[i, j] - ((Matrix4x4)(ref b))[i, j]) > tolerance) { return false; } } } return true; } private Mesh StaticMeshFor(string asset, Mesh reference) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)reference)) { throw new InvalidOperationException("Missing static reference " + asset); } string key = asset + "|" + ((Object)reference).GetInstanceID(); if (staticMeshes.TryGetValue(key, out var value)) { return value; } if (!canonicalBases.TryGetValue(asset, out var value2)) { throw new InvalidOperationException("Missing canonical rig " + asset); } Matrix4x4[] bindposes = reference.bindposes; Matrix4x4[] bindposes2 = value2.Authored.bindposes; if (bindposes.Length != bindposes2.Length || bindposes.Length == 0) { throw new InvalidOperationException("Static bind count " + asset); } Matrix4x4 b = ((Matrix4x4)(ref bindposes[0])).inverse * bindposes2[0]; for (int i = 1; i < bindposes.Length; i++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[i])).inverse * bindposes2[i], b, 0.0002f)) { if (asset != "pressure-mine" && asset != "spider-mine") { throw new InvalidOperationException("Nonuniform static bind conversion " + asset + " bone " + i); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E4_STATIC_MINE_BIND_VARIANT " + asset + " uses canonical assembled rest shape")); break; } } value = Object.Instantiate<Mesh>(value2.Authored); ((Object)value).name = "EclipseEngineerE4Static_" + asset; Vector3[] vertices = value.vertices; Vector3[] normals = value.normals; Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int j = 0; j < vertices.Length; j++) { vertices[j] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(vertices[j]); int num = j; Vector3 val = ((Matrix4x4)(ref transpose)).MultiplyVector(normals[j]); normals[num] = ((Vector3)(ref val)).normalized; } value.vertices = vertices; value.normals = normals; value.boneWeights = (BoneWeight[])(object)new BoneWeight[0]; value.bindposes = (Matrix4x4[])(object)new Matrix4x4[0]; value.RecalculateBounds(); value.RecalculateTangents(); staticMeshes.Add(key, value); return value; } private static bool Finite(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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_0028: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(v.x + v.y + v.z)) { return !float.IsInfinity(v.x + v.y + v.z); } return false; } } internal static class StartupGuard { internal static IEnumerator Run(Func<IEnumerator> create, Func<bool> expired, Action<Exception> failed) { Stack<IEnumerator> stack = new Stack<IEnumerator>(); Exception failure = null; try { stack.Push(create()); } catch (Exception ex) { failure = ex; } try { while (failure == null && stack.Count > 0) { bool flag = false; object obj = null; try { if (expired()) { throw new TimeoutException("Castle Doctrine startup deadline exceeded."); } IEnumerator enumerator = stack.Peek(); flag = enumerator.MoveNext(); if (flag) { obj = enumerator.Current; } else { stack.Pop(); (enumerator as IDisposable)?.Dispose(); } } catch (Exception ex2) { failure = ex2; } if (failure != null) { break; } if (flag) { if (obj is IEnumerator item) { stack.Push(item); } else { yield return obj; } } } } finally { if (stack.Count > 0 && failure == null) { failure = new OperationCanceledException("Castle Doctrine startup iterator was cancelled."); } while (stack.Count > 0) { try { (stack.Pop() as IDisposable)?.Dispose(); } catch (Exception ex3) { if (failure == null) { failure = ex3; } } } if (failure != null) { try { failed(failure); } catch { } } } } } internal sealed class TextureAssetCache { private readonly Dictionary<string, Texture2D> values = new Dictionary<string, Texture2D>(); internal Texture2D Load(string path, bool linear) { //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_006f: 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_007e: Expected O, but got Unknown byte[] array = File.ReadAllBytes(path); string key; using (SHA256 sHA = SHA256.Create()) { key = (linear ? "linear:" : "srgb:") + Convert.ToBase64String(sHA.ComputeHash(array)); } if (values.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear) { name = Path.GetFileName(path), anisoLevel = 4, filterMode = (FilterMode)2 }; try { if (!ImageConversion.LoadImage(val, array, true)) { throw new InvalidDataException("Cannot decode " + Path.GetFileName(path)); } values[key] = val; return val; } catch { Object.Destroy((Object)(object)val); throw; } } }
BepInEx/plugins/RodaniusSkins/engineer-one-man-band/EngineerOneManBand.dll
Decompiled a week agousing 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.Security.Cryptography; using System.Text; using BepInEx; using EngineerUnqualifiedPersonnelPlaytest; using EntityStates; using EntityStates.Engi.EngiWeapon; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.Projectile; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EngineerOneManBandPlaytest; [BepInPlugin("eclipseplaytest.engineer.e3", "Engineer - One-Man Band (Playtest)", "0.3.1")] [BepInDependency("rodanius.engineer.unqualifiedpersonnel", "0.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EngineerOneManBand : BaseUnityPlugin { private sealed class Prepared { public SkinDef[] OriginalSkins; public SkinDef[] CommittedSkins; public string BodyName; public GameObject Model; public ModelSkinController Controller; public SkinDef Skin; public Mesh Mesh; public Mesh Reference; public Material Material; } private sealed class Design { public string Slug; public string Name; public Color32[] Colors; public Design(string slug, string name, Color32[] colors) { Slug = slug; Name = name; Colors = colors; } } private sealed class MeshBasis { public Mesh Reference; public Mesh Authored; } public sealed class BandVisuals : MonoBehaviour { private sealed class Saved { public Renderer Renderer; public Mesh Mesh; public Material[] Materials; public Bounds Bounds; public bool Offscreen; public bool ChangeMesh; public bool ChangeMaterial; public Mesh AssignedMesh; public Material[] AssignedMaterials; public bool ChangeBounds; public Bounds AssignedBounds; public bool ChangeOffscreen; public bool AssignedOffscreen; } private readonly Dictionary<Renderer, Saved> changed = new Dictionary<Renderer, Saved>(); private ModelSkinController controller; private CharacterBody body; private EntityStateMachine[] machines; private bool lobbyDirty = true; private static readonly FieldInfo Blueprint = typeof(PlaceTurret).GetField("blueprints", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo Wrist = typeof(PlaceTurret).GetField("wristDisplayObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private void Applied(int index) { if (!OwnSkin() && changed.Count > 0) { Restore(); } lobbyDirty = true; } private void Start() { controller = ((Component)this).GetComponentInChildren<ModelSkinController>(true); body = ((Component)this).GetComponentInParent<CharacterBody>(); machines = (EntityStateMachine[])(Object.op_Implicit((Object)(object)body) ? ((Array)((Component)body).GetComponents<EntityStateMachine>()) : ((Array)new EntityStateMachine[0])); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; } } private bool OwnSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length && Object.op_Implicit((Object)(object)controller.skins[currentSkinIndex])) { return ((Object)controller.skins[currentSkinIndex]).name.StartsWith("skinEclipsePlaytestEngineerE3_", StringComparison.Ordinal); } return false; } private Saved Save(Renderer r) { //IL_0074: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (changed.TryGetValue(r, out var value)) { return value; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((r is SkinnedMeshRenderer) ? r : null); MeshFilter component = ((Component)r).GetComponent<MeshFilter>(); value = new Saved { Renderer = r, Materials = r.sharedMaterials, Mesh = (Object.op_Implicit((Object)(object)val) ? val.sharedMesh : (Object.op_Implicit((Object)(object)component) ? component.sharedMesh : null)), Bounds = (Bounds)(Object.op_Implicit((Object)(object)val) ? ((Renderer)val).localBounds : default(Bounds)), Offscreen = (Object.op_Implicit((Object)(object)val) && val.updateWhenOffscreen) }; changed.Add(r, value); return value; } private void ApplySkinned(SkinnedMeshRenderer r, string asset, bool keepMaterial) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) Saved saved = Save((Renderer)(object)r); saved.ChangeMesh = true; saved.ChangeMaterial = !keepMaterial; Mesh val = (saved.AssignedMesh = instance.MeshFor(asset, r, saved.Mesh)); if ((Object)(object)r.sharedMesh != (Object)(object)val) { r.sharedMesh = val; Mesh val2 = new Mesh(); r.BakeMesh(val2); Bounds bounds = saved.Bounds; Bounds bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).min); bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).max); ((Bounds)(ref bounds)).Expand(((Bounds)(ref bounds)).size * 0.5f); ((Renderer)r).localBounds = bounds; saved.ChangeBounds = true; saved.AssignedBounds = bounds; Object.Destroy((Object)(object)val2); } r.updateWhenOffscreen = true; saved.ChangeOffscreen = true; saved.AssignedOffscreen = true; if (!keepMaterial) { ((Renderer)r).sharedMaterial = instance.assetMaterials[asset]; saved.AssignedMaterials = ((Renderer)r).sharedMaterials; } } private void Restore() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) foreach (Saved value in changed.Values) { if (!Object.op_Implicit((Object)(object)value.Renderer)) { continue; } Renderer renderer = value.Renderer; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); MeshFilter component = ((Component)value.Renderer).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)val)) { if (value.ChangeMesh && (Object)(object)val.sharedMesh == (Object)(object)value.AssignedMesh) { if (value.ChangeBounds && ((Renderer)val).localBounds == value.AssignedBounds) { ((Renderer)val).localBounds = value.Bounds; } if (value.ChangeOffscreen && val.updateWhenOffscreen == value.AssignedOffscreen) { val.updateWhenOffscreen = value.Offscreen; } val.sharedMesh = value.Mesh; } } else if (Object.op_Implicit((Object)(object)component) && value.ChangeMesh && (Object)(object)component.sharedMesh == (Object)(object)value.AssignedMesh) { component.sharedMesh = value.Mesh; } if (value.ChangeMaterial && value.AssignedMaterials != null && value.Renderer.sharedMaterials.SequenceEqual(value.AssignedMaterials)) { value.Renderer.sharedMaterials = value.Materials; } } changed.Clear(); } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)instance) || !instance.registered) { return; } Renderer[] array = changed.Keys.Where((Renderer r) => !Object.op_Implicit((Object)(object)r)).ToArray(); foreach (Renderer key in array) { changed.Remove(key); } if (!OwnSkin()) { if (changed.Count > 0) { Restore(); } lobbyDirty = true; return; } if (lobbyDirty) { SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { string text = MineAsset((Renderer)(object)val); if (text != null) { ApplySkinned(val, text, keepMaterial: false); } else if (!Object.op_Implicit((Object)(object)body) && val.bones.Length == 15 && Object.op_Implicit((Object)(object)((Component)this).transform.Find("TurretHolder")) && ((Component)val).transform.IsChildOf(((Component)this).transform.Find("TurretHolder"))) { ApplySkinned(val, "turret", keepMaterial: false); } } MeshRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren2) { string text2 = MineAsset((Renderer)(object)val2); if (text2 != null) { MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)component)) { Saved saved = Save((Renderer)(object)val2); saved.ChangeMesh = true; component.sharedMesh = instance.StaticMeshFor(text2, saved.Mesh); saved.AssignedMesh = component.sharedMesh; saved.ChangeMaterial = true; ((Renderer)val2).sharedMaterial = instance.assetMaterials[text2]; saved.AssignedMaterials = ((Renderer)val2).sharedMaterials; } } } lobbyDirty = false; } if (!Object.op_Implicit((Object)(object)body)) { return; } EntityStateMachine[] array2 = machines; for (int num = 0; num < array2.Length; num++) { EntityState state = array2[num].state; PlaceTurret val3 = (PlaceTurret)(object)((state is PlaceTurret) ? state : null); if (val3 == null) { continue; } string asset = ((val3 is PlaceWalkerTurret) ? "walker" : "turret"); object? obj = Blueprint?.GetValue(val3); BlueprintController val4 = (BlueprintController)((obj is BlueprintController) ? obj : null); if (Object.op_Implicit((Object)(object)val4)) { SkinnedMeshRenderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val5 in componentsInChildren) { if (val5.bones.Length == 15) { ApplySkinned(val5, asset, keepMaterial: true); } } } object? obj2 = Wrist?.GetValue(val3); GameObject val6 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (!Object.op_Implicit((Object)(object)val6)) { continue; } MeshFilter[] componentsInChildren3 = val6.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val7 in componentsInChildren3) { if (((Object)val7).name == "EngiTurretMesh") { Renderer component2 = ((Component)val7).GetComponent<Renderer>(); Saved saved2 = Save(component2); saved2.ChangeMesh = true; val7.sharedMesh = instance.StaticMeshFor(asset, saved2.Mesh); saved2.AssignedMesh = val7.sharedMesh; } } } } private void OnDisable() { Restore(); lobbyDirty = true; } private void OnDestroy() { if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } } } public const string Guid = "eclipseplaytest.engineer.e3"; public const string Version = "0.3.1"; private static EngineerOneManBand instance; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private float registrationDeadline; private string folder; private SkinDef skin; private GameObject modelPrefab; private string startupStage = "awake"; private readonly List<BandVisuals> startupVisuals = new List<BandVisuals>(); private readonly List<Prepared> prepared = new List<Prepared>(); private bool registered; private static readonly Design[] Designs = new Design[1] { new Design("one-man-band", "One-Man Band (Playtest)", (Color32[])(object)new Color32[4] { new Color32((byte)167, (byte)36, (byte)41, byte.MaxValue), new Color32((byte)220, (byte)178, (byte)75, byte.MaxValue), new Color32((byte)28, (byte)39, (byte)59, byte.MaxValue), new Color32((byte)235, (byte)225, (byte)200, byte.MaxValue) }) }; private readonly TextureAssetCache textureCache = new TextureAssetCache(); private GameObject cosmeticStorage; private readonly Dictionary<string, MeshBasis> canonicalBases = new Dictionary<string, MeshBasis>(); private readonly Dictionary<string, Material> assetMaterials = new Dictionary<string, Material>(); private readonly Dictionary<string, Mesh> remappedMeshes = new Dictionary<string, Mesh>(); private readonly Dictionary<string, Mesh> staticMeshes = new Dictionary<string, Mesh>(); private void Awake() { folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); instance = this; SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(EngineerOneManBand)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; } [SystemInitializer(new Type[] { typeof(BodyCatalog), typeof(ProjectileCatalog), typeof(SurvivorCatalog), typeof(EngineerUnqualifiedPersonnel) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { return EmptyStartup(); } instance.registrationDeadline = Time.realtimeSinceStartup + 60f; return StartupGuard.Run(instance.RegisterAsync, () => Time.realtimeSinceStartup > instance.registrationDeadline, delegate(Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E3_STARTUP_DISABLED version=0.3.1 stage=" + instance.startupStage + " " + ex)); try { instance.RollbackRegistration(); ((BaseUnityPlugin)instance).Logger.LogWarning((object)"ENGINEER_E3_ROLLBACK_OK existing skin arrays retained."); } catch (Exception ex2) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E3_ROLLBACK_FAILED " + ex2)); } }); } private static IEnumerator EmptyStartup() { yield break; } private void Stage(string value) { startupStage = value; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E3_STARTUP_STAGE version=0.3.1 stage=" + value)); } private void RollbackRegistration() { registered = false; foreach (Prepared item in prepared) { if (Object.op_Implicit((Object)(object)item.Controller) && item.CommittedSkins != null && item.Controller.skins == item.CommittedSkins) { item.Controller.skins = item.OriginalSkins; } } foreach (BandVisuals startupVisual in startupVisuals) { if (Object.op_Implicit((Object)(object)startupVisual)) { Object.Destroy((Object)(object)startupVisual); } } startupVisuals.Clear(); if (Object.op_Implicit((Object)(object)cosmeticStorage)) { Object.Destroy((Object)(object)cosmeticStorage); cosmeticStorage = null; } } private void ValidateAndCommit() { foreach (Prepared p in prepared) { if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Private bake produced no runtime skin: " + p.BodyName); } if (p.Controller.skins != p.OriginalSkins) { throw new InvalidOperationException("Skin list changed during startup: " + p.BodyName); } if (p.OriginalSkins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == ((Object)p.Skin).name)) { throw new InvalidOperationException("Duplicate One-Man Band skin: " + ((Object)p.Skin).name); } p.CommittedSkins = p.OriginalSkins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { p.Skin }).ToArray(); } foreach (Prepared item in prepared) { item.Controller.skins = item.CommittedSkins; } } private IEnumerator RegisterAsync() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E3_REGISTRATION_BEGIN 0.3.1"); string[][] array = new string[3][] { new string[4] { "EngiTurretBody", "turret", "15", "skinEngiTurretDefault" }, new string[4] { "EngiWalkerTurretBody", "walker", "15", "skinEngiWalkerTurretDefault" }, new string[4] { "EngiBody", "one-man-band", "83", "skinEngiDefault" } }; foreach (string[] array2 in array) { Stage("prepare:" + array2[0]); yield return Prepare(array2[0], array2[1], int.Parse(array2[2]), array2[3]); } Prepared bodySkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiBody"); bodySkin.Skin.skinDefParams.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[2] { new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiTurretBody").Skin }, new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiWalkerTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiWalkerTurretBody").Skin } }; Stage("prepare:mine-ghosts"); yield return PrepareMineGhosts(bodySkin.Skin); foreach (Prepared p in prepared) { Stage("private-bake:" + p.BodyName); ValidateSkin(p); yield return p.Skin.BakeAsync(); if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Bake returned without runtime skin: " + p.BodyName); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E3_PRIVATE_BAKE_OK body=" + p.BodyName)); } Stage("commit"); ValidateAndCommit(); modelPrefab = bodySkin.Model; skin = bodySkin.Skin; foreach (Prepared item in prepared) { if (!Object.op_Implicit((Object)(object)item.Model.GetComponent<BandVisuals>())) { startupVisuals.Add(item.Model.AddComponent<BandVisuals>()); } } registered = true; Stage("registered"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E3_REGISTERED One-Man Band body, both turrets, pressure and spider mines; native Animator retained; unlocked=true version=0.3.1"); } private IEnumerator Prepare(string bodyName, string assetName, int boneCount, string defaultName) { GameObject val = BodyCatalog.FindBodyPrefab(bodyName); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing body " + bodyName); } GameObject model = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = model.GetComponent<ModelSkinController>(); SkinDef baseSkin = null; if (Object.op_Implicit((Object)(object)controller) && controller.skins != null && controller.skins.Length != 0) { baseSkin = controller.skins[0]; } if (!Object.op_Implicit((Object)(object)baseSkin)) { AsyncOperationHandle<SkinDef> h = Addressables.LoadAssetAsync<SkinDef>((object)("RoR2/Base/Engi/" + defaultName + ".asset")); retainedAssets.Add(AsyncOperationHandle<SkinDef>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline("default skin " + bodyName); yield return null; } baseSkin = h.Result; } if (!Object.op_Implicit((Object)(object)baseSkin)) { throw new InvalidOperationException("Missing default skin " + bodyName); } SkinDefParams bp = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)bp) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> h2 = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(h2)); while (!h2.IsDone) { CheckLoadDeadline("parameters " + bodyName); yield return null; } bp = h2.Result; } if (!Object.op_Implicit((Object)(object)bp)) { throw new InvalidOperationException("Missing parameters " + bodyName); } SkinnedMeshRenderer target = model.GetComponentsInChildren<SkinnedMeshRenderer>(true).Single((SkinnedMeshRenderer r) => r.bones.Length == boneCount); Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = bp.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference)) { AsyncOperationHandle<Mesh> h3 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(h3)); while (!h3.IsDone) { CheckLoadDeadline("mesh " + bodyName); yield return null; } reference = h3.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != target.bones.Length) { throw new InvalidOperationException("Bind pose mismatch " + bodyName); } RendererInfo ri = bp.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = ri.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && ri.defaultMaterialAddress != null && ((AssetReference)ri.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> h4 = Addressables.LoadAssetAsync<Material>(((AssetReference)ri.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(h4)); while (!h4.IsDone) { CheckLoadDeadline("material " + bodyName); yield return null; } val3 = h4.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Missing native material " + bodyName); } Mesh val4 = ReadMesh(Path.Combine(folder, assetName + ".meshbin"), target, reference); ((Object)val4).name = "EclipsePlaytest_EngineerE3_" + assetName; Material val5 = MakeMaterial(assetName, val3); canonicalBases[assetName] = new MeshBasis { Reference = reference, Authored = val4 }; ri.defaultMaterial = val5; ri.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { ri }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = val4, meshAddress = new AssetReferenceT<Mesh>("") } }; SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>(); ((Object)val7).name = "skinEclipsePlaytestEngineerE3_" + assetName; val7.nameToken = "ECLIPSEPLAYTEST_ENGINEER_E3_" + assetName.ToUpperInvariant().Replace('-', '_'); LanguageAPI.Add(val7.nameToken, (bodyName == "EngiBody") ? "One-Man Band (Playtest)" : ("One-Man Band " + assetName)); val7.icon = CreateIcon(Designs[0].Colors); val7.unlockableDef = null; val7.rootObject = model; val7.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; val7.skinDefParams = val6; if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { throw new InvalidOperationException("Missing native skin controller/list: " + bodyName); } prepared.Add(new Prepared { BodyName = bodyName, Model = model, Controller = controller, Skin = val7, Mesh = val4, Reference = reference, Material = val5, OriginalSkins = controller.skins }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E3_PREPARED body=" + bodyName + " vertices=" + val4.vertexCount + " unlocked=true")); } private static void ValidateSkin(Prepared p) { //IL_00ee: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) SkinDef skin = p.Skin; SkinDefParams skinDefParams = skin.skinDefParams; if (!Object.op_Implicit((Object)(object)skin.rootObject) || !Object.op_Implicit((Object)(object)skinDefParams) || skin.baseSkins == null || skin.baseSkins.Any((SkinDef s) => !Object.op_Implicit((Object)(object)s) || s == skin)) { throw new InvalidOperationException("Invalid skin graph: " + p.BodyName); } if (skin.skinDefParamsAddress == null) { skin.skinDefParamsAddress = new AssetReferenceT<SkinDefParams>(""); } if (skinDefParams.rendererInfos == null || skinDefParams.meshReplacements == null || skinDefParams.gameObjectActivations == null || skinDefParams.lightReplacements == null || skinDefParams.projectileGhostReplacements == null || skinDefParams.minionSkinReplacements == null) { throw new InvalidOperationException("Null parameter collection: " + p.BodyName); } RendererInfo[] rendererInfos = skinDefParams.rendererInfos; foreach (RendererInfo val in rendererInfos) { if (!Object.op_Implicit((Object)(object)val.renderer) || !Object.op_Implicit((Object)(object)val.defaultMaterial) || !((Component)val.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid material/renderer root: " + p.BodyName); } } MeshReplacement[] meshReplacements = skinDefParams.meshReplacements; foreach (MeshReplacement val2 in meshReplacements) { if (!Object.op_Implicit((Object)(object)val2.renderer) || !Object.op_Implicit((Object)(object)val2.mesh) || !((Component)val2.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid mesh/renderer root: " + p.BodyName); } } ProjectileGhostReplacement[] projectileGhostReplacements = skinDefParams.projectileGhostReplacements; foreach (ProjectileGhostReplacement val3 in projectileGhostReplacements) { if (!Object.op_Implicit((Object)(object)val3.projectilePrefab) || !Object.op_Implicit((Object)(object)val3.projectileGhostReplacementPrefab) || ProjectileCatalog.GetProjectileIndex(val3.projectilePrefab) < 0) { throw new InvalidOperationException("Unregistered mine projectile: " + p.BodyName); } } MinionSkinReplacement[] minionSkinReplacements = skinDefParams.minionSkinReplacements; foreach (MinionSkinReplacement val4 in minionSkinReplacements) { if (!Object.op_Implicit((Object)(object)val4.minionBodyPrefab) || !Object.op_Implicit((Object)(object)val4.minionSkin) || val4.minionSkin.runtimeSkin == null) { throw new InvalidOperationException("Unbaked turret skin: " + p.BodyName); } } } private static Sprite CreateIcon(Color32[] colors) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00c6: 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_0083: 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_0071: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : colors[num]); } } val.SetPixels32(array); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private void CheckLoadDeadline(string asset) { if (Time.realtimeSinceStartup > registrationDeadline) { throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin."); } } private void SyncDisplaySkins() { if (!registered) { return; } try { SyncDisplaySkinsChecked(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("ENGINEER_E3_DISPLAY_SYNC_FAILED version=0.3.1 " + ex)); } } private void SyncDisplaySkinsChecked() { SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "EngiBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)val.displayPrefab.GetComponent<BandVisuals>())) { val.displayPrefab.AddComponent<BandVisuals>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E3_DISPLAY_READY version=0.3.1 skins=" + val2.skins.Length + " catalogSkins=" + SkinCatalog.skinCount)); } } private Texture2D ReadTexture(string name, bool linear) { return textureCache.Load(Path.Combine(folder, name), linear); } private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_0592: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (new string(binaryReader.ReadChars(4)) != "PWE2") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0 || !hashSet.Add(array[i])) { throw new InvalidDataException("Missing/duplicate reference bone: " + name); } } Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num3]; for (int num5 = 0; num5 < num3; num5++) { Matrix4x4 val = default(Matrix4x4); for (int num6 = 0; num6 < 4; num6++) { for (int num7 = 0; num7 < 4; num7++) { float num8 = binaryReader.ReadSingle(); if (float.IsNaN(num8) || float.IsInfinity(num8)) { throw new InvalidDataException("Invalid bind matrix."); } ((Matrix4x4)(ref val))[num6, num7] = num8; } } if (Math.Abs(((Matrix4x4)(ref val)).determinant) < 1E-05f) { throw new InvalidDataException("Singular bind matrix."); } array2[array[num5]] = val; } Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector3[] array4 = (Vector3[])(object)new Vector3[num]; Vector2[] array5 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array6 = (BoneWeight[])(object)new BoneWeight[num]; for (int num9 = 0; num9 < num; num9++) { array3[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array5[num9] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); int[] array7 = new int[4]; for (int num10 = 0; num10 < 4; num10++) { int num11 = binaryReader.ReadInt32(); if (num11 < 0 || num11 >= num3) { throw new InvalidDataException("Bone out of range."); } array7[num10] = array[num11]; } float[] array8 = new float[4]; for (int num12 = 0; num12 < 4; num12++) { array8[num12] = binaryReader.ReadSingle(); } if (array8.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array8.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } if (!Finite(array3[num9]) || !Finite(array4[num9])) { throw new InvalidDataException("Non-finite vertex."); } int num13 = num9; BoneWeight val2 = default(BoneWeight); ((BoneWeight)(ref val2)).boneIndex0 = array7[0]; ((BoneWeight)(ref val2)).boneIndex1 = array7[1]; ((BoneWeight)(ref val2)).boneIndex2 = array7[2]; ((BoneWeight)(ref val2)).boneIndex3 = array7[3]; ((BoneWeight)(ref val2)).weight0 = array8[0]; ((BoneWeight)(ref val2)).weight1 = array8[1]; ((BoneWeight)(ref val2)).weight2 = array8[2]; ((BoneWeight)(ref val2)).weight3 = array8[3]; array6[num13] = val2; } int[] array9 = new int[num2]; for (int num14 = 0; num14 < num2; num14++) { array9[num14] = binaryReader.ReadInt32(); if (array9[num14] < 0 || array9[num14] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } if (Object.op_Implicit((Object)(object)reference) && reference.bindposes.Length == num3) { Matrix4x4[] bindposes = reference.bindposes; int num15 = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Base"); if (num15 < 0) { num15 = 0; } Matrix4x4 b = ((Matrix4x4)(ref bindposes[num15])).inverse * array2[num15]; bool flag = true; for (int num16 = 0; num16 < num3; num16++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[num16])).inverse * array2[num16], b, 0.0002f)) { flag = false; } } if (!flag) { if (num3 != 2 && (num3 != 14 || !renderer.bones.Any((Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Screw"))) { throw new InvalidDataException("Unsupported nonuniform bind variant: " + ((Object)renderer).name); } Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int num17 = 0; num17 < num; num17++) { array3[num17] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(array3[num17]); int num18 = num17; Vector3 val3 = ((Matrix4x4)(ref transpose)).MultiplyVector(array4[num17]); array4[num18] = ((Vector3)(ref val3)).normalized; } array2 = bindposes; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E3_MINE_BIND_VARIANT renderer=" + ((Object)renderer).name + " reference=" + ((Object)reference).name)); } } Mesh val4 = new Mesh { name = "EclipsePlaytestEngineerOneManBand", indexFormat = (IndexFormat)(num > 65535), vertices = array3, normals = array4, uv = array5, boneWeights = array6, bindposes = array2, triangles = array9 }; val4.RecalculateBounds(); val4.RecalculateTangents(); return val4; } private Material MakeMaterial(string asset, Material source) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (assetMaterials.TryGetValue(asset, out var value)) { return value; } if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader)) { throw new InvalidOperationException("Missing shader for " + asset); } value = new Material(source) { name = "matEclipsePlaytest_EngineerE3_" + asset }; value.SetTexture("_MainTex", (Texture)(object)ReadTexture(asset + "-albedo-spec.png", linear: false)); value.SetTexture("_NormalTex", (Texture)(object)ReadTexture(asset + "-normal.png", linear: true)); value.SetTexture("_EmTex", (Texture)(object)ReadTexture(asset + "-emission.png", linear: false)); value.SetColor("_Color", Color.white); value.SetFloat("_NormalStrength", 0.3f); value.SetFloat("_Smoothness", 0.28f); value.SetFloat("_SpecularStrength", 0.35f); value.SetFloat("_SpecularExponent", 8f); value.SetFloat("_EmPower", asset.EndsWith("mine", StringComparison.Ordinal) ? 0.4f : 0f); value.DisableKeyword("LIMBREMOVAL"); value.SetFloat("_LimbRemovalOn", 0f); assetMaterials.Add(asset, value); return value; } private static string MineAsset(Renderer r) { if (((Object)r).name == "EngiMineMesh") { return "pressure-mine"; } if (((Object)r).name == "EngiSpiderMineMesh") { return "spider-mine"; } return null; } private IEnumerator PrepareMineGhosts(SkinDef bodySkin) { cosmeticStorage = new GameObject("OneManBandCosmeticPrefabs"); cosmeticStorage.SetActive(false); Object.DontDestroyOnLoad((Object)(object)cosmeticStorage); List<ProjectileGhostReplacement> replacements = new List<ProjectileGhostReplacement>(); string[] array = new string[2] { "EngiMine", "SpiderMine" }; foreach (string name in array) { AsyncOperationHandle<GameObject> h = Addressables.LoadAssetAsync<GameObject>((object)("RoR2/Base/Engi/" + name + ".prefab")); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline(name); yield return null; } if (!Object.op_Implicit((Object)(object)h.Result)) { throw new InvalidOperationException("Missing projectile " + name); } ProjectileController component = h.Result.GetComponent<ProjectileController>(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("Missing ProjectileController " + name); } GameObject val = component.ghostPrefab; if (!Object.op_Implicit((Object)(object)val) && component.ghostPrefabAddress != null && ((AssetReference)component.ghostPrefabAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<GameObject> gh = Addressables.LoadAssetAsync<GameObject>(((AssetReference)component.ghostPrefabAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(gh)); while (!gh.IsDone) { CheckLoadDeadline(name + " ghost"); yield return null; } val = gh.Result; } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing mine ghost " + name); } GameObject val2 = Object.Instantiate<GameObject>(val, cosmeticStorage.transform); ((Object)val2).name = "EclipseOneManBand_" + name + "Ghost"; string asset = ((name == "EngiMine") ? "pressure-mine" : "spider-mine"); SkinnedMeshRenderer[] array2 = (from r in val2.GetComponentsInChildren<SkinnedMeshRenderer>(true) where MineAsset((Renderer)(object)r) == asset select r).ToArray(); if (array2.Length != 1) { throw new InvalidOperationException("Ambiguous mine renderer " + name + ": " + array2.Length); } SkinnedMeshRenderer val3 = array2[0]; int num = ((asset == "pressure-mine") ? 2 : 14); if (val3.bones.Length != num || !Object.op_Implicit((Object)(object)val3.sharedMesh)) { throw new InvalidOperationException("Missing native mine rig " + name); } Mesh sharedMesh = val3.sharedMesh; Mesh val4 = MeshFor(asset, val3); Material sharedMaterial = MakeMaterial(asset, ((Renderer)val3).sharedMaterial); canonicalBases[asset] = new MeshBasis { Reference = sharedMesh, Authored = val4 }; val3.sharedMesh = val4; ((Renderer)val3).sharedMaterial = sharedMaterial; Mesh val5 = new Mesh(); val3.BakeMesh(val5); Bounds localBounds = ((Renderer)val3).localBounds; Bounds bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).min); bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).max); ((Bounds)(ref localBounds)).Expand(((Bounds)(ref localBounds)).size * 0.5f); ((Renderer)val3).localBounds = localBounds; Object.Destroy((Object)(object)val5); val3.updateWhenOffscreen = true; val2.SetActive(true); replacements.Add(new ProjectileGhostReplacement { projectilePrefab = h.Result, projectileGhostReplacementPrefab = val2, ghostReplacementAddress = new AssetReferenceT<GameObject>("") }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E3_MINE_READY asset=" + asset + " vertices=" + val4.vertexCount + " native effects/controller preserved")); } bodySkin.skinDefParams.projectileGhostReplacements = replacements.ToArray(); } private Mesh MeshFor(string asset, SkinnedMeshRenderer target, Mesh nativeReference = null) { if (!Object.op_Implicit((Object)(object)nativeReference)) { nativeReference = target.sharedMesh; } string key = asset + "|" + (Object.op_Implicit((Object)(object)nativeReference) ? ((Object)nativeReference).GetInstanceID() : 0) + "|" + string.Join("|", target.bones.Select((Transform b) => (!Object.op_Implicit((Object)(object)b)) ? "<null>" : ((Object)b).name)); if (!remappedMeshes.TryGetValue(key, out var value)) { value = ReadMesh(Path.Combine(folder, asset + ".meshbin"), target, nativeReference); remappedMeshes.Add(key, value); } return value; } private static bool SameMatrix(Matrix4x4 a, Matrix4x4 b, float tolerance) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (Math.Abs(((Matrix4x4)(ref a))[i, j] - ((Matrix4x4)(ref b))[i, j]) > tolerance) { return false; } } } return true; } private Mesh StaticMeshFor(string asset, Mesh reference) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)reference)) { throw new InvalidOperationException("Missing static reference " + asset); } string key = asset + "|" + ((Object)reference).GetInstanceID(); if (staticMeshes.TryGetValue(key, out var value)) { return value; } if (!canonicalBases.TryGetValue(asset, out var value2)) { throw new InvalidOperationException("Missing canonical rig " + asset); } Matrix4x4[] bindposes = reference.bindposes; Matrix4x4[] bindposes2 = value2.Authored.bindposes; if (bindposes.Length != bindposes2.Length || bindposes.Length == 0) { throw new InvalidOperationException("Static bind count " + asset); } Matrix4x4 b = ((Matrix4x4)(ref bindposes[0])).inverse * bindposes2[0]; for (int i = 1; i < bindposes.Length; i++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[i])).inverse * bindposes2[i], b, 0.0002f)) { if (asset != "pressure-mine" && asset != "spider-mine") { throw new InvalidOperationException("Nonuniform static bind conversion " + asset + " bone " + i); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E3_STATIC_MINE_BIND_VARIANT " + asset + " uses canonical assembled rest shape")); break; } } value = Object.Instantiate<Mesh>(value2.Authored); ((Object)value).name = "EclipseEngineerE3Static_" + asset; Vector3[] vertices = value.vertices; Vector3[] normals = value.normals; Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int j = 0; j < vertices.Length; j++) { vertices[j] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(vertices[j]); int num = j; Vector3 val = ((Matrix4x4)(ref transpose)).MultiplyVector(normals[j]); normals[num] = ((Vector3)(ref val)).normalized; } value.vertices = vertices; value.normals = normals; value.boneWeights = (BoneWeight[])(object)new BoneWeight[0]; value.bindposes = (Matrix4x4[])(object)new Matrix4x4[0]; value.RecalculateBounds(); value.RecalculateTangents(); staticMeshes.Add(key, value); return value; } private static bool Finite(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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_0028: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(v.x + v.y + v.z)) { return !float.IsInfinity(v.x + v.y + v.z); } return false; } } internal static class StartupGuard { internal static IEnumerator Run(Func<IEnumerator> create, Func<bool> expired, Action<Exception> failed) { Stack<IEnumerator> stack = new Stack<IEnumerator>(); Exception failure = null; try { stack.Push(create()); } catch (Exception ex) { failure = ex; } try { while (failure == null && stack.Count > 0) { bool flag = false; object obj = null; try { if (expired()) { throw new TimeoutException("One-Man Band startup deadline exceeded."); } IEnumerator enumerator = stack.Peek(); flag = enumerator.MoveNext(); if (flag) { obj = enumerator.Current; } else { stack.Pop(); (enumerator as IDisposable)?.Dispose(); } } catch (Exception ex2) { failure = ex2; } if (failure != null) { break; } if (flag) { if (obj is IEnumerator item) { stack.Push(item); } else { yield return obj; } } } } finally { if (stack.Count > 0 && failure == null) { failure = new OperationCanceledException("One-Man Band startup iterator was cancelled."); } while (stack.Count > 0) { try { (stack.Pop() as IDisposable)?.Dispose(); } catch (Exception ex3) { if (failure == null) { failure = ex3; } } } if (failure != null) { try { failed(failure); } catch { } } } } } internal sealed class TextureAssetCache { private readonly Dictionary<string, Texture2D> values = new Dictionary<string, Texture2D>(); internal Texture2D Load(string path, bool linear) { //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_006f: 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_007e: Expected O, but got Unknown byte[] array = File.ReadAllBytes(path); string key; using (SHA256 sHA = SHA256.Create()) { key = (linear ? "linear:" : "srgb:") + Convert.ToBase64String(sHA.ComputeHash(array)); } if (values.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear) { name = Path.GetFileName(path), anisoLevel = 4, filterMode = (FilterMode)2 }; try { if (!ImageConversion.LoadImage(val, array, true)) { throw new InvalidDataException("Cannot decode " + Path.GetFileName(path)); } values[key] = val; return val; } catch { Object.Destroy((Object)(object)val); throw; } } }
BepInEx/plugins/RodaniusSkins/engineer-orbital-architect/EngineerOrbitalArchitect.dll
Decompiled a week agousing 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.Security.Cryptography; using System.Text; using BepInEx; using EngineerPrimitiveSolutionsPlaytest; using EntityStates; using EntityStates.Engi.EngiWeapon; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.Projectile; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EngineerOrbitalArchitectPlaytest; [BepInPlugin("eclipseplaytest.engineer.e8", "Engineer - Orbital Architect (Playtest)", "0.3.1")] [BepInDependency("eclipseplaytest.engineer.e7", "0.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EngineerOrbitalArchitect : BaseUnityPlugin { private sealed class Prepared { public SkinDef[] OriginalSkins; public SkinDef[] CommittedSkins; public string BodyName; public GameObject Model; public ModelSkinController Controller; public SkinDef Skin; public Mesh Mesh; public Mesh Reference; public Material Material; } private sealed class Design { public string Slug; public string Name; public Color32[] Colors; public Design(string slug, string name, Color32[] colors) { Slug = slug; Name = name; Colors = colors; } } private sealed class MeshBasis { public Mesh Reference; public Mesh Authored; } public sealed class BandVisuals : MonoBehaviour { private sealed class Saved { public Renderer Renderer; public Mesh Mesh; public Material[] Materials; public Bounds Bounds; public bool Offscreen; public bool ChangeMesh; public bool ChangeMaterial; public Mesh AssignedMesh; public Material[] AssignedMaterials; public bool ChangeBounds; public Bounds AssignedBounds; public bool ChangeOffscreen; public bool AssignedOffscreen; } private readonly Dictionary<Renderer, Saved> changed = new Dictionary<Renderer, Saved>(); private ModelSkinController controller; private CharacterBody body; private EntityStateMachine[] machines; private bool lobbyDirty = true; private static readonly FieldInfo Blueprint = typeof(PlaceTurret).GetField("blueprints", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo Wrist = typeof(PlaceTurret).GetField("wristDisplayObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private void Applied(int index) { if (!OwnSkin() && changed.Count > 0) { Restore(); } lobbyDirty = true; } private void Start() { controller = ((Component)this).GetComponentInChildren<ModelSkinController>(true); body = ((Component)this).GetComponentInParent<CharacterBody>(); machines = (EntityStateMachine[])(Object.op_Implicit((Object)(object)body) ? ((Array)((Component)body).GetComponents<EntityStateMachine>()) : ((Array)new EntityStateMachine[0])); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; } } private bool OwnSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length && Object.op_Implicit((Object)(object)controller.skins[currentSkinIndex])) { return ((Object)controller.skins[currentSkinIndex]).name.StartsWith("skinEclipsePlaytestEngineerE8_", StringComparison.Ordinal); } return false; } private Saved Save(Renderer r) { //IL_0074: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (changed.TryGetValue(r, out var value)) { return value; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((r is SkinnedMeshRenderer) ? r : null); MeshFilter component = ((Component)r).GetComponent<MeshFilter>(); value = new Saved { Renderer = r, Materials = r.sharedMaterials, Mesh = (Object.op_Implicit((Object)(object)val) ? val.sharedMesh : (Object.op_Implicit((Object)(object)component) ? component.sharedMesh : null)), Bounds = (Bounds)(Object.op_Implicit((Object)(object)val) ? ((Renderer)val).localBounds : default(Bounds)), Offscreen = (Object.op_Implicit((Object)(object)val) && val.updateWhenOffscreen) }; changed.Add(r, value); return value; } private void ApplySkinned(SkinnedMeshRenderer r, string asset, bool keepMaterial) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) Saved saved = Save((Renderer)(object)r); saved.ChangeMesh = true; saved.ChangeMaterial = !keepMaterial; Mesh val = (saved.AssignedMesh = instance.MeshFor(asset, r, saved.Mesh)); if ((Object)(object)r.sharedMesh != (Object)(object)val) { r.sharedMesh = val; Mesh val2 = new Mesh(); r.BakeMesh(val2); Bounds bounds = saved.Bounds; Bounds bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).min); bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).max); ((Bounds)(ref bounds)).Expand(((Bounds)(ref bounds)).size * 0.5f); ((Renderer)r).localBounds = bounds; saved.ChangeBounds = true; saved.AssignedBounds = bounds; Object.Destroy((Object)(object)val2); } r.updateWhenOffscreen = true; saved.ChangeOffscreen = true; saved.AssignedOffscreen = true; if (!keepMaterial) { ((Renderer)r).sharedMaterial = instance.assetMaterials[asset]; saved.AssignedMaterials = ((Renderer)r).sharedMaterials; } } private void Restore() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) foreach (Saved value in changed.Values) { if (!Object.op_Implicit((Object)(object)value.Renderer)) { continue; } Renderer renderer = value.Renderer; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); MeshFilter component = ((Component)value.Renderer).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)val)) { if (value.ChangeMesh && (Object)(object)val.sharedMesh == (Object)(object)value.AssignedMesh) { if (value.ChangeBounds && ((Renderer)val).localBounds == value.AssignedBounds) { ((Renderer)val).localBounds = value.Bounds; } if (value.ChangeOffscreen && val.updateWhenOffscreen == value.AssignedOffscreen) { val.updateWhenOffscreen = value.Offscreen; } val.sharedMesh = value.Mesh; } } else if (Object.op_Implicit((Object)(object)component) && value.ChangeMesh && (Object)(object)component.sharedMesh == (Object)(object)value.AssignedMesh) { component.sharedMesh = value.Mesh; } if (value.ChangeMaterial && value.AssignedMaterials != null && value.Renderer.sharedMaterials.SequenceEqual(value.AssignedMaterials)) { value.Renderer.sharedMaterials = value.Materials; } } changed.Clear(); } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)instance) || !instance.registered) { return; } Renderer[] array = changed.Keys.Where((Renderer r) => !Object.op_Implicit((Object)(object)r)).ToArray(); foreach (Renderer key in array) { changed.Remove(key); } if (!OwnSkin()) { if (changed.Count > 0) { Restore(); } lobbyDirty = true; return; } if (lobbyDirty) { SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { string text = MineAsset((Renderer)(object)val); if (text != null) { ApplySkinned(val, text, keepMaterial: false); } else if (!Object.op_Implicit((Object)(object)body) && val.bones.Length == 15 && Object.op_Implicit((Object)(object)((Component)this).transform.Find("TurretHolder")) && ((Component)val).transform.IsChildOf(((Component)this).transform.Find("TurretHolder"))) { ApplySkinned(val, "turret", keepMaterial: false); } } MeshRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren2) { string text2 = MineAsset((Renderer)(object)val2); if (text2 != null) { MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)component)) { Saved saved = Save((Renderer)(object)val2); saved.ChangeMesh = true; component.sharedMesh = instance.StaticMeshFor(text2, saved.Mesh); saved.AssignedMesh = component.sharedMesh; saved.ChangeMaterial = true; ((Renderer)val2).sharedMaterial = instance.assetMaterials[text2]; saved.AssignedMaterials = ((Renderer)val2).sharedMaterials; } } } lobbyDirty = false; } if (!Object.op_Implicit((Object)(object)body)) { return; } EntityStateMachine[] array2 = machines; for (int num = 0; num < array2.Length; num++) { EntityState state = array2[num].state; PlaceTurret val3 = (PlaceTurret)(object)((state is PlaceTurret) ? state : null); if (val3 == null) { continue; } string asset = ((val3 is PlaceWalkerTurret) ? "walker" : "turret"); object? obj = Blueprint?.GetValue(val3); BlueprintController val4 = (BlueprintController)((obj is BlueprintController) ? obj : null); if (Object.op_Implicit((Object)(object)val4)) { SkinnedMeshRenderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val5 in componentsInChildren) { if (val5.bones.Length == 15) { ApplySkinned(val5, asset, keepMaterial: true); } } } object? obj2 = Wrist?.GetValue(val3); GameObject val6 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (!Object.op_Implicit((Object)(object)val6)) { continue; } MeshFilter[] componentsInChildren3 = val6.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val7 in componentsInChildren3) { if (((Object)val7).name == "EngiTurretMesh") { Renderer component2 = ((Component)val7).GetComponent<Renderer>(); Saved saved2 = Save(component2); saved2.ChangeMesh = true; val7.sharedMesh = instance.StaticMeshFor(asset, saved2.Mesh); saved2.AssignedMesh = val7.sharedMesh; } } } } private void OnDisable() { Restore(); lobbyDirty = true; } private void OnDestroy() { if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } } } public const string Guid = "eclipseplaytest.engineer.e8"; public const string Version = "0.3.1"; private static EngineerOrbitalArchitect instance; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private float registrationDeadline; private string folder; private SkinDef skin; private GameObject modelPrefab; private string startupStage = "awake"; private readonly List<BandVisuals> startupVisuals = new List<BandVisuals>(); private readonly List<Prepared> prepared = new List<Prepared>(); private bool registered; private static readonly Design[] Designs = new Design[1] { new Design("orbital-architect", "Orbital Architect (Playtest)", (Color32[])(object)new Color32[4] { new Color32((byte)224, (byte)220, (byte)196, byte.MaxValue), new Color32((byte)28, (byte)114, (byte)126, byte.MaxValue), new Color32((byte)238, (byte)121, (byte)36, byte.MaxValue), new Color32((byte)61, (byte)204, (byte)219, byte.MaxValue) }) }; private readonly TextureAssetCache textureCache = new TextureAssetCache(); private GameObject cosmeticStorage; private readonly Dictionary<string, MeshBasis> canonicalBases = new Dictionary<string, MeshBasis>(); private readonly Dictionary<string, Material> assetMaterials = new Dictionary<string, Material>(); private readonly Dictionary<string, Mesh> remappedMeshes = new Dictionary<string, Mesh>(); private readonly Dictionary<string, Mesh> staticMeshes = new Dictionary<string, Mesh>(); private void Awake() { folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); instance = this; SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(EngineerOrbitalArchitect)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; } [SystemInitializer(new Type[] { typeof(BodyCatalog), typeof(ProjectileCatalog), typeof(SurvivorCatalog), typeof(EngineerPrimitiveSolutions) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { return EmptyStartup(); } instance.registrationDeadline = Time.realtimeSinceStartup + 60f; return StartupGuard.Run(instance.RegisterAsync, () => Time.realtimeSinceStartup > instance.registrationDeadline, delegate(Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E8_STARTUP_DISABLED version=0.3.1 stage=" + instance.startupStage + " " + ex)); try { instance.RollbackRegistration(); ((BaseUnityPlugin)instance).Logger.LogWarning((object)"ENGINEER_E8_ROLLBACK_OK existing skin arrays retained."); } catch (Exception ex2) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E8_ROLLBACK_FAILED " + ex2)); } }); } private static IEnumerator EmptyStartup() { yield break; } private void Stage(string value) { startupStage = value; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E8_STARTUP_STAGE version=0.3.1 stage=" + value)); } private void RollbackRegistration() { registered = false; foreach (Prepared item in prepared) { if (Object.op_Implicit((Object)(object)item.Controller) && item.CommittedSkins != null && item.Controller.skins == item.CommittedSkins) { item.Controller.skins = item.OriginalSkins; } } foreach (BandVisuals startupVisual in startupVisuals) { if (Object.op_Implicit((Object)(object)startupVisual)) { Object.Destroy((Object)(object)startupVisual); } } startupVisuals.Clear(); if (Object.op_Implicit((Object)(object)cosmeticStorage)) { Object.Destroy((Object)(object)cosmeticStorage); cosmeticStorage = null; } } private void ValidateAndCommit() { foreach (Prepared p in prepared) { if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Private bake produced no runtime skin: " + p.BodyName); } if (p.Controller.skins != p.OriginalSkins) { throw new InvalidOperationException("Skin list changed during startup: " + p.BodyName); } if (p.OriginalSkins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == ((Object)p.Skin).name)) { throw new InvalidOperationException("Duplicate Orbital Architect skin: " + ((Object)p.Skin).name); } p.CommittedSkins = p.OriginalSkins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { p.Skin }).ToArray(); } foreach (Prepared item in prepared) { item.Controller.skins = item.CommittedSkins; } } private IEnumerator RegisterAsync() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E8_REGISTRATION_BEGIN 0.3.1"); string[][] array = new string[3][] { new string[4] { "EngiTurretBody", "turret", "15", "skinEngiTurretDefault" }, new string[4] { "EngiWalkerTurretBody", "walker", "15", "skinEngiWalkerTurretDefault" }, new string[4] { "EngiBody", "orbital-architect", "83", "skinEngiDefault" } }; foreach (string[] array2 in array) { Stage("prepare:" + array2[0]); yield return Prepare(array2[0], array2[1], int.Parse(array2[2]), array2[3]); } Prepared bodySkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiBody"); bodySkin.Skin.skinDefParams.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[2] { new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiTurretBody").Skin }, new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiWalkerTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiWalkerTurretBody").Skin } }; Stage("prepare:mine-ghosts"); yield return PrepareMineGhosts(bodySkin.Skin); foreach (Prepared p in prepared) { Stage("private-bake:" + p.BodyName); ValidateSkin(p); yield return p.Skin.BakeAsync(); if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Bake returned without runtime skin: " + p.BodyName); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E8_PRIVATE_BAKE_OK body=" + p.BodyName)); } Stage("commit"); ValidateAndCommit(); modelPrefab = bodySkin.Model; skin = bodySkin.Skin; foreach (Prepared item in prepared) { if (!Object.op_Implicit((Object)(object)item.Model.GetComponent<BandVisuals>())) { startupVisuals.Add(item.Model.AddComponent<BandVisuals>()); } } registered = true; Stage("registered"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E8_REGISTERED Orbital Architect body, both turrets, pressure and spider mines; native Animator retained; unlocked=true version=0.3.1"); } private IEnumerator Prepare(string bodyName, string assetName, int boneCount, string defaultName) { GameObject val = BodyCatalog.FindBodyPrefab(bodyName); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing body " + bodyName); } GameObject model = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = model.GetComponent<ModelSkinController>(); SkinDef baseSkin = null; if (Object.op_Implicit((Object)(object)controller) && controller.skins != null && controller.skins.Length != 0) { baseSkin = controller.skins[0]; } if (!Object.op_Implicit((Object)(object)baseSkin)) { AsyncOperationHandle<SkinDef> h = Addressables.LoadAssetAsync<SkinDef>((object)("RoR2/Base/Engi/" + defaultName + ".asset")); retainedAssets.Add(AsyncOperationHandle<SkinDef>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline("default skin " + bodyName); yield return null; } baseSkin = h.Result; } if (!Object.op_Implicit((Object)(object)baseSkin)) { throw new InvalidOperationException("Missing default skin " + bodyName); } SkinDefParams bp = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)bp) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> h2 = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(h2)); while (!h2.IsDone) { CheckLoadDeadline("parameters " + bodyName); yield return null; } bp = h2.Result; } if (!Object.op_Implicit((Object)(object)bp)) { throw new InvalidOperationException("Missing parameters " + bodyName); } SkinnedMeshRenderer target = model.GetComponentsInChildren<SkinnedMeshRenderer>(true).Single((SkinnedMeshRenderer r) => r.bones.Length == boneCount); Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = bp.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference)) { AsyncOperationHandle<Mesh> h3 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(h3)); while (!h3.IsDone) { CheckLoadDeadline("mesh " + bodyName); yield return null; } reference = h3.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != target.bones.Length) { throw new InvalidOperationException("Bind pose mismatch " + bodyName); } RendererInfo ri = bp.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = ri.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && ri.defaultMaterialAddress != null && ((AssetReference)ri.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> h4 = Addressables.LoadAssetAsync<Material>(((AssetReference)ri.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(h4)); while (!h4.IsDone) { CheckLoadDeadline("material " + bodyName); yield return null; } val3 = h4.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Missing native material " + bodyName); } Mesh val4 = ReadMesh(Path.Combine(folder, assetName + ".meshbin"), target, reference); ((Object)val4).name = "EclipsePlaytest_EngineerE8_" + assetName; Material val5 = MakeMaterial(assetName, val3); canonicalBases[assetName] = new MeshBasis { Reference = reference, Authored = val4 }; ri.defaultMaterial = val5; ri.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { ri }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = val4, meshAddress = new AssetReferenceT<Mesh>("") } }; SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>(); ((Object)val7).name = "skinEclipsePlaytestEngineerE8_" + assetName; val7.nameToken = "ECLIPSEPLAYTEST_ENGINEER_E8_" + assetName.ToUpperInvariant().Replace('-', '_'); LanguageAPI.Add(val7.nameToken, (bodyName == "EngiBody") ? "Orbital Architect (Playtest)" : ("Orbital Architect " + assetName)); val7.icon = CreateIcon(Designs[0].Colors); val7.unlockableDef = null; val7.rootObject = model; val7.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; val7.skinDefParams = val6; if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { throw new InvalidOperationException("Missing native skin controller/list: " + bodyName); } prepared.Add(new Prepared { BodyName = bodyName, Model = model, Controller = controller, Skin = val7, Mesh = val4, Reference = reference, Material = val5, OriginalSkins = controller.skins }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E8_PREPARED body=" + bodyName + " vertices=" + val4.vertexCount + " unlocked=true")); } private static void ValidateSkin(Prepared p) { //IL_00ee: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) SkinDef skin = p.Skin; SkinDefParams skinDefParams = skin.skinDefParams; if (!Object.op_Implicit((Object)(object)skin.rootObject) || !Object.op_Implicit((Object)(object)skinDefParams) || skin.baseSkins == null || skin.baseSkins.Any((SkinDef s) => !Object.op_Implicit((Object)(object)s) || s == skin)) { throw new InvalidOperationException("Invalid skin graph: " + p.BodyName); } if (skin.skinDefParamsAddress == null) { skin.skinDefParamsAddress = new AssetReferenceT<SkinDefParams>(""); } if (skinDefParams.rendererInfos == null || skinDefParams.meshReplacements == null || skinDefParams.gameObjectActivations == null || skinDefParams.lightReplacements == null || skinDefParams.projectileGhostReplacements == null || skinDefParams.minionSkinReplacements == null) { throw new InvalidOperationException("Null parameter collection: " + p.BodyName); } RendererInfo[] rendererInfos = skinDefParams.rendererInfos; foreach (RendererInfo val in rendererInfos) { if (!Object.op_Implicit((Object)(object)val.renderer) || !Object.op_Implicit((Object)(object)val.defaultMaterial) || !((Component)val.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid material/renderer root: " + p.BodyName); } } MeshReplacement[] meshReplacements = skinDefParams.meshReplacements; foreach (MeshReplacement val2 in meshReplacements) { if (!Object.op_Implicit((Object)(object)val2.renderer) || !Object.op_Implicit((Object)(object)val2.mesh) || !((Component)val2.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid mesh/renderer root: " + p.BodyName); } } ProjectileGhostReplacement[] projectileGhostReplacements = skinDefParams.projectileGhostReplacements; foreach (ProjectileGhostReplacement val3 in projectileGhostReplacements) { if (!Object.op_Implicit((Object)(object)val3.projectilePrefab) || !Object.op_Implicit((Object)(object)val3.projectileGhostReplacementPrefab) || ProjectileCatalog.GetProjectileIndex(val3.projectilePrefab) < 0) { throw new InvalidOperationException("Unregistered mine projectile: " + p.BodyName); } } MinionSkinReplacement[] minionSkinReplacements = skinDefParams.minionSkinReplacements; foreach (MinionSkinReplacement val4 in minionSkinReplacements) { if (!Object.op_Implicit((Object)(object)val4.minionBodyPrefab) || !Object.op_Implicit((Object)(object)val4.minionSkin) || val4.minionSkin.runtimeSkin == null) { throw new InvalidOperationException("Unbaked turret skin: " + p.BodyName); } } } private static Sprite CreateIcon(Color32[] colors) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00c6: 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_0083: 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_0071: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : colors[num]); } } val.SetPixels32(array); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private void CheckLoadDeadline(string asset) { if (Time.realtimeSinceStartup > registrationDeadline) { throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin."); } } private void SyncDisplaySkins() { if (!registered) { return; } try { SyncDisplaySkinsChecked(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("ENGINEER_E8_DISPLAY_SYNC_FAILED version=0.3.1 " + ex)); } } private void SyncDisplaySkinsChecked() { SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "EngiBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)val.displayPrefab.GetComponent<BandVisuals>())) { val.displayPrefab.AddComponent<BandVisuals>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E8_DISPLAY_READY version=0.3.1 skins=" + val2.skins.Length + " catalogSkins=" + SkinCatalog.skinCount)); } } private Texture2D ReadTexture(string name, bool linear) { return textureCache.Load(Path.Combine(folder, name), linear); } private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_0592: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (new string(binaryReader.ReadChars(4)) != "PWE2") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0 || !hashSet.Add(array[i])) { throw new InvalidDataException("Missing/duplicate reference bone: " + name); } } Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num3]; for (int num5 = 0; num5 < num3; num5++) { Matrix4x4 val = default(Matrix4x4); for (int num6 = 0; num6 < 4; num6++) { for (int num7 = 0; num7 < 4; num7++) { float num8 = binaryReader.ReadSingle(); if (float.IsNaN(num8) || float.IsInfinity(num8)) { throw new InvalidDataException("Invalid bind matrix."); } ((Matrix4x4)(ref val))[num6, num7] = num8; } } if (Math.Abs(((Matrix4x4)(ref val)).determinant) < 1E-05f) { throw new InvalidDataException("Singular bind matrix."); } array2[array[num5]] = val; } Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector3[] array4 = (Vector3[])(object)new Vector3[num]; Vector2[] array5 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array6 = (BoneWeight[])(object)new BoneWeight[num]; for (int num9 = 0; num9 < num; num9++) { array3[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array5[num9] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); int[] array7 = new int[4]; for (int num10 = 0; num10 < 4; num10++) { int num11 = binaryReader.ReadInt32(); if (num11 < 0 || num11 >= num3) { throw new InvalidDataException("Bone out of range."); } array7[num10] = array[num11]; } float[] array8 = new float[4]; for (int num12 = 0; num12 < 4; num12++) { array8[num12] = binaryReader.ReadSingle(); } if (array8.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array8.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } if (!Finite(array3[num9]) || !Finite(array4[num9])) { throw new InvalidDataException("Non-finite vertex."); } int num13 = num9; BoneWeight val2 = default(BoneWeight); ((BoneWeight)(ref val2)).boneIndex0 = array7[0]; ((BoneWeight)(ref val2)).boneIndex1 = array7[1]; ((BoneWeight)(ref val2)).boneIndex2 = array7[2]; ((BoneWeight)(ref val2)).boneIndex3 = array7[3]; ((BoneWeight)(ref val2)).weight0 = array8[0]; ((BoneWeight)(ref val2)).weight1 = array8[1]; ((BoneWeight)(ref val2)).weight2 = array8[2]; ((BoneWeight)(ref val2)).weight3 = array8[3]; array6[num13] = val2; } int[] array9 = new int[num2]; for (int num14 = 0; num14 < num2; num14++) { array9[num14] = binaryReader.ReadInt32(); if (array9[num14] < 0 || array9[num14] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } if (Object.op_Implicit((Object)(object)reference) && reference.bindposes.Length == num3) { Matrix4x4[] bindposes = reference.bindposes; int num15 = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Base"); if (num15 < 0) { num15 = 0; } Matrix4x4 b = ((Matrix4x4)(ref bindposes[num15])).inverse * array2[num15]; bool flag = true; for (int num16 = 0; num16 < num3; num16++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[num16])).inverse * array2[num16], b, 0.0002f)) { flag = false; } } if (!flag) { if (num3 != 2 && (num3 != 14 || !renderer.bones.Any((Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Screw"))) { throw new InvalidDataException("Unsupported nonuniform bind variant: " + ((Object)renderer).name); } Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int num17 = 0; num17 < num; num17++) { array3[num17] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(array3[num17]); int num18 = num17; Vector3 val3 = ((Matrix4x4)(ref transpose)).MultiplyVector(array4[num17]); array4[num18] = ((Vector3)(ref val3)).normalized; } array2 = bindposes; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E8_MINE_BIND_VARIANT renderer=" + ((Object)renderer).name + " reference=" + ((Object)reference).name)); } } Mesh val4 = new Mesh { name = "EclipsePlaytestEngineerOrbitalArchitect", indexFormat = (IndexFormat)(num > 65535), vertices = array3, normals = array4, uv = array5, boneWeights = array6, bindposes = array2, triangles = array9 }; val4.RecalculateBounds(); val4.RecalculateTangents(); return val4; } private Material MakeMaterial(string asset, Material source) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (assetMaterials.TryGetValue(asset, out var value)) { return value; } if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader)) { throw new InvalidOperationException("Missing shader for " + asset); } value = new Material(source) { name = "matEclipsePlaytest_EngineerE8_" + asset }; value.SetTexture("_MainTex", (Texture)(object)ReadTexture(asset + "-albedo-spec.png", linear: false)); value.SetTexture("_NormalTex", (Texture)(object)ReadTexture(asset + "-normal.png", linear: true)); value.SetTexture("_EmTex", (Texture)(object)ReadTexture(asset + "-emission.png", linear: false)); value.SetColor("_Color", Color.white); value.SetFloat("_NormalStrength", 0.3f); value.SetFloat("_Smoothness", 0.28f); value.SetFloat("_SpecularStrength", 0.35f); value.SetFloat("_SpecularExponent", 8f); value.SetFloat("_EmPower", asset.EndsWith("mine", StringComparison.Ordinal) ? 0.4f : 0f); value.DisableKeyword("LIMBREMOVAL"); value.SetFloat("_LimbRemovalOn", 0f); assetMaterials.Add(asset, value); return value; } private static string MineAsset(Renderer r) { if (((Object)r).name == "EngiMineMesh") { return "pressure-mine"; } if (((Object)r).name == "EngiSpiderMineMesh") { return "spider-mine"; } return null; } private IEnumerator PrepareMineGhosts(SkinDef bodySkin) { cosmeticStorage = new GameObject("OrbitalArchitectCosmeticPrefabs"); cosmeticStorage.SetActive(false); Object.DontDestroyOnLoad((Object)(object)cosmeticStorage); List<ProjectileGhostReplacement> replacements = new List<ProjectileGhostReplacement>(); string[] array = new string[2] { "EngiMine", "SpiderMine" }; foreach (string name in array) { AsyncOperationHandle<GameObject> h = Addressables.LoadAssetAsync<GameObject>((object)("RoR2/Base/Engi/" + name + ".prefab")); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline(name); yield return null; } if (!Object.op_Implicit((Object)(object)h.Result)) { throw new InvalidOperationException("Missing projectile " + name); } ProjectileController component = h.Result.GetComponent<ProjectileController>(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("Missing ProjectileController " + name); } GameObject val = component.ghostPrefab; if (!Object.op_Implicit((Object)(object)val) && component.ghostPrefabAddress != null && ((AssetReference)component.ghostPrefabAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<GameObject> gh = Addressables.LoadAssetAsync<GameObject>(((AssetReference)component.ghostPrefabAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(gh)); while (!gh.IsDone) { CheckLoadDeadline(name + " ghost"); yield return null; } val = gh.Result; } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing mine ghost " + name); } GameObject val2 = Object.Instantiate<GameObject>(val, cosmeticStorage.transform); ((Object)val2).name = "EclipseOrbitalArchitect_" + name + "Ghost"; string asset = ((name == "EngiMine") ? "pressure-mine" : "spider-mine"); SkinnedMeshRenderer[] array2 = (from r in val2.GetComponentsInChildren<SkinnedMeshRenderer>(true) where MineAsset((Renderer)(object)r) == asset select r).ToArray(); if (array2.Length != 1) { throw new InvalidOperationException("Ambiguous mine renderer " + name + ": " + array2.Length); } SkinnedMeshRenderer val3 = array2[0]; int num = ((asset == "pressure-mine") ? 2 : 14); if (val3.bones.Length != num || !Object.op_Implicit((Object)(object)val3.sharedMesh)) { throw new InvalidOperationException("Missing native mine rig " + name); } Mesh sharedMesh = val3.sharedMesh; Mesh val4 = MeshFor(asset, val3); Material sharedMaterial = MakeMaterial(asset, ((Renderer)val3).sharedMaterial); canonicalBases[asset] = new MeshBasis { Reference = sharedMesh, Authored = val4 }; val3.sharedMesh = val4; ((Renderer)val3).sharedMaterial = sharedMaterial; Mesh val5 = new Mesh(); val3.BakeMesh(val5); Bounds localBounds = ((Renderer)val3).localBounds; Bounds bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).min); bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).max); ((Bounds)(ref localBounds)).Expand(((Bounds)(ref localBounds)).size * 0.5f); ((Renderer)val3).localBounds = localBounds; Object.Destroy((Object)(object)val5); val3.updateWhenOffscreen = true; val2.SetActive(true); replacements.Add(new ProjectileGhostReplacement { projectilePrefab = h.Result, projectileGhostReplacementPrefab = val2, ghostReplacementAddress = new AssetReferenceT<GameObject>("") }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E8_MINE_READY asset=" + asset + " vertices=" + val4.vertexCount + " native effects/controller preserved")); } bodySkin.skinDefParams.projectileGhostReplacements = replacements.ToArray(); } private Mesh MeshFor(string asset, SkinnedMeshRenderer target, Mesh nativeReference = null) { if (!Object.op_Implicit((Object)(object)nativeReference)) { nativeReference = target.sharedMesh; } string key = asset + "|" + (Object.op_Implicit((Object)(object)nativeReference) ? ((Object)nativeReference).GetInstanceID() : 0) + "|" + string.Join("|", target.bones.Select((Transform b) => (!Object.op_Implicit((Object)(object)b)) ? "<null>" : ((Object)b).name)); if (!remappedMeshes.TryGetValue(key, out var value)) { value = ReadMesh(Path.Combine(folder, asset + ".meshbin"), target, nativeReference); remappedMeshes.Add(key, value); } return value; } private static bool SameMatrix(Matrix4x4 a, Matrix4x4 b, float tolerance) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (Math.Abs(((Matrix4x4)(ref a))[i, j] - ((Matrix4x4)(ref b))[i, j]) > tolerance) { return false; } } } return true; } private Mesh StaticMeshFor(string asset, Mesh reference) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)reference)) { throw new InvalidOperationException("Missing static reference " + asset); } string key = asset + "|" + ((Object)reference).GetInstanceID(); if (staticMeshes.TryGetValue(key, out var value)) { return value; } if (!canonicalBases.TryGetValue(asset, out var value2)) { throw new InvalidOperationException("Missing canonical rig " + asset); } Matrix4x4[] bindposes = reference.bindposes; Matrix4x4[] bindposes2 = value2.Authored.bindposes; if (bindposes.Length != bindposes2.Length || bindposes.Length == 0) { throw new InvalidOperationException("Static bind count " + asset); } Matrix4x4 b = ((Matrix4x4)(ref bindposes[0])).inverse * bindposes2[0]; for (int i = 1; i < bindposes.Length; i++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[i])).inverse * bindposes2[i], b, 0.0002f)) { if (asset != "pressure-mine" && asset != "spider-mine") { throw new InvalidOperationException("Nonuniform static bind conversion " + asset + " bone " + i); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E8_STATIC_MINE_BIND_VARIANT " + asset + " uses canonical assembled rest shape")); break; } } value = Object.Instantiate<Mesh>(value2.Authored); ((Object)value).name = "EclipseEngineerE8Static_" + asset; Vector3[] vertices = value.vertices; Vector3[] normals = value.normals; Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int j = 0; j < vertices.Length; j++) { vertices[j] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(vertices[j]); int num = j; Vector3 val = ((Matrix4x4)(ref transpose)).MultiplyVector(normals[j]); normals[num] = ((Vector3)(ref val)).normalized; } value.vertices = vertices; value.normals = normals; value.boneWeights = (BoneWeight[])(object)new BoneWeight[0]; value.bindposes = (Matrix4x4[])(object)new Matrix4x4[0]; value.RecalculateBounds(); value.RecalculateTangents(); staticMeshes.Add(key, value); return value; } private static bool Finite(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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_0028: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(v.x + v.y + v.z)) { return !float.IsInfinity(v.x + v.y + v.z); } return false; } } internal static class StartupGuard { internal static IEnumerator Run(Func<IEnumerator> create, Func<bool> expired, Action<Exception> failed) { Stack<IEnumerator> stack = new Stack<IEnumerator>(); Exception failure = null; try { stack.Push(create()); } catch (Exception ex) { failure = ex; } try { while (failure == null && stack.Count > 0) { bool flag = false; object obj = null; try { if (expired()) { throw new TimeoutException("Orbital Architect startup deadline exceeded."); } IEnumerator enumerator = stack.Peek(); flag = enumerator.MoveNext(); if (flag) { obj = enumerator.Current; } else { stack.Pop(); (enumerator as IDisposable)?.Dispose(); } } catch (Exception ex2) { failure = ex2; } if (failure != null) { break; } if (flag) { if (obj is IEnumerator item) { stack.Push(item); } else { yield return obj; } } } } finally { if (stack.Count > 0 && failure == null) { failure = new OperationCanceledException("Orbital Architect startup iterator was cancelled."); } while (stack.Count > 0) { try { (stack.Pop() as IDisposable)?.Dispose(); } catch (Exception ex3) { if (failure == null) { failure = ex3; } } } if (failure != null) { try { failed(failure); } catch { } } } } } internal sealed class TextureAssetCache { private readonly Dictionary<string, Texture2D> values = new Dictionary<string, Texture2D>(); internal Texture2D Load(string path, bool linear) { //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_006f: 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_007e: Expected O, but got Unknown byte[] array = File.ReadAllBytes(path); string key; using (SHA256 sHA = SHA256.Create()) { key = (linear ? "linear:" : "srgb:") + Convert.ToBase64String(sHA.ComputeHash(array)); } if (values.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear) { name = Path.GetFileName(path), anisoLevel = 4, filterMode = (FilterMode)2 }; try { if (!ImageConversion.LoadImage(val, array, true)) { throw new InvalidDataException("Cannot decode " + Path.GetFileName(path)); } values[key] = val; return val; } catch { Object.Destroy((Object)(object)val); throw; } } }
BepInEx/plugins/RodaniusSkins/engineer-primitive-solutions/EngineerPrimitiveSolutions.dll
Decompiled a week agousing 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.Security.Cryptography; using System.Text; using BepInEx; using EngineerBubbleWorksPlaytest; using EntityStates; using EntityStates.Engi.EngiWeapon; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.Projectile; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EngineerPrimitiveSolutionsPlaytest; [BepInPlugin("eclipseplaytest.engineer.e7", "Engineer - Primitive Solutions (Playtest)", "0.3.1")] [BepInDependency("eclipseplaytest.engineer.e6", "0.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EngineerPrimitiveSolutions : BaseUnityPlugin { private sealed class Prepared { public SkinDef[] OriginalSkins; public SkinDef[] CommittedSkins; public string BodyName; public GameObject Model; public ModelSkinController Controller; public SkinDef Skin; public Mesh Mesh; public Mesh Reference; public Material Material; } private sealed class Design { public string Slug; public string Name; public Color32[] Colors; public Design(string slug, string name, Color32[] colors) { Slug = slug; Name = name; Colors = colors; } } private sealed class MeshBasis { public Mesh Reference; public Mesh Authored; } public sealed class BandVisuals : MonoBehaviour { private sealed class Saved { public Renderer Renderer; public Mesh Mesh; public Material[] Materials; public Bounds Bounds; public bool Offscreen; public bool ChangeMesh; public bool ChangeMaterial; public Mesh AssignedMesh; public Material[] AssignedMaterials; public bool ChangeBounds; public Bounds AssignedBounds; public bool ChangeOffscreen; public bool AssignedOffscreen; } private readonly Dictionary<Renderer, Saved> changed = new Dictionary<Renderer, Saved>(); private ModelSkinController controller; private CharacterBody body; private EntityStateMachine[] machines; private bool lobbyDirty = true; private static readonly FieldInfo Blueprint = typeof(PlaceTurret).GetField("blueprints", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo Wrist = typeof(PlaceTurret).GetField("wristDisplayObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private void Applied(int index) { if (!OwnSkin() && changed.Count > 0) { Restore(); } lobbyDirty = true; } private void Start() { controller = ((Component)this).GetComponentInChildren<ModelSkinController>(true); body = ((Component)this).GetComponentInParent<CharacterBody>(); machines = (EntityStateMachine[])(Object.op_Implicit((Object)(object)body) ? ((Array)((Component)body).GetComponents<EntityStateMachine>()) : ((Array)new EntityStateMachine[0])); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; } } private bool OwnSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length && Object.op_Implicit((Object)(object)controller.skins[currentSkinIndex])) { return ((Object)controller.skins[currentSkinIndex]).name.StartsWith("skinEclipsePlaytestEngineerE7_", StringComparison.Ordinal); } return false; } private Saved Save(Renderer r) { //IL_0074: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (changed.TryGetValue(r, out var value)) { return value; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((r is SkinnedMeshRenderer) ? r : null); MeshFilter component = ((Component)r).GetComponent<MeshFilter>(); value = new Saved { Renderer = r, Materials = r.sharedMaterials, Mesh = (Object.op_Implicit((Object)(object)val) ? val.sharedMesh : (Object.op_Implicit((Object)(object)component) ? component.sharedMesh : null)), Bounds = (Bounds)(Object.op_Implicit((Object)(object)val) ? ((Renderer)val).localBounds : default(Bounds)), Offscreen = (Object.op_Implicit((Object)(object)val) && val.updateWhenOffscreen) }; changed.Add(r, value); return value; } private void ApplySkinned(SkinnedMeshRenderer r, string asset, bool keepMaterial) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) Saved saved = Save((Renderer)(object)r); saved.ChangeMesh = true; saved.ChangeMaterial = !keepMaterial; Mesh val = (saved.AssignedMesh = instance.MeshFor(asset, r, saved.Mesh)); if ((Object)(object)r.sharedMesh != (Object)(object)val) { r.sharedMesh = val; Mesh val2 = new Mesh(); r.BakeMesh(val2); Bounds bounds = saved.Bounds; Bounds bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).min); bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).max); ((Bounds)(ref bounds)).Expand(((Bounds)(ref bounds)).size * 0.5f); ((Renderer)r).localBounds = bounds; saved.ChangeBounds = true; saved.AssignedBounds = bounds; Object.Destroy((Object)(object)val2); } r.updateWhenOffscreen = true; saved.ChangeOffscreen = true; saved.AssignedOffscreen = true; if (!keepMaterial) { ((Renderer)r).sharedMaterial = instance.assetMaterials[asset]; saved.AssignedMaterials = ((Renderer)r).sharedMaterials; } } private void Restore() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) foreach (Saved value in changed.Values) { if (!Object.op_Implicit((Object)(object)value.Renderer)) { continue; } Renderer renderer = value.Renderer; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); MeshFilter component = ((Component)value.Renderer).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)val)) { if (value.ChangeMesh && (Object)(object)val.sharedMesh == (Object)(object)value.AssignedMesh) { if (value.ChangeBounds && ((Renderer)val).localBounds == value.AssignedBounds) { ((Renderer)val).localBounds = value.Bounds; } if (value.ChangeOffscreen && val.updateWhenOffscreen == value.AssignedOffscreen) { val.updateWhenOffscreen = value.Offscreen; } val.sharedMesh = value.Mesh; } } else if (Object.op_Implicit((Object)(object)component) && value.ChangeMesh && (Object)(object)component.sharedMesh == (Object)(object)value.AssignedMesh) { component.sharedMesh = value.Mesh; } if (value.ChangeMaterial && value.AssignedMaterials != null && value.Renderer.sharedMaterials.SequenceEqual(value.AssignedMaterials)) { value.Renderer.sharedMaterials = value.Materials; } } changed.Clear(); } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)instance) || !instance.registered) { return; } Renderer[] array = changed.Keys.Where((Renderer r) => !Object.op_Implicit((Object)(object)r)).ToArray(); foreach (Renderer key in array) { changed.Remove(key); } if (!OwnSkin()) { if (changed.Count > 0) { Restore(); } lobbyDirty = true; return; } if (lobbyDirty) { SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { string text = MineAsset((Renderer)(object)val); if (text != null) { ApplySkinned(val, text, keepMaterial: false); } else if (!Object.op_Implicit((Object)(object)body) && val.bones.Length == 15 && Object.op_Implicit((Object)(object)((Component)this).transform.Find("TurretHolder")) && ((Component)val).transform.IsChildOf(((Component)this).transform.Find("TurretHolder"))) { ApplySkinned(val, "turret", keepMaterial: false); } } MeshRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren2) { string text2 = MineAsset((Renderer)(object)val2); if (text2 != null) { MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)component)) { Saved saved = Save((Renderer)(object)val2); saved.ChangeMesh = true; component.sharedMesh = instance.StaticMeshFor(text2, saved.Mesh); saved.AssignedMesh = component.sharedMesh; saved.ChangeMaterial = true; ((Renderer)val2).sharedMaterial = instance.assetMaterials[text2]; saved.AssignedMaterials = ((Renderer)val2).sharedMaterials; } } } lobbyDirty = false; } if (!Object.op_Implicit((Object)(object)body)) { return; } EntityStateMachine[] array2 = machines; for (int num = 0; num < array2.Length; num++) { EntityState state = array2[num].state; PlaceTurret val3 = (PlaceTurret)(object)((state is PlaceTurret) ? state : null); if (val3 == null) { continue; } string asset = ((val3 is PlaceWalkerTurret) ? "walker" : "turret"); object? obj = Blueprint?.GetValue(val3); BlueprintController val4 = (BlueprintController)((obj is BlueprintController) ? obj : null); if (Object.op_Implicit((Object)(object)val4)) { SkinnedMeshRenderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val5 in componentsInChildren) { if (val5.bones.Length == 15) { ApplySkinned(val5, asset, keepMaterial: true); } } } object? obj2 = Wrist?.GetValue(val3); GameObject val6 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (!Object.op_Implicit((Object)(object)val6)) { continue; } MeshFilter[] componentsInChildren3 = val6.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val7 in componentsInChildren3) { if (((Object)val7).name == "EngiTurretMesh") { Renderer component2 = ((Component)val7).GetComponent<Renderer>(); Saved saved2 = Save(component2); saved2.ChangeMesh = true; val7.sharedMesh = instance.StaticMeshFor(asset, saved2.Mesh); saved2.AssignedMesh = val7.sharedMesh; } } } } private void OnDisable() { Restore(); lobbyDirty = true; } private void OnDestroy() { if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } } } public const string Guid = "eclipseplaytest.engineer.e7"; public const string Version = "0.3.1"; private static EngineerPrimitiveSolutions instance; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private float registrationDeadline; private string folder; private SkinDef skin; private GameObject modelPrefab; private string startupStage = "awake"; private readonly List<BandVisuals> startupVisuals = new List<BandVisuals>(); private readonly List<Prepared> prepared = new List<Prepared>(); private bool registered; private static readonly Design[] Designs = new Design[1] { new Design("primitive-solutions", "Primitive Solutions (Playtest)", (Color32[])(object)new Color32[4] { new Color32((byte)145, (byte)99, (byte)57, byte.MaxValue), new Color32((byte)84, (byte)64, (byte)42, byte.MaxValue), new Color32((byte)169, (byte)163, (byte)147, byte.MaxValue), new Color32((byte)218, (byte)204, (byte)169, byte.MaxValue) }) }; private readonly TextureAssetCache textureCache = new TextureAssetCache(); private GameObject cosmeticStorage; private readonly Dictionary<string, MeshBasis> canonicalBases = new Dictionary<string, MeshBasis>(); private readonly Dictionary<string, Material> assetMaterials = new Dictionary<string, Material>(); private readonly Dictionary<string, Mesh> remappedMeshes = new Dictionary<string, Mesh>(); private readonly Dictionary<string, Mesh> staticMeshes = new Dictionary<string, Mesh>(); private void Awake() { folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); instance = this; SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(EngineerPrimitiveSolutions)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; } [SystemInitializer(new Type[] { typeof(BodyCatalog), typeof(ProjectileCatalog), typeof(SurvivorCatalog), typeof(EngineerBubbleWorks) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { return EmptyStartup(); } instance.registrationDeadline = Time.realtimeSinceStartup + 60f; return StartupGuard.Run(instance.RegisterAsync, () => Time.realtimeSinceStartup > instance.registrationDeadline, delegate(Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E7_STARTUP_DISABLED version=0.3.1 stage=" + instance.startupStage + " " + ex)); try { instance.RollbackRegistration(); ((BaseUnityPlugin)instance).Logger.LogWarning((object)"ENGINEER_E7_ROLLBACK_OK existing skin arrays retained."); } catch (Exception ex2) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E7_ROLLBACK_FAILED " + ex2)); } }); } private static IEnumerator EmptyStartup() { yield break; } private void Stage(string value) { startupStage = value; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E7_STARTUP_STAGE version=0.3.1 stage=" + value)); } private void RollbackRegistration() { registered = false; foreach (Prepared item in prepared) { if (Object.op_Implicit((Object)(object)item.Controller) && item.CommittedSkins != null && item.Controller.skins == item.CommittedSkins) { item.Controller.skins = item.OriginalSkins; } } foreach (BandVisuals startupVisual in startupVisuals) { if (Object.op_Implicit((Object)(object)startupVisual)) { Object.Destroy((Object)(object)startupVisual); } } startupVisuals.Clear(); if (Object.op_Implicit((Object)(object)cosmeticStorage)) { Object.Destroy((Object)(object)cosmeticStorage); cosmeticStorage = null; } } private void ValidateAndCommit() { foreach (Prepared p in prepared) { if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Private bake produced no runtime skin: " + p.BodyName); } if (p.Controller.skins != p.OriginalSkins) { throw new InvalidOperationException("Skin list changed during startup: " + p.BodyName); } if (p.OriginalSkins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == ((Object)p.Skin).name)) { throw new InvalidOperationException("Duplicate Primitive Solutions skin: " + ((Object)p.Skin).name); } p.CommittedSkins = p.OriginalSkins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { p.Skin }).ToArray(); } foreach (Prepared item in prepared) { item.Controller.skins = item.CommittedSkins; } } private IEnumerator RegisterAsync() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E7_REGISTRATION_BEGIN 0.3.1"); string[][] array = new string[3][] { new string[4] { "EngiTurretBody", "turret", "15", "skinEngiTurretDefault" }, new string[4] { "EngiWalkerTurretBody", "walker", "15", "skinEngiWalkerTurretDefault" }, new string[4] { "EngiBody", "primitive-solutions", "83", "skinEngiDefault" } }; foreach (string[] array2 in array) { Stage("prepare:" + array2[0]); yield return Prepare(array2[0], array2[1], int.Parse(array2[2]), array2[3]); } Prepared bodySkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiBody"); bodySkin.Skin.skinDefParams.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[2] { new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiTurretBody").Skin }, new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiWalkerTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiWalkerTurretBody").Skin } }; Stage("prepare:mine-ghosts"); yield return PrepareMineGhosts(bodySkin.Skin); foreach (Prepared p in prepared) { Stage("private-bake:" + p.BodyName); ValidateSkin(p); yield return p.Skin.BakeAsync(); if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Bake returned without runtime skin: " + p.BodyName); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E7_PRIVATE_BAKE_OK body=" + p.BodyName)); } Stage("commit"); ValidateAndCommit(); modelPrefab = bodySkin.Model; skin = bodySkin.Skin; foreach (Prepared item in prepared) { if (!Object.op_Implicit((Object)(object)item.Model.GetComponent<BandVisuals>())) { startupVisuals.Add(item.Model.AddComponent<BandVisuals>()); } } registered = true; Stage("registered"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E7_REGISTERED Primitive Solutions body, both turrets, pressure and spider mines; native Animator retained; unlocked=true version=0.3.1"); } private IEnumerator Prepare(string bodyName, string assetName, int boneCount, string defaultName) { GameObject val = BodyCatalog.FindBodyPrefab(bodyName); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing body " + bodyName); } GameObject model = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = model.GetComponent<ModelSkinController>(); SkinDef baseSkin = null; if (Object.op_Implicit((Object)(object)controller) && controller.skins != null && controller.skins.Length != 0) { baseSkin = controller.skins[0]; } if (!Object.op_Implicit((Object)(object)baseSkin)) { AsyncOperationHandle<SkinDef> h = Addressables.LoadAssetAsync<SkinDef>((object)("RoR2/Base/Engi/" + defaultName + ".asset")); retainedAssets.Add(AsyncOperationHandle<SkinDef>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline("default skin " + bodyName); yield return null; } baseSkin = h.Result; } if (!Object.op_Implicit((Object)(object)baseSkin)) { throw new InvalidOperationException("Missing default skin " + bodyName); } SkinDefParams bp = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)bp) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> h2 = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(h2)); while (!h2.IsDone) { CheckLoadDeadline("parameters " + bodyName); yield return null; } bp = h2.Result; } if (!Object.op_Implicit((Object)(object)bp)) { throw new InvalidOperationException("Missing parameters " + bodyName); } SkinnedMeshRenderer target = model.GetComponentsInChildren<SkinnedMeshRenderer>(true).Single((SkinnedMeshRenderer r) => r.bones.Length == boneCount); Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = bp.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference)) { AsyncOperationHandle<Mesh> h3 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(h3)); while (!h3.IsDone) { CheckLoadDeadline("mesh " + bodyName); yield return null; } reference = h3.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != target.bones.Length) { throw new InvalidOperationException("Bind pose mismatch " + bodyName); } RendererInfo ri = bp.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = ri.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && ri.defaultMaterialAddress != null && ((AssetReference)ri.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> h4 = Addressables.LoadAssetAsync<Material>(((AssetReference)ri.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(h4)); while (!h4.IsDone) { CheckLoadDeadline("material " + bodyName); yield return null; } val3 = h4.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Missing native material " + bodyName); } Mesh val4 = ReadMesh(Path.Combine(folder, assetName + ".meshbin"), target, reference); ((Object)val4).name = "EclipsePlaytest_EngineerE7_" + assetName; Material val5 = MakeMaterial(assetName, val3); canonicalBases[assetName] = new MeshBasis { Reference = reference, Authored = val4 }; ri.defaultMaterial = val5; ri.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { ri }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = val4, meshAddress = new AssetReferenceT<Mesh>("") } }; SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>(); ((Object)val7).name = "skinEclipsePlaytestEngineerE7_" + assetName; val7.nameToken = "ECLIPSEPLAYTEST_ENGINEER_E7_" + assetName.ToUpperInvariant().Replace('-', '_'); LanguageAPI.Add(val7.nameToken, (bodyName == "EngiBody") ? "Primitive Solutions (Playtest)" : ("Primitive Solutions " + assetName)); val7.icon = CreateIcon(Designs[0].Colors); val7.unlockableDef = null; val7.rootObject = model; val7.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; val7.skinDefParams = val6; if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { throw new InvalidOperationException("Missing native skin controller/list: " + bodyName); } prepared.Add(new Prepared { BodyName = bodyName, Model = model, Controller = controller, Skin = val7, Mesh = val4, Reference = reference, Material = val5, OriginalSkins = controller.skins }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E7_PREPARED body=" + bodyName + " vertices=" + val4.vertexCount + " unlocked=true")); } private static void ValidateSkin(Prepared p) { //IL_00ee: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) SkinDef skin = p.Skin; SkinDefParams skinDefParams = skin.skinDefParams; if (!Object.op_Implicit((Object)(object)skin.rootObject) || !Object.op_Implicit((Object)(object)skinDefParams) || skin.baseSkins == null || skin.baseSkins.Any((SkinDef s) => !Object.op_Implicit((Object)(object)s) || s == skin)) { throw new InvalidOperationException("Invalid skin graph: " + p.BodyName); } if (skin.skinDefParamsAddress == null) { skin.skinDefParamsAddress = new AssetReferenceT<SkinDefParams>(""); } if (skinDefParams.rendererInfos == null || skinDefParams.meshReplacements == null || skinDefParams.gameObjectActivations == null || skinDefParams.lightReplacements == null || skinDefParams.projectileGhostReplacements == null || skinDefParams.minionSkinReplacements == null) { throw new InvalidOperationException("Null parameter collection: " + p.BodyName); } RendererInfo[] rendererInfos = skinDefParams.rendererInfos; foreach (RendererInfo val in rendererInfos) { if (!Object.op_Implicit((Object)(object)val.renderer) || !Object.op_Implicit((Object)(object)val.defaultMaterial) || !((Component)val.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid material/renderer root: " + p.BodyName); } } MeshReplacement[] meshReplacements = skinDefParams.meshReplacements; foreach (MeshReplacement val2 in meshReplacements) { if (!Object.op_Implicit((Object)(object)val2.renderer) || !Object.op_Implicit((Object)(object)val2.mesh) || !((Component)val2.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid mesh/renderer root: " + p.BodyName); } } ProjectileGhostReplacement[] projectileGhostReplacements = skinDefParams.projectileGhostReplacements; foreach (ProjectileGhostReplacement val3 in projectileGhostReplacements) { if (!Object.op_Implicit((Object)(object)val3.projectilePrefab) || !Object.op_Implicit((Object)(object)val3.projectileGhostReplacementPrefab) || ProjectileCatalog.GetProjectileIndex(val3.projectilePrefab) < 0) { throw new InvalidOperationException("Unregistered mine projectile: " + p.BodyName); } } MinionSkinReplacement[] minionSkinReplacements = skinDefParams.minionSkinReplacements; foreach (MinionSkinReplacement val4 in minionSkinReplacements) { if (!Object.op_Implicit((Object)(object)val4.minionBodyPrefab) || !Object.op_Implicit((Object)(object)val4.minionSkin) || val4.minionSkin.runtimeSkin == null) { throw new InvalidOperationException("Unbaked turret skin: " + p.BodyName); } } } private static Sprite CreateIcon(Color32[] colors) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00c6: 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_0083: 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_0071: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : colors[num]); } } val.SetPixels32(array); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private void CheckLoadDeadline(string asset) { if (Time.realtimeSinceStartup > registrationDeadline) { throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin."); } } private void SyncDisplaySkins() { if (!registered) { return; } try { SyncDisplaySkinsChecked(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("ENGINEER_E7_DISPLAY_SYNC_FAILED version=0.3.1 " + ex)); } } private void SyncDisplaySkinsChecked() { SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "EngiBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)val.displayPrefab.GetComponent<BandVisuals>())) { val.displayPrefab.AddComponent<BandVisuals>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E7_DISPLAY_READY version=0.3.1 skins=" + val2.skins.Length + " catalogSkins=" + SkinCatalog.skinCount)); } } private Texture2D ReadTexture(string name, bool linear) { return textureCache.Load(Path.Combine(folder, name), linear); } private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_0592: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (new string(binaryReader.ReadChars(4)) != "PWE2") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0 || !hashSet.Add(array[i])) { throw new InvalidDataException("Missing/duplicate reference bone: " + name); } } Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num3]; for (int num5 = 0; num5 < num3; num5++) { Matrix4x4 val = default(Matrix4x4); for (int num6 = 0; num6 < 4; num6++) { for (int num7 = 0; num7 < 4; num7++) { float num8 = binaryReader.ReadSingle(); if (float.IsNaN(num8) || float.IsInfinity(num8)) { throw new InvalidDataException("Invalid bind matrix."); } ((Matrix4x4)(ref val))[num6, num7] = num8; } } if (Math.Abs(((Matrix4x4)(ref val)).determinant) < 1E-05f) { throw new InvalidDataException("Singular bind matrix."); } array2[array[num5]] = val; } Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector3[] array4 = (Vector3[])(object)new Vector3[num]; Vector2[] array5 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array6 = (BoneWeight[])(object)new BoneWeight[num]; for (int num9 = 0; num9 < num; num9++) { array3[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array5[num9] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); int[] array7 = new int[4]; for (int num10 = 0; num10 < 4; num10++) { int num11 = binaryReader.ReadInt32(); if (num11 < 0 || num11 >= num3) { throw new InvalidDataException("Bone out of range."); } array7[num10] = array[num11]; } float[] array8 = new float[4]; for (int num12 = 0; num12 < 4; num12++) { array8[num12] = binaryReader.ReadSingle(); } if (array8.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array8.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } if (!Finite(array3[num9]) || !Finite(array4[num9])) { throw new InvalidDataException("Non-finite vertex."); } int num13 = num9; BoneWeight val2 = default(BoneWeight); ((BoneWeight)(ref val2)).boneIndex0 = array7[0]; ((BoneWeight)(ref val2)).boneIndex1 = array7[1]; ((BoneWeight)(ref val2)).boneIndex2 = array7[2]; ((BoneWeight)(ref val2)).boneIndex3 = array7[3]; ((BoneWeight)(ref val2)).weight0 = array8[0]; ((BoneWeight)(ref val2)).weight1 = array8[1]; ((BoneWeight)(ref val2)).weight2 = array8[2]; ((BoneWeight)(ref val2)).weight3 = array8[3]; array6[num13] = val2; } int[] array9 = new int[num2]; for (int num14 = 0; num14 < num2; num14++) { array9[num14] = binaryReader.ReadInt32(); if (array9[num14] < 0 || array9[num14] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } if (Object.op_Implicit((Object)(object)reference) && reference.bindposes.Length == num3) { Matrix4x4[] bindposes = reference.bindposes; int num15 = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Base"); if (num15 < 0) { num15 = 0; } Matrix4x4 b = ((Matrix4x4)(ref bindposes[num15])).inverse * array2[num15]; bool flag = true; for (int num16 = 0; num16 < num3; num16++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[num16])).inverse * array2[num16], b, 0.0002f)) { flag = false; } } if (!flag) { if (num3 != 2 && (num3 != 14 || !renderer.bones.Any((Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Screw"))) { throw new InvalidDataException("Unsupported nonuniform bind variant: " + ((Object)renderer).name); } Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int num17 = 0; num17 < num; num17++) { array3[num17] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(array3[num17]); int num18 = num17; Vector3 val3 = ((Matrix4x4)(ref transpose)).MultiplyVector(array4[num17]); array4[num18] = ((Vector3)(ref val3)).normalized; } array2 = bindposes; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E7_MINE_BIND_VARIANT renderer=" + ((Object)renderer).name + " reference=" + ((Object)reference).name)); } } Mesh val4 = new Mesh { name = "EclipsePlaytestEngineerPrimitiveSolutions", indexFormat = (IndexFormat)(num > 65535), vertices = array3, normals = array4, uv = array5, boneWeights = array6, bindposes = array2, triangles = array9 }; val4.RecalculateBounds(); val4.RecalculateTangents(); return val4; } private Material MakeMaterial(string asset, Material source) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (assetMaterials.TryGetValue(asset, out var value)) { return value; } if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader)) { throw new InvalidOperationException("Missing shader for " + asset); } value = new Material(source) { name = "matEclipsePlaytest_EngineerE7_" + asset }; value.SetTexture("_MainTex", (Texture)(object)ReadTexture(asset + "-albedo-spec.png", linear: false)); value.SetTexture("_NormalTex", (Texture)(object)ReadTexture(asset + "-normal.png", linear: true)); value.SetTexture("_EmTex", (Texture)(object)ReadTexture(asset + "-emission.png", linear: false)); value.SetColor("_Color", Color.white); value.SetFloat("_NormalStrength", 0.3f); value.SetFloat("_Smoothness", 0.28f); value.SetFloat("_SpecularStrength", 0.35f); value.SetFloat("_SpecularExponent", 8f); value.SetFloat("_EmPower", asset.EndsWith("mine", StringComparison.Ordinal) ? 0.4f : 0f); value.DisableKeyword("LIMBREMOVAL"); value.SetFloat("_LimbRemovalOn", 0f); assetMaterials.Add(asset, value); return value; } private static string MineAsset(Renderer r) { if (((Object)r).name == "EngiMineMesh") { return "pressure-mine"; } if (((Object)r).name == "EngiSpiderMineMesh") { return "spider-mine"; } return null; } private IEnumerator PrepareMineGhosts(SkinDef bodySkin) { cosmeticStorage = new GameObject("PrimitiveSolutionsCosmeticPrefabs"); cosmeticStorage.SetActive(false); Object.DontDestroyOnLoad((Object)(object)cosmeticStorage); List<ProjectileGhostReplacement> replacements = new List<ProjectileGhostReplacement>(); string[] array = new string[2] { "EngiMine", "SpiderMine" }; foreach (string name in array) { AsyncOperationHandle<GameObject> h = Addressables.LoadAssetAsync<GameObject>((object)("RoR2/Base/Engi/" + name + ".prefab")); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline(name); yield return null; } if (!Object.op_Implicit((Object)(object)h.Result)) { throw new InvalidOperationException("Missing projectile " + name); } ProjectileController component = h.Result.GetComponent<ProjectileController>(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("Missing ProjectileController " + name); } GameObject val = component.ghostPrefab; if (!Object.op_Implicit((Object)(object)val) && component.ghostPrefabAddress != null && ((AssetReference)component.ghostPrefabAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<GameObject> gh = Addressables.LoadAssetAsync<GameObject>(((AssetReference)component.ghostPrefabAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(gh)); while (!gh.IsDone) { CheckLoadDeadline(name + " ghost"); yield return null; } val = gh.Result; } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing mine ghost " + name); } GameObject val2 = Object.Instantiate<GameObject>(val, cosmeticStorage.transform); ((Object)val2).name = "EclipsePrimitiveSolutions_" + name + "Ghost"; string asset = ((name == "EngiMine") ? "pressure-mine" : "spider-mine"); SkinnedMeshRenderer[] array2 = (from r in val2.GetComponentsInChildren<SkinnedMeshRenderer>(true) where MineAsset((Renderer)(object)r) == asset select r).ToArray(); if (array2.Length != 1) { throw new InvalidOperationException("Ambiguous mine renderer " + name + ": " + array2.Length); } SkinnedMeshRenderer val3 = array2[0]; int num = ((asset == "pressure-mine") ? 2 : 14); if (val3.bones.Length != num || !Object.op_Implicit((Object)(object)val3.sharedMesh)) { throw new InvalidOperationException("Missing native mine rig " + name); } Mesh sharedMesh = val3.sharedMesh; Mesh val4 = MeshFor(asset, val3); Material sharedMaterial = MakeMaterial(asset, ((Renderer)val3).sharedMaterial); canonicalBases[asset] = new MeshBasis { Reference = sharedMesh, Authored = val4 }; val3.sharedMesh = val4; ((Renderer)val3).sharedMaterial = sharedMaterial; Mesh val5 = new Mesh(); val3.BakeMesh(val5); Bounds localBounds = ((Renderer)val3).localBounds; Bounds bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).min); bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).max); ((Bounds)(ref localBounds)).Expand(((Bounds)(ref localBounds)).size * 0.5f); ((Renderer)val3).localBounds = localBounds; Object.Destroy((Object)(object)val5); val3.updateWhenOffscreen = true; val2.SetActive(true); replacements.Add(new ProjectileGhostReplacement { projectilePrefab = h.Result, projectileGhostReplacementPrefab = val2, ghostReplacementAddress = new AssetReferenceT<GameObject>("") }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E7_MINE_READY asset=" + asset + " vertices=" + val4.vertexCount + " native effects/controller preserved")); } bodySkin.skinDefParams.projectileGhostReplacements = replacements.ToArray(); } private Mesh MeshFor(string asset, SkinnedMeshRenderer target, Mesh nativeReference = null) { if (!Object.op_Implicit((Object)(object)nativeReference)) { nativeReference = target.sharedMesh; } string key = asset + "|" + (Object.op_Implicit((Object)(object)nativeReference) ? ((Object)nativeReference).GetInstanceID() : 0) + "|" + string.Join("|", target.bones.Select((Transform b) => (!Object.op_Implicit((Object)(object)b)) ? "<null>" : ((Object)b).name)); if (!remappedMeshes.TryGetValue(key, out var value)) { value = ReadMesh(Path.Combine(folder, asset + ".meshbin"), target, nativeReference); remappedMeshes.Add(key, value); } return value; } private static bool SameMatrix(Matrix4x4 a, Matrix4x4 b, float tolerance) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (Math.Abs(((Matrix4x4)(ref a))[i, j] - ((Matrix4x4)(ref b))[i, j]) > tolerance) { return false; } } } return true; } private Mesh StaticMeshFor(string asset, Mesh reference) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)reference)) { throw new InvalidOperationException("Missing static reference " + asset); } string key = asset + "|" + ((Object)reference).GetInstanceID(); if (staticMeshes.TryGetValue(key, out var value)) { return value; } if (!canonicalBases.TryGetValue(asset, out var value2)) { throw new InvalidOperationException("Missing canonical rig " + asset); } Matrix4x4[] bindposes = reference.bindposes; Matrix4x4[] bindposes2 = value2.Authored.bindposes; if (bindposes.Length != bindposes2.Length || bindposes.Length == 0) { throw new InvalidOperationException("Static bind count " + asset); } Matrix4x4 b = ((Matrix4x4)(ref bindposes[0])).inverse * bindposes2[0]; for (int i = 1; i < bindposes.Length; i++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[i])).inverse * bindposes2[i], b, 0.0002f)) { if (asset != "pressure-mine" && asset != "spider-mine") { throw new InvalidOperationException("Nonuniform static bind conversion " + asset + " bone " + i); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E7_STATIC_MINE_BIND_VARIANT " + asset + " uses canonical assembled rest shape")); break; } } value = Object.Instantiate<Mesh>(value2.Authored); ((Object)value).name = "EclipseEngineerE7Static_" + asset; Vector3[] vertices = value.vertices; Vector3[] normals = value.normals; Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int j = 0; j < vertices.Length; j++) { vertices[j] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(vertices[j]); int num = j; Vector3 val = ((Matrix4x4)(ref transpose)).MultiplyVector(normals[j]); normals[num] = ((Vector3)(ref val)).normalized; } value.vertices = vertices; value.normals = normals; value.boneWeights = (BoneWeight[])(object)new BoneWeight[0]; value.bindposes = (Matrix4x4[])(object)new Matrix4x4[0]; value.RecalculateBounds(); value.RecalculateTangents(); staticMeshes.Add(key, value); return value; } private static bool Finite(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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_0028: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(v.x + v.y + v.z)) { return !float.IsInfinity(v.x + v.y + v.z); } return false; } } internal static class StartupGuard { internal static IEnumerator Run(Func<IEnumerator> create, Func<bool> expired, Action<Exception> failed) { Stack<IEnumerator> stack = new Stack<IEnumerator>(); Exception failure = null; try { stack.Push(create()); } catch (Exception ex) { failure = ex; } try { while (failure == null && stack.Count > 0) { bool flag = false; object obj = null; try { if (expired()) { throw new TimeoutException("Primitive Solutions startup deadline exceeded."); } IEnumerator enumerator = stack.Peek(); flag = enumerator.MoveNext(); if (flag) { obj = enumerator.Current; } else { stack.Pop(); (enumerator as IDisposable)?.Dispose(); } } catch (Exception ex2) { failure = ex2; } if (failure != null) { break; } if (flag) { if (obj is IEnumerator item) { stack.Push(item); } else { yield return obj; } } } } finally { if (stack.Count > 0 && failure == null) { failure = new OperationCanceledException("Primitive Solutions startup iterator was cancelled."); } while (stack.Count > 0) { try { (stack.Pop() as IDisposable)?.Dispose(); } catch (Exception ex3) { if (failure == null) { failure = ex3; } } } if (failure != null) { try { failed(failure); } catch { } } } } } internal sealed class TextureAssetCache { private readonly Dictionary<string, Texture2D> values = new Dictionary<string, Texture2D>(); internal Texture2D Load(string path, bool linear) { //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_006f: 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_007e: Expected O, but got Unknown byte[] array = File.ReadAllBytes(path); string key; using (SHA256 sHA = SHA256.Create()) { key = (linear ? "linear:" : "srgb:") + Convert.ToBase64String(sHA.ComputeHash(array)); } if (values.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear) { name = Path.GetFileName(path), anisoLevel = 4, filterMode = (FilterMode)2 }; try { if (!ImageConversion.LoadImage(val, array, true)) { throw new InvalidDataException("Cannot decode " + Path.GetFileName(path)); } values[key] = val; return val; } catch { Object.Destroy((Object)(object)val); throw; } } }
BepInEx/plugins/RodaniusSkins/engineer-traffic-control/EngineerTrafficControl.dll
Decompiled a week agousing 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.Security.Cryptography; using System.Text; using BepInEx; using EngineerCastleDoctrinePlaytest; using EntityStates; using EntityStates.Engi.EngiWeapon; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.Projectile; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EngineerTrafficControlPlaytest; [BepInPlugin("eclipseplaytest.engineer.e5", "Engineer - Traffic Control (Playtest)", "0.3.1")] [BepInDependency("eclipseplaytest.engineer.e4", "0.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EngineerTrafficControl : BaseUnityPlugin { private sealed class Prepared { public SkinDef[] OriginalSkins; public SkinDef[] CommittedSkins; public string BodyName; public GameObject Model; public ModelSkinController Controller; public SkinDef Skin; public Mesh Mesh; public Mesh Reference; public Material Material; } private sealed class Design { public string Slug; public string Name; public Color32[] Colors; public Design(string slug, string name, Color32[] colors) { Slug = slug; Name = name; Colors = colors; } } private sealed class MeshBasis { public Mesh Reference; public Mesh Authored; } public sealed class BandVisuals : MonoBehaviour { private sealed class Saved { public Renderer Renderer; public Mesh Mesh; public Material[] Materials; public Bounds Bounds; public bool Offscreen; public bool ChangeMesh; public bool ChangeMaterial; public Mesh AssignedMesh; public Material[] AssignedMaterials; public bool ChangeBounds; public Bounds AssignedBounds; public bool ChangeOffscreen; public bool AssignedOffscreen; } private readonly Dictionary<Renderer, Saved> changed = new Dictionary<Renderer, Saved>(); private ModelSkinController controller; private CharacterBody body; private EntityStateMachine[] machines; private bool lobbyDirty = true; private static readonly FieldInfo Blueprint = typeof(PlaceTurret).GetField("blueprints", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo Wrist = typeof(PlaceTurret).GetField("wristDisplayObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private void Applied(int index) { if (!OwnSkin() && changed.Count > 0) { Restore(); } lobbyDirty = true; } private void Start() { controller = ((Component)this).GetComponentInChildren<ModelSkinController>(true); body = ((Component)this).GetComponentInParent<CharacterBody>(); machines = (EntityStateMachine[])(Object.op_Implicit((Object)(object)body) ? ((Array)((Component)body).GetComponents<EntityStateMachine>()) : ((Array)new EntityStateMachine[0])); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; } } private bool OwnSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length && Object.op_Implicit((Object)(object)controller.skins[currentSkinIndex])) { return ((Object)controller.skins[currentSkinIndex]).name.StartsWith("skinEclipsePlaytestEngineerE5_", StringComparison.Ordinal); } return false; } private Saved Save(Renderer r) { //IL_0074: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (changed.TryGetValue(r, out var value)) { return value; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((r is SkinnedMeshRenderer) ? r : null); MeshFilter component = ((Component)r).GetComponent<MeshFilter>(); value = new Saved { Renderer = r, Materials = r.sharedMaterials, Mesh = (Object.op_Implicit((Object)(object)val) ? val.sharedMesh : (Object.op_Implicit((Object)(object)component) ? component.sharedMesh : null)), Bounds = (Bounds)(Object.op_Implicit((Object)(object)val) ? ((Renderer)val).localBounds : default(Bounds)), Offscreen = (Object.op_Implicit((Object)(object)val) && val.updateWhenOffscreen) }; changed.Add(r, value); return value; } private void ApplySkinned(SkinnedMeshRenderer r, string asset, bool keepMaterial) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) Saved saved = Save((Renderer)(object)r); saved.ChangeMesh = true; saved.ChangeMaterial = !keepMaterial; Mesh val = (saved.AssignedMesh = instance.MeshFor(asset, r, saved.Mesh)); if ((Object)(object)r.sharedMesh != (Object)(object)val) { r.sharedMesh = val; Mesh val2 = new Mesh(); r.BakeMesh(val2); Bounds bounds = saved.Bounds; Bounds bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).min); bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).max); ((Bounds)(ref bounds)).Expand(((Bounds)(ref bounds)).size * 0.5f); ((Renderer)r).localBounds = bounds; saved.ChangeBounds = true; saved.AssignedBounds = bounds; Object.Destroy((Object)(object)val2); } r.updateWhenOffscreen = true; saved.ChangeOffscreen = true; saved.AssignedOffscreen = true; if (!keepMaterial) { ((Renderer)r).sharedMaterial = instance.assetMaterials[asset]; saved.AssignedMaterials = ((Renderer)r).sharedMaterials; } } private void Restore() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) foreach (Saved value in changed.Values) { if (!Object.op_Implicit((Object)(object)value.Renderer)) { continue; } Renderer renderer = value.Renderer; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); MeshFilter component = ((Component)value.Renderer).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)val)) { if (value.ChangeMesh && (Object)(object)val.sharedMesh == (Object)(object)value.AssignedMesh) { if (value.ChangeBounds && ((Renderer)val).localBounds == value.AssignedBounds) { ((Renderer)val).localBounds = value.Bounds; } if (value.ChangeOffscreen && val.updateWhenOffscreen == value.AssignedOffscreen) { val.updateWhenOffscreen = value.Offscreen; } val.sharedMesh = value.Mesh; } } else if (Object.op_Implicit((Object)(object)component) && value.ChangeMesh && (Object)(object)component.sharedMesh == (Object)(object)value.AssignedMesh) { component.sharedMesh = value.Mesh; } if (value.ChangeMaterial && value.AssignedMaterials != null && value.Renderer.sharedMaterials.SequenceEqual(value.AssignedMaterials)) { value.Renderer.sharedMaterials = value.Materials; } } changed.Clear(); } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)instance) || !instance.registered) { return; } Renderer[] array = changed.Keys.Where((Renderer r) => !Object.op_Implicit((Object)(object)r)).ToArray(); foreach (Renderer key in array) { changed.Remove(key); } if (!OwnSkin()) { if (changed.Count > 0) { Restore(); } lobbyDirty = true; return; } if (lobbyDirty) { SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { string text = MineAsset((Renderer)(object)val); if (text != null) { ApplySkinned(val, text, keepMaterial: false); } else if (!Object.op_Implicit((Object)(object)body) && val.bones.Length == 15 && Object.op_Implicit((Object)(object)((Component)this).transform.Find("TurretHolder")) && ((Component)val).transform.IsChildOf(((Component)this).transform.Find("TurretHolder"))) { ApplySkinned(val, "turret", keepMaterial: false); } } MeshRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren2) { string text2 = MineAsset((Renderer)(object)val2); if (text2 != null) { MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)component)) { Saved saved = Save((Renderer)(object)val2); saved.ChangeMesh = true; component.sharedMesh = instance.StaticMeshFor(text2, saved.Mesh); saved.AssignedMesh = component.sharedMesh; saved.ChangeMaterial = true; ((Renderer)val2).sharedMaterial = instance.assetMaterials[text2]; saved.AssignedMaterials = ((Renderer)val2).sharedMaterials; } } } lobbyDirty = false; } if (!Object.op_Implicit((Object)(object)body)) { return; } EntityStateMachine[] array2 = machines; for (int num = 0; num < array2.Length; num++) { EntityState state = array2[num].state; PlaceTurret val3 = (PlaceTurret)(object)((state is PlaceTurret) ? state : null); if (val3 == null) { continue; } string asset = ((val3 is PlaceWalkerTurret) ? "walker" : "turret"); object? obj = Blueprint?.GetValue(val3); BlueprintController val4 = (BlueprintController)((obj is BlueprintController) ? obj : null); if (Object.op_Implicit((Object)(object)val4)) { SkinnedMeshRenderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val5 in componentsInChildren) { if (val5.bones.Length == 15) { ApplySkinned(val5, asset, keepMaterial: true); } } } object? obj2 = Wrist?.GetValue(val3); GameObject val6 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (!Object.op_Implicit((Object)(object)val6)) { continue; } MeshFilter[] componentsInChildren3 = val6.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val7 in componentsInChildren3) { if (((Object)val7).name == "EngiTurretMesh") { Renderer component2 = ((Component)val7).GetComponent<Renderer>(); Saved saved2 = Save(component2); saved2.ChangeMesh = true; val7.sharedMesh = instance.StaticMeshFor(asset, saved2.Mesh); saved2.AssignedMesh = val7.sharedMesh; } } } } private void OnDisable() { Restore(); lobbyDirty = true; } private void OnDestroy() { if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } } } public const string Guid = "eclipseplaytest.engineer.e5"; public const string Version = "0.3.1"; private static EngineerTrafficControl instance; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private float registrationDeadline; private string folder; private SkinDef skin; private GameObject modelPrefab; private string startupStage = "awake"; private readonly List<BandVisuals> startupVisuals = new List<BandVisuals>(); private readonly List<Prepared> prepared = new List<Prepared>(); private bool registered; private static readonly Design[] Designs = new Design[1] { new Design("traffic-control", "Traffic Control (Playtest)", (Color32[])(object)new Color32[4] { new Color32((byte)240, (byte)101, (byte)24, byte.MaxValue), new Color32((byte)238, (byte)234, (byte)209, byte.MaxValue), new Color32((byte)40, (byte)44, (byte)46, byte.MaxValue), new Color32((byte)239, (byte)184, (byte)38, byte.MaxValue) }) }; private readonly TextureAssetCache textureCache = new TextureAssetCache(); private GameObject cosmeticStorage; private readonly Dictionary<string, MeshBasis> canonicalBases = new Dictionary<string, MeshBasis>(); private readonly Dictionary<string, Material> assetMaterials = new Dictionary<string, Material>(); private readonly Dictionary<string, Mesh> remappedMeshes = new Dictionary<string, Mesh>(); private readonly Dictionary<string, Mesh> staticMeshes = new Dictionary<string, Mesh>(); private void Awake() { folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); instance = this; SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(EngineerTrafficControl)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; } [SystemInitializer(new Type[] { typeof(BodyCatalog), typeof(ProjectileCatalog), typeof(SurvivorCatalog), typeof(EngineerCastleDoctrine) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { return EmptyStartup(); } instance.registrationDeadline = Time.realtimeSinceStartup + 60f; return StartupGuard.Run(instance.RegisterAsync, () => Time.realtimeSinceStartup > instance.registrationDeadline, delegate(Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E5_STARTUP_DISABLED version=0.3.1 stage=" + instance.startupStage + " " + ex)); try { instance.RollbackRegistration(); ((BaseUnityPlugin)instance).Logger.LogWarning((object)"ENGINEER_E5_ROLLBACK_OK existing skin arrays retained."); } catch (Exception ex2) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E5_ROLLBACK_FAILED " + ex2)); } }); } private static IEnumerator EmptyStartup() { yield break; } private void Stage(string value) { startupStage = value; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E5_STARTUP_STAGE version=0.3.1 stage=" + value)); } private void RollbackRegistration() { registered = false; foreach (Prepared item in prepared) { if (Object.op_Implicit((Object)(object)item.Controller) && item.CommittedSkins != null && item.Controller.skins == item.CommittedSkins) { item.Controller.skins = item.OriginalSkins; } } foreach (BandVisuals startupVisual in startupVisuals) { if (Object.op_Implicit((Object)(object)startupVisual)) { Object.Destroy((Object)(object)startupVisual); } } startupVisuals.Clear(); if (Object.op_Implicit((Object)(object)cosmeticStorage)) { Object.Destroy((Object)(object)cosmeticStorage); cosmeticStorage = null; } } private void ValidateAndCommit() { foreach (Prepared p in prepared) { if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Private bake produced no runtime skin: " + p.BodyName); } if (p.Controller.skins != p.OriginalSkins) { throw new InvalidOperationException("Skin list changed during startup: " + p.BodyName); } if (p.OriginalSkins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == ((Object)p.Skin).name)) { throw new InvalidOperationException("Duplicate Traffic Control skin: " + ((Object)p.Skin).name); } p.CommittedSkins = p.OriginalSkins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { p.Skin }).ToArray(); } foreach (Prepared item in prepared) { item.Controller.skins = item.CommittedSkins; } } private IEnumerator RegisterAsync() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E5_REGISTRATION_BEGIN 0.3.1"); string[][] array = new string[3][] { new string[4] { "EngiTurretBody", "turret", "15", "skinEngiTurretDefault" }, new string[4] { "EngiWalkerTurretBody", "walker", "15", "skinEngiWalkerTurretDefault" }, new string[4] { "EngiBody", "traffic-control", "83", "skinEngiDefault" } }; foreach (string[] array2 in array) { Stage("prepare:" + array2[0]); yield return Prepare(array2[0], array2[1], int.Parse(array2[2]), array2[3]); } Prepared bodySkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiBody"); bodySkin.Skin.skinDefParams.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[2] { new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiTurretBody").Skin }, new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiWalkerTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiWalkerTurretBody").Skin } }; Stage("prepare:mine-ghosts"); yield return PrepareMineGhosts(bodySkin.Skin); foreach (Prepared p in prepared) { Stage("private-bake:" + p.BodyName); ValidateSkin(p); yield return p.Skin.BakeAsync(); if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Bake returned without runtime skin: " + p.BodyName); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E5_PRIVATE_BAKE_OK body=" + p.BodyName)); } Stage("commit"); ValidateAndCommit(); modelPrefab = bodySkin.Model; skin = bodySkin.Skin; foreach (Prepared item in prepared) { if (!Object.op_Implicit((Object)(object)item.Model.GetComponent<BandVisuals>())) { startupVisuals.Add(item.Model.AddComponent<BandVisuals>()); } } registered = true; Stage("registered"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E5_REGISTERED Traffic Control body, both turrets, pressure and spider mines; native Animator retained; unlocked=true version=0.3.1"); } private IEnumerator Prepare(string bodyName, string assetName, int boneCount, string defaultName) { GameObject val = BodyCatalog.FindBodyPrefab(bodyName); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing body " + bodyName); } GameObject model = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = model.GetComponent<ModelSkinController>(); SkinDef baseSkin = null; if (Object.op_Implicit((Object)(object)controller) && controller.skins != null && controller.skins.Length != 0) { baseSkin = controller.skins[0]; } if (!Object.op_Implicit((Object)(object)baseSkin)) { AsyncOperationHandle<SkinDef> h = Addressables.LoadAssetAsync<SkinDef>((object)("RoR2/Base/Engi/" + defaultName + ".asset")); retainedAssets.Add(AsyncOperationHandle<SkinDef>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline("default skin " + bodyName); yield return null; } baseSkin = h.Result; } if (!Object.op_Implicit((Object)(object)baseSkin)) { throw new InvalidOperationException("Missing default skin " + bodyName); } SkinDefParams bp = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)bp) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> h2 = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(h2)); while (!h2.IsDone) { CheckLoadDeadline("parameters " + bodyName); yield return null; } bp = h2.Result; } if (!Object.op_Implicit((Object)(object)bp)) { throw new InvalidOperationException("Missing parameters " + bodyName); } SkinnedMeshRenderer target = model.GetComponentsInChildren<SkinnedMeshRenderer>(true).Single((SkinnedMeshRenderer r) => r.bones.Length == boneCount); Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = bp.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference)) { AsyncOperationHandle<Mesh> h3 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(h3)); while (!h3.IsDone) { CheckLoadDeadline("mesh " + bodyName); yield return null; } reference = h3.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != target.bones.Length) { throw new InvalidOperationException("Bind pose mismatch " + bodyName); } RendererInfo ri = bp.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = ri.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && ri.defaultMaterialAddress != null && ((AssetReference)ri.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> h4 = Addressables.LoadAssetAsync<Material>(((AssetReference)ri.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(h4)); while (!h4.IsDone) { CheckLoadDeadline("material " + bodyName); yield return null; } val3 = h4.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Missing native material " + bodyName); } Mesh val4 = ReadMesh(Path.Combine(folder, assetName + ".meshbin"), target, reference); ((Object)val4).name = "EclipsePlaytest_EngineerE5_" + assetName; Material val5 = MakeMaterial(assetName, val3); canonicalBases[assetName] = new MeshBasis { Reference = reference, Authored = val4 }; ri.defaultMaterial = val5; ri.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { ri }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = val4, meshAddress = new AssetReferenceT<Mesh>("") } }; SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>(); ((Object)val7).name = "skinEclipsePlaytestEngineerE5_" + assetName; val7.nameToken = "ECLIPSEPLAYTEST_ENGINEER_E5_" + assetName.ToUpperInvariant().Replace('-', '_'); LanguageAPI.Add(val7.nameToken, (bodyName == "EngiBody") ? "Traffic Control (Playtest)" : ("Traffic Control " + assetName)); val7.icon = CreateIcon(Designs[0].Colors); val7.unlockableDef = null; val7.rootObject = model; val7.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; val7.skinDefParams = val6; if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { throw new InvalidOperationException("Missing native skin controller/list: " + bodyName); } prepared.Add(new Prepared { BodyName = bodyName, Model = model, Controller = controller, Skin = val7, Mesh = val4, Reference = reference, Material = val5, OriginalSkins = controller.skins }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E5_PREPARED body=" + bodyName + " vertices=" + val4.vertexCount + " unlocked=true")); } private static void ValidateSkin(Prepared p) { //IL_00ee: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) SkinDef skin = p.Skin; SkinDefParams skinDefParams = skin.skinDefParams; if (!Object.op_Implicit((Object)(object)skin.rootObject) || !Object.op_Implicit((Object)(object)skinDefParams) || skin.baseSkins == null || skin.baseSkins.Any((SkinDef s) => !Object.op_Implicit((Object)(object)s) || s == skin)) { throw new InvalidOperationException("Invalid skin graph: " + p.BodyName); } if (skin.skinDefParamsAddress == null) { skin.skinDefParamsAddress = new AssetReferenceT<SkinDefParams>(""); } if (skinDefParams.rendererInfos == null || skinDefParams.meshReplacements == null || skinDefParams.gameObjectActivations == null || skinDefParams.lightReplacements == null || skinDefParams.projectileGhostReplacements == null || skinDefParams.minionSkinReplacements == null) { throw new InvalidOperationException("Null parameter collection: " + p.BodyName); } RendererInfo[] rendererInfos = skinDefParams.rendererInfos; foreach (RendererInfo val in rendererInfos) { if (!Object.op_Implicit((Object)(object)val.renderer) || !Object.op_Implicit((Object)(object)val.defaultMaterial) || !((Component)val.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid material/renderer root: " + p.BodyName); } } MeshReplacement[] meshReplacements = skinDefParams.meshReplacements; foreach (MeshReplacement val2 in meshReplacements) { if (!Object.op_Implicit((Object)(object)val2.renderer) || !Object.op_Implicit((Object)(object)val2.mesh) || !((Component)val2.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid mesh/renderer root: " + p.BodyName); } } ProjectileGhostReplacement[] projectileGhostReplacements = skinDefParams.projectileGhostReplacements; foreach (ProjectileGhostReplacement val3 in projectileGhostReplacements) { if (!Object.op_Implicit((Object)(object)val3.projectilePrefab) || !Object.op_Implicit((Object)(object)val3.projectileGhostReplacementPrefab) || ProjectileCatalog.GetProjectileIndex(val3.projectilePrefab) < 0) { throw new InvalidOperationException("Unregistered mine projectile: " + p.BodyName); } } MinionSkinReplacement[] minionSkinReplacements = skinDefParams.minionSkinReplacements; foreach (MinionSkinReplacement val4 in minionSkinReplacements) { if (!Object.op_Implicit((Object)(object)val4.minionBodyPrefab) || !Object.op_Implicit((Object)(object)val4.minionSkin) || val4.minionSkin.runtimeSkin == null) { throw new InvalidOperationException("Unbaked turret skin: " + p.BodyName); } } } private static Sprite CreateIcon(Color32[] colors) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00c6: 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_0083: 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_0071: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : colors[num]); } } val.SetPixels32(array); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private void CheckLoadDeadline(string asset) { if (Time.realtimeSinceStartup > registrationDeadline) { throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin."); } } private void SyncDisplaySkins() { if (!registered) { return; } try { SyncDisplaySkinsChecked(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("ENGINEER_E5_DISPLAY_SYNC_FAILED version=0.3.1 " + ex)); } } private void SyncDisplaySkinsChecked() { SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "EngiBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)val.displayPrefab.GetComponent<BandVisuals>())) { val.displayPrefab.AddComponent<BandVisuals>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E5_DISPLAY_READY version=0.3.1 skins=" + val2.skins.Length + " catalogSkins=" + SkinCatalog.skinCount)); } } private Texture2D ReadTexture(string name, bool linear) { return textureCache.Load(Path.Combine(folder, name), linear); } private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_0592: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (new string(binaryReader.ReadChars(4)) != "PWE2") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0 || !hashSet.Add(array[i])) { throw new InvalidDataException("Missing/duplicate reference bone: " + name); } } Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num3]; for (int num5 = 0; num5 < num3; num5++) { Matrix4x4 val = default(Matrix4x4); for (int num6 = 0; num6 < 4; num6++) { for (int num7 = 0; num7 < 4; num7++) { float num8 = binaryReader.ReadSingle(); if (float.IsNaN(num8) || float.IsInfinity(num8)) { throw new InvalidDataException("Invalid bind matrix."); } ((Matrix4x4)(ref val))[num6, num7] = num8; } } if (Math.Abs(((Matrix4x4)(ref val)).determinant) < 1E-05f) { throw new InvalidDataException("Singular bind matrix."); } array2[array[num5]] = val; } Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector3[] array4 = (Vector3[])(object)new Vector3[num]; Vector2[] array5 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array6 = (BoneWeight[])(object)new BoneWeight[num]; for (int num9 = 0; num9 < num; num9++) { array3[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array5[num9] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); int[] array7 = new int[4]; for (int num10 = 0; num10 < 4; num10++) { int num11 = binaryReader.ReadInt32(); if (num11 < 0 || num11 >= num3) { throw new InvalidDataException("Bone out of range."); } array7[num10] = array[num11]; } float[] array8 = new float[4]; for (int num12 = 0; num12 < 4; num12++) { array8[num12] = binaryReader.ReadSingle(); } if (array8.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array8.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } if (!Finite(array3[num9]) || !Finite(array4[num9])) { throw new InvalidDataException("Non-finite vertex."); } int num13 = num9; BoneWeight val2 = default(BoneWeight); ((BoneWeight)(ref val2)).boneIndex0 = array7[0]; ((BoneWeight)(ref val2)).boneIndex1 = array7[1]; ((BoneWeight)(ref val2)).boneIndex2 = array7[2]; ((BoneWeight)(ref val2)).boneIndex3 = array7[3]; ((BoneWeight)(ref val2)).weight0 = array8[0]; ((BoneWeight)(ref val2)).weight1 = array8[1]; ((BoneWeight)(ref val2)).weight2 = array8[2]; ((BoneWeight)(ref val2)).weight3 = array8[3]; array6[num13] = val2; } int[] array9 = new int[num2]; for (int num14 = 0; num14 < num2; num14++) { array9[num14] = binaryReader.ReadInt32(); if (array9[num14] < 0 || array9[num14] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } if (Object.op_Implicit((Object)(object)reference) && reference.bindposes.Length == num3) { Matrix4x4[] bindposes = reference.bindposes; int num15 = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Base"); if (num15 < 0) { num15 = 0; } Matrix4x4 b = ((Matrix4x4)(ref bindposes[num15])).inverse * array2[num15]; bool flag = true; for (int num16 = 0; num16 < num3; num16++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[num16])).inverse * array2[num16], b, 0.0002f)) { flag = false; } } if (!flag) { if (num3 != 2 && (num3 != 14 || !renderer.bones.Any((Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Screw"))) { throw new InvalidDataException("Unsupported nonuniform bind variant: " + ((Object)renderer).name); } Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int num17 = 0; num17 < num; num17++) { array3[num17] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(array3[num17]); int num18 = num17; Vector3 val3 = ((Matrix4x4)(ref transpose)).MultiplyVector(array4[num17]); array4[num18] = ((Vector3)(ref val3)).normalized; } array2 = bindposes; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E5_MINE_BIND_VARIANT renderer=" + ((Object)renderer).name + " reference=" + ((Object)reference).name)); } } Mesh val4 = new Mesh { name = "EclipsePlaytestEngineerTrafficControl", indexFormat = (IndexFormat)(num > 65535), vertices = array3, normals = array4, uv = array5, boneWeights = array6, bindposes = array2, triangles = array9 }; val4.RecalculateBounds(); val4.RecalculateTangents(); return val4; } private Material MakeMaterial(string asset, Material source) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (assetMaterials.TryGetValue(asset, out var value)) { return value; } if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader)) { throw new InvalidOperationException("Missing shader for " + asset); } value = new Material(source) { name = "matEclipsePlaytest_EngineerE5_" + asset }; value.SetTexture("_MainTex", (Texture)(object)ReadTexture(asset + "-albedo-spec.png", linear: false)); value.SetTexture("_NormalTex", (Texture)(object)ReadTexture(asset + "-normal.png", linear: true)); value.SetTexture("_EmTex", (Texture)(object)ReadTexture(asset + "-emission.png", linear: false)); value.SetColor("_Color", Color.white); value.SetFloat("_NormalStrength", 0.3f); value.SetFloat("_Smoothness", 0.28f); value.SetFloat("_SpecularStrength", 0.35f); value.SetFloat("_SpecularExponent", 8f); value.SetFloat("_EmPower", asset.EndsWith("mine", StringComparison.Ordinal) ? 0.4f : 0f); value.DisableKeyword("LIMBREMOVAL"); value.SetFloat("_LimbRemovalOn", 0f); assetMaterials.Add(asset, value); return value; } private static string MineAsset(Renderer r) { if (((Object)r).name == "EngiMineMesh") { return "pressure-mine"; } if (((Object)r).name == "EngiSpiderMineMesh") { return "spider-mine"; } return null; } private IEnumerator PrepareMineGhosts(SkinDef bodySkin) { cosmeticStorage = new GameObject("TrafficControlCosmeticPrefabs"); cosmeticStorage.SetActive(false); Object.DontDestroyOnLoad((Object)(object)cosmeticStorage); List<ProjectileGhostReplacement> replacements = new List<ProjectileGhostReplacement>(); string[] array = new string[2] { "EngiMine", "SpiderMine" }; foreach (string name in array) { AsyncOperationHandle<GameObject> h = Addressables.LoadAssetAsync<GameObject>((object)("RoR2/Base/Engi/" + name + ".prefab")); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline(name); yield return null; } if (!Object.op_Implicit((Object)(object)h.Result)) { throw new InvalidOperationException("Missing projectile " + name); } ProjectileController component = h.Result.GetComponent<ProjectileController>(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("Missing ProjectileController " + name); } GameObject val = component.ghostPrefab; if (!Object.op_Implicit((Object)(object)val) && component.ghostPrefabAddress != null && ((AssetReference)component.ghostPrefabAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<GameObject> gh = Addressables.LoadAssetAsync<GameObject>(((AssetReference)component.ghostPrefabAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(gh)); while (!gh.IsDone) { CheckLoadDeadline(name + " ghost"); yield return null; } val = gh.Result; } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing mine ghost " + name); } GameObject val2 = Object.Instantiate<GameObject>(val, cosmeticStorage.transform); ((Object)val2).name = "EclipseTrafficControl_" + name + "Ghost"; string asset = ((name == "EngiMine") ? "pressure-mine" : "spider-mine"); SkinnedMeshRenderer[] array2 = (from r in val2.GetComponentsInChildren<SkinnedMeshRenderer>(true) where MineAsset((Renderer)(object)r) == asset select r).ToArray(); if (array2.Length != 1) { throw new InvalidOperationException("Ambiguous mine renderer " + name + ": " + array2.Length); } SkinnedMeshRenderer val3 = array2[0]; int num = ((asset == "pressure-mine") ? 2 : 14); if (val3.bones.Length != num || !Object.op_Implicit((Object)(object)val3.sharedMesh)) { throw new InvalidOperationException("Missing native mine rig " + name); } Mesh sharedMesh = val3.sharedMesh; Mesh val4 = MeshFor(asset, val3); Material sharedMaterial = MakeMaterial(asset, ((Renderer)val3).sharedMaterial); canonicalBases[asset] = new MeshBasis { Reference = sharedMesh, Authored = val4 }; val3.sharedMesh = val4; ((Renderer)val3).sharedMaterial = sharedMaterial; Mesh val5 = new Mesh(); val3.BakeMesh(val5); Bounds localBounds = ((Renderer)val3).localBounds; Bounds bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).min); bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).max); ((Bounds)(ref localBounds)).Expand(((Bounds)(ref localBounds)).size * 0.5f); ((Renderer)val3).localBounds = localBounds; Object.Destroy((Object)(object)val5); val3.updateWhenOffscreen = true; val2.SetActive(true); replacements.Add(new ProjectileGhostReplacement { projectilePrefab = h.Result, projectileGhostReplacementPrefab = val2, ghostReplacementAddress = new AssetReferenceT<GameObject>("") }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E5_MINE_READY asset=" + asset + " vertices=" + val4.vertexCount + " native effects/controller preserved")); } bodySkin.skinDefParams.projectileGhostReplacements = replacements.ToArray(); } private Mesh MeshFor(string asset, SkinnedMeshRenderer target, Mesh nativeReference = null) { if (!Object.op_Implicit((Object)(object)nativeReference)) { nativeReference = target.sharedMesh; } string key = asset + "|" + (Object.op_Implicit((Object)(object)nativeReference) ? ((Object)nativeReference).GetInstanceID() : 0) + "|" + string.Join("|", target.bones.Select((Transform b) => (!Object.op_Implicit((Object)(object)b)) ? "<null>" : ((Object)b).name)); if (!remappedMeshes.TryGetValue(key, out var value)) { value = ReadMesh(Path.Combine(folder, asset + ".meshbin"), target, nativeReference); remappedMeshes.Add(key, value); } return value; } private static bool SameMatrix(Matrix4x4 a, Matrix4x4 b, float tolerance) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (Math.Abs(((Matrix4x4)(ref a))[i, j] - ((Matrix4x4)(ref b))[i, j]) > tolerance) { return false; } } } return true; } private Mesh StaticMeshFor(string asset, Mesh reference) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)reference)) { throw new InvalidOperationException("Missing static reference " + asset); } string key = asset + "|" + ((Object)reference).GetInstanceID(); if (staticMeshes.TryGetValue(key, out var value)) { return value; } if (!canonicalBases.TryGetValue(asset, out var value2)) { throw new InvalidOperationException("Missing canonical rig " + asset); } Matrix4x4[] bindposes = reference.bindposes; Matrix4x4[] bindposes2 = value2.Authored.bindposes; if (bindposes.Length != bindposes2.Length || bindposes.Length == 0) { throw new InvalidOperationException("Static bind count " + asset); } Matrix4x4 b = ((Matrix4x4)(ref bindposes[0])).inverse * bindposes2[0]; for (int i = 1; i < bindposes.Length; i++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[i])).inverse * bindposes2[i], b, 0.0002f)) { if (asset != "pressure-mine" && asset != "spider-mine") { throw new InvalidOperationException("Nonuniform static bind conversion " + asset + " bone " + i); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E5_STATIC_MINE_BIND_VARIANT " + asset + " uses canonical assembled rest shape")); break; } } value = Object.Instantiate<Mesh>(value2.Authored); ((Object)value).name = "EclipseEngineerE5Static_" + asset; Vector3[] vertices = value.vertices; Vector3[] normals = value.normals; Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int j = 0; j < vertices.Length; j++) { vertices[j] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(vertices[j]); int num = j; Vector3 val = ((Matrix4x4)(ref transpose)).MultiplyVector(normals[j]); normals[num] = ((Vector3)(ref val)).normalized; } value.vertices = vertices; value.normals = normals; value.boneWeights = (BoneWeight[])(object)new BoneWeight[0]; value.bindposes = (Matrix4x4[])(object)new Matrix4x4[0]; value.RecalculateBounds(); value.RecalculateTangents(); staticMeshes.Add(key, value); return value; } private static bool Finite(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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_0028: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(v.x + v.y + v.z)) { return !float.IsInfinity(v.x + v.y + v.z); } return false; } } internal static class StartupGuard { internal static IEnumerator Run(Func<IEnumerator> create, Func<bool> expired, Action<Exception> failed) { Stack<IEnumerator> stack = new Stack<IEnumerator>(); Exception failure = null; try { stack.Push(create()); } catch (Exception ex) { failure = ex; } try { while (failure == null && stack.Count > 0) { bool flag = false; object obj = null; try { if (expired()) { throw new TimeoutException("Traffic Control startup deadline exceeded."); } IEnumerator enumerator = stack.Peek(); flag = enumerator.MoveNext(); if (flag) { obj = enumerator.Current; } else { stack.Pop(); (enumerator as IDisposable)?.Dispose(); } } catch (Exception ex2) { failure = ex2; } if (failure != null) { break; } if (flag) { if (obj is IEnumerator item) { stack.Push(item); } else { yield return obj; } } } } finally { if (stack.Count > 0 && failure == null) { failure = new OperationCanceledException("Traffic Control startup iterator was cancelled."); } while (stack.Count > 0) { try { (stack.Pop() as IDisposable)?.Dispose(); } catch (Exception ex3) { if (failure == null) { failure = ex3; } } } if (failure != null) { try { failed(failure); } catch { } } } } } internal sealed class TextureAssetCache { private readonly Dictionary<string, Texture2D> values = new Dictionary<string, Texture2D>(); internal Texture2D Load(string path, bool linear) { //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_006f: 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_007e: Expected O, but got Unknown byte[] array = File.ReadAllBytes(path); string key; using (SHA256 sHA = SHA256.Create()) { key = (linear ? "linear:" : "srgb:") + Convert.ToBase64String(sHA.ComputeHash(array)); } if (values.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear) { name = Path.GetFileName(path), anisoLevel = 4, filterMode = (FilterMode)2 }; try { if (!ImageConversion.LoadImage(val, array, true)) { throw new InvalidDataException("Cannot decode " + Path.GetFileName(path)); } values[key] = val; return val; } catch { Object.Destroy((Object)(object)val); throw; } } }
BepInEx/plugins/RodaniusSkins/engineer-unqualified-personnel/EngineerUnqualifiedPersonnel.dll
Decompiled a week agousing 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.Security.Cryptography; using System.Text; using BepInEx; using EngineerUnionBuilderPlaytest; using EntityStates; using EntityStates.Engi.EngiWeapon; using HG.Reflection; using R2API; using R2API.Utils; using RoR2; using RoR2.Projectile; using RoR2.UI.MainMenu; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: AssemblyVersion("0.0.0.0")] namespace EngineerUnqualifiedPersonnelPlaytest; [BepInPlugin("rodanius.engineer.unqualifiedpersonnel", "Engineer - Unqualified Personnel (Playtest)", "0.3.1")] [BepInDependency("eclipseplaytest.engineer.e1", "0.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EngineerUnqualifiedPersonnel : BaseUnityPlugin { private sealed class Prepared { public SkinDef[] OriginalSkins; public SkinDef[] CommittedSkins; public string BodyName; public GameObject Model; public ModelSkinController Controller; public SkinDef Skin; public Mesh Mesh; public Mesh Reference; public Material Material; } private sealed class Design { public string Slug; public string Name; public Color32[] Colors; public Design(string slug, string name, Color32[] colors) { Slug = slug; Name = name; Colors = colors; } } private sealed class MeshBasis { public Mesh Reference; public Mesh Authored; } public sealed class PersonnelVisuals : MonoBehaviour { private sealed class Saved { public Renderer Renderer; public Mesh Mesh; public Material[] Materials; public Bounds Bounds; public bool Offscreen; public bool ChangeMesh; public bool ChangeMaterial; public Mesh AssignedMesh; public Material[] AssignedMaterials; public bool ChangeBounds; public Bounds AssignedBounds; public bool ChangeOffscreen; public bool AssignedOffscreen; } private readonly Dictionary<Renderer, Saved> changed = new Dictionary<Renderer, Saved>(); private ModelSkinController controller; private CharacterBody body; private EntityStateMachine[] machines; private bool lobbyDirty = true; private static readonly FieldInfo Blueprint = typeof(PlaceTurret).GetField("blueprints", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo Wrist = typeof(PlaceTurret).GetField("wristDisplayObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private void Applied(int index) { if (!OwnSkin() && changed.Count > 0) { Restore(); } lobbyDirty = true; } private void Start() { controller = ((Component)this).GetComponentInChildren<ModelSkinController>(true); body = ((Component)this).GetComponentInParent<CharacterBody>(); machines = (EntityStateMachine[])(Object.op_Implicit((Object)(object)body) ? ((Array)((Component)body).GetComponents<EntityStateMachine>()) : ((Array)new EntityStateMachine[0])); if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied += Applied; } } private bool OwnSkin() { if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { return false; } int currentSkinIndex = controller.currentSkinIndex; if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length && Object.op_Implicit((Object)(object)controller.skins[currentSkinIndex])) { return SkinIdentity.Owns(((Object)controller.skins[currentSkinIndex]).name); } return false; } private Saved Save(Renderer r) { //IL_0074: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (changed.TryGetValue(r, out var value)) { return value; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((r is SkinnedMeshRenderer) ? r : null); MeshFilter component = ((Component)r).GetComponent<MeshFilter>(); value = new Saved { Renderer = r, Materials = r.sharedMaterials, Mesh = (Object.op_Implicit((Object)(object)val) ? val.sharedMesh : (Object.op_Implicit((Object)(object)component) ? component.sharedMesh : null)), Bounds = (Bounds)(Object.op_Implicit((Object)(object)val) ? ((Renderer)val).localBounds : default(Bounds)), Offscreen = (Object.op_Implicit((Object)(object)val) && val.updateWhenOffscreen) }; changed.Add(r, value); return value; } private void ApplySkinned(SkinnedMeshRenderer r, string asset, bool keepMaterial) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) Saved saved = Save((Renderer)(object)r); saved.ChangeMesh = true; saved.ChangeMaterial = !keepMaterial; Mesh val = (saved.AssignedMesh = instance.MeshFor(asset, r, saved.Mesh)); if ((Object)(object)r.sharedMesh != (Object)(object)val) { r.sharedMesh = val; Mesh val2 = new Mesh(); r.BakeMesh(val2); Bounds bounds = saved.Bounds; Bounds bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).min); bounds2 = val2.bounds; ((Bounds)(ref bounds)).Encapsulate(((Bounds)(ref bounds2)).max); ((Bounds)(ref bounds)).Expand(((Bounds)(ref bounds)).size * 0.5f); ((Renderer)r).localBounds = bounds; saved.ChangeBounds = true; saved.AssignedBounds = bounds; Object.Destroy((Object)(object)val2); } r.updateWhenOffscreen = true; saved.ChangeOffscreen = true; saved.AssignedOffscreen = true; if (!keepMaterial) { ((Renderer)r).sharedMaterial = instance.assetMaterials[asset]; saved.AssignedMaterials = ((Renderer)r).sharedMaterials; } } private void Restore() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) foreach (Saved value in changed.Values) { if (!Object.op_Implicit((Object)(object)value.Renderer)) { continue; } Renderer renderer = value.Renderer; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); MeshFilter component = ((Component)value.Renderer).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)val)) { if (value.ChangeMesh && (Object)(object)val.sharedMesh == (Object)(object)value.AssignedMesh) { if (value.ChangeBounds && ((Renderer)val).localBounds == value.AssignedBounds) { ((Renderer)val).localBounds = value.Bounds; } if (value.ChangeOffscreen && val.updateWhenOffscreen == value.AssignedOffscreen) { val.updateWhenOffscreen = value.Offscreen; } val.sharedMesh = value.Mesh; } } else if (Object.op_Implicit((Object)(object)component) && value.ChangeMesh && (Object)(object)component.sharedMesh == (Object)(object)value.AssignedMesh) { component.sharedMesh = value.Mesh; } if (value.ChangeMaterial && value.AssignedMaterials != null && value.Renderer.sharedMaterials.SequenceEqual(value.AssignedMaterials)) { value.Renderer.sharedMaterials = value.Materials; } } changed.Clear(); } private void LateUpdate() { if (!Object.op_Implicit((Object)(object)instance) || !instance.registered) { return; } Renderer[] array = changed.Keys.Where((Renderer r) => !Object.op_Implicit((Object)(object)r)).ToArray(); foreach (Renderer key in array) { changed.Remove(key); } if (!OwnSkin()) { if (changed.Count > 0) { Restore(); } lobbyDirty = true; return; } if (lobbyDirty) { SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { string text = MineAsset((Renderer)(object)val); if (text != null) { ApplySkinned(val, text, keepMaterial: false); } else if (!Object.op_Implicit((Object)(object)body) && val.bones.Length == 15 && Object.op_Implicit((Object)(object)((Component)this).transform.Find("TurretHolder")) && ((Component)val).transform.IsChildOf(((Component)this).transform.Find("TurretHolder"))) { ApplySkinned(val, "turret", keepMaterial: false); } } MeshRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren2) { string text2 = MineAsset((Renderer)(object)val2); if (text2 != null) { MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)component)) { Saved saved = Save((Renderer)(object)val2); saved.ChangeMesh = true; component.sharedMesh = instance.StaticMeshFor(text2, saved.Mesh); saved.AssignedMesh = component.sharedMesh; saved.ChangeMaterial = true; ((Renderer)val2).sharedMaterial = instance.assetMaterials[text2]; saved.AssignedMaterials = ((Renderer)val2).sharedMaterials; } } } lobbyDirty = false; } if (!Object.op_Implicit((Object)(object)body)) { return; } EntityStateMachine[] array2 = machines; for (int num = 0; num < array2.Length; num++) { EntityState state = array2[num].state; PlaceTurret val3 = (PlaceTurret)(object)((state is PlaceTurret) ? state : null); if (val3 == null) { continue; } string asset = ((val3 is PlaceWalkerTurret) ? "walker" : "turret"); object? obj = Blueprint?.GetValue(val3); BlueprintController val4 = (BlueprintController)((obj is BlueprintController) ? obj : null); if (Object.op_Implicit((Object)(object)val4)) { SkinnedMeshRenderer[] componentsInChildren = ((Component)val4).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val5 in componentsInChildren) { if (val5.bones.Length == 15) { ApplySkinned(val5, asset, keepMaterial: true); } } } object? obj2 = Wrist?.GetValue(val3); GameObject val6 = (GameObject)((obj2 is GameObject) ? obj2 : null); if (!Object.op_Implicit((Object)(object)val6)) { continue; } MeshFilter[] componentsInChildren3 = val6.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val7 in componentsInChildren3) { if (((Object)val7).name == "EngiTurretMesh") { Renderer component2 = ((Component)val7).GetComponent<Renderer>(); Saved saved2 = Save(component2); saved2.ChangeMesh = true; val7.sharedMesh = instance.StaticMeshFor(asset, saved2.Mesh); saved2.AssignedMesh = val7.sharedMesh; } } } } private void OnDisable() { Restore(); lobbyDirty = true; } private void OnDestroy() { if (Object.op_Implicit((Object)(object)controller)) { controller.onSkinApplied -= Applied; } } } public const string Guid = "rodanius.engineer.unqualifiedpersonnel"; public const string Version = "0.3.1"; private static EngineerUnqualifiedPersonnel instance; private readonly List<AsyncOperationHandle> retainedAssets = new List<AsyncOperationHandle>(); private float registrationDeadline; private string folder; private SkinDef skin; private GameObject modelPrefab; private string startupStage = "awake"; private readonly List<PersonnelVisuals> startupVisuals = new List<PersonnelVisuals>(); private readonly List<Prepared> prepared = new List<Prepared>(); private bool registered; private static readonly Design[] Designs = new Design[1] { new Design("unqualified-personnel", "Unqualified Personnel (Playtest)", (Color32[])(object)new Color32[4] { new Color32((byte)45, (byte)125, (byte)132, byte.MaxValue), new Color32((byte)231, (byte)226, (byte)207, byte.MaxValue), new Color32((byte)68, (byte)116, (byte)154, byte.MaxValue), new Color32((byte)172, (byte)61, (byte)52, byte.MaxValue) }) }; private readonly TextureAssetCache textureCache = new TextureAssetCache(); private GameObject cosmeticStorage; private readonly Dictionary<string, MeshBasis> canonicalBases = new Dictionary<string, MeshBasis>(); private readonly Dictionary<string, Material> assetMaterials = new Dictionary<string, Material>(); private readonly Dictionary<string, Mesh> remappedMeshes = new Dictionary<string, Mesh>(); private readonly Dictionary<string, Mesh> staticMeshes = new Dictionary<string, Mesh>(); private void Awake() { folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); instance = this; SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(EngineerUnqualifiedPersonnel)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplaySkins)); MainMenuController.OnMainMenuInitialised += SyncDisplaySkins; } [SystemInitializer(new Type[] { typeof(BodyCatalog), typeof(ProjectileCatalog), typeof(SurvivorCatalog), typeof(EngineerUnionBuilder) })] private static IEnumerator InitializeSkin() { if (!Object.op_Implicit((Object)(object)instance)) { return EmptyStartup(); } instance.registrationDeadline = Time.realtimeSinceStartup + 60f; return StartupGuard.Run(instance.RegisterAsync, () => Time.realtimeSinceStartup > instance.registrationDeadline, delegate(Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E2_STARTUP_DISABLED version=0.3.1 stage=" + instance.startupStage + " " + ex)); try { instance.RollbackRegistration(); ((BaseUnityPlugin)instance).Logger.LogWarning((object)"ENGINEER_E2_ROLLBACK_OK existing skin arrays retained."); } catch (Exception ex2) { ((BaseUnityPlugin)instance).Logger.LogError((object)("ENGINEER_E2_ROLLBACK_FAILED " + ex2)); } }); } private static IEnumerator EmptyStartup() { yield break; } private void Stage(string value) { startupStage = value; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E2_STARTUP_STAGE version=0.3.1 stage=" + value)); } private void RollbackRegistration() { registered = false; foreach (Prepared item in prepared) { if (Object.op_Implicit((Object)(object)item.Controller) && item.CommittedSkins != null && item.Controller.skins == item.CommittedSkins) { item.Controller.skins = item.OriginalSkins; } } foreach (PersonnelVisuals startupVisual in startupVisuals) { if (Object.op_Implicit((Object)(object)startupVisual)) { Object.Destroy((Object)(object)startupVisual); } } startupVisuals.Clear(); if (Object.op_Implicit((Object)(object)cosmeticStorage)) { Object.Destroy((Object)(object)cosmeticStorage); cosmeticStorage = null; } } private void ValidateAndCommit() { foreach (Prepared p in prepared) { if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Private bake produced no runtime skin: " + p.BodyName); } if (p.Controller.skins != p.OriginalSkins) { throw new InvalidOperationException("Skin list changed during startup: " + p.BodyName); } if (p.OriginalSkins.Any((SkinDef s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == ((Object)p.Skin).name)) { throw new InvalidOperationException("Duplicate Unqualified Personnel skin: " + ((Object)p.Skin).name); } p.CommittedSkins = p.OriginalSkins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { p.Skin }).ToArray(); } foreach (Prepared item in prepared) { item.Controller.skins = item.CommittedSkins; } } private IEnumerator RegisterAsync() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E2_REGISTRATION_BEGIN 0.3.1"); string[][] array = new string[3][] { new string[4] { "EngiTurretBody", "turret", "15", "skinEngiTurretDefault" }, new string[4] { "EngiWalkerTurretBody", "walker", "15", "skinEngiWalkerTurretDefault" }, new string[4] { "EngiBody", "unqualified-personnel", "83", "skinEngiDefault" } }; foreach (string[] array2 in array) { Stage("prepare:" + array2[0]); yield return Prepare(array2[0], array2[1], int.Parse(array2[2]), array2[3]); } Prepared bodySkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiBody"); bodySkin.Skin.skinDefParams.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[2] { new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiTurretBody").Skin }, new MinionSkinReplacement { minionBodyPrefab = BodyCatalog.FindBodyPrefab("EngiWalkerTurretBody"), minionSkin = prepared.Single((Prepared prepared) => prepared.BodyName == "EngiWalkerTurretBody").Skin } }; Stage("prepare:mine-ghosts"); yield return PrepareMineGhosts(bodySkin.Skin); foreach (Prepared p in prepared) { Stage("private-bake:" + p.BodyName); ValidateSkin(p); yield return p.Skin.BakeAsync(); if (p.Skin.runtimeSkin == null) { throw new InvalidOperationException("Bake returned without runtime skin: " + p.BodyName); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E2_PRIVATE_BAKE_OK body=" + p.BodyName)); } Stage("commit"); ValidateAndCommit(); modelPrefab = bodySkin.Model; skin = bodySkin.Skin; foreach (Prepared item in prepared) { if (!Object.op_Implicit((Object)(object)item.Model.GetComponent<PersonnelVisuals>())) { startupVisuals.Add(item.Model.AddComponent<PersonnelVisuals>()); } } registered = true; Stage("registered"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ENGINEER_E2_REGISTERED Unqualified Personnel body, both turrets, pressure and spider mines; native Animator retained; unlocked=true version=0.3.1"); } private IEnumerator Prepare(string bodyName, string assetName, int boneCount, string defaultName) { GameObject val = BodyCatalog.FindBodyPrefab(bodyName); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing body " + bodyName); } GameObject model = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject; ModelSkinController controller = model.GetComponent<ModelSkinController>(); SkinDef baseSkin = null; if (Object.op_Implicit((Object)(object)controller) && controller.skins != null && controller.skins.Length != 0) { baseSkin = controller.skins[0]; } if (!Object.op_Implicit((Object)(object)baseSkin)) { AsyncOperationHandle<SkinDef> h = Addressables.LoadAssetAsync<SkinDef>((object)("RoR2/Base/Engi/" + defaultName + ".asset")); retainedAssets.Add(AsyncOperationHandle<SkinDef>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline("default skin " + bodyName); yield return null; } baseSkin = h.Result; } if (!Object.op_Implicit((Object)(object)baseSkin)) { throw new InvalidOperationException("Missing default skin " + bodyName); } SkinDefParams bp = baseSkin.skinDefParams; if (!Object.op_Implicit((Object)(object)bp) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<SkinDefParams> h2 = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(h2)); while (!h2.IsDone) { CheckLoadDeadline("parameters " + bodyName); yield return null; } bp = h2.Result; } if (!Object.op_Implicit((Object)(object)bp)) { throw new InvalidOperationException("Missing parameters " + bodyName); } SkinnedMeshRenderer target = model.GetComponentsInChildren<SkinnedMeshRenderer>(true).Single((SkinnedMeshRenderer r) => r.bones.Length == boneCount); Mesh reference = target.sharedMesh; if (!Object.op_Implicit((Object)(object)reference)) { MeshReplacement val2 = bp.meshReplacements.First((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)target); reference = val2.mesh; if (!Object.op_Implicit((Object)(object)reference)) { AsyncOperationHandle<Mesh> h3 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Mesh>.op_Implicit(h3)); while (!h3.IsDone) { CheckLoadDeadline("mesh " + bodyName); yield return null; } reference = h3.Result; } } if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != target.bones.Length) { throw new InvalidOperationException("Bind pose mismatch " + bodyName); } RendererInfo ri = bp.rendererInfos.First((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)target); Material val3 = ri.defaultMaterial; if (!Object.op_Implicit((Object)(object)val3) && ri.defaultMaterialAddress != null && ((AssetReference)ri.defaultMaterialAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<Material> h4 = Addressables.LoadAssetAsync<Material>(((AssetReference)ri.defaultMaterialAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<Material>.op_Implicit(h4)); while (!h4.IsDone) { CheckLoadDeadline("material " + bodyName); yield return null; } val3 = h4.Result; } if (!Object.op_Implicit((Object)(object)val3)) { val3 = ((Renderer)target).sharedMaterial; } if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader)) { throw new InvalidOperationException("Missing native material " + bodyName); } Mesh val4 = ReadMesh(Path.Combine(folder, assetName + ".meshbin"), target, reference); ((Object)val4).name = "EclipsePlaytest_EngineerE2_" + assetName; Material val5 = MakeMaterial(assetName, val3); canonicalBases[assetName] = new MeshBasis { Reference = reference, Authored = val4 }; ri.defaultMaterial = val5; ri.defaultMaterialAddress = new AssetReferenceT<Material>(""); SkinDefParams val6 = ScriptableObject.CreateInstance<SkinDefParams>(); val6.rendererInfos = (RendererInfo[])(object)new RendererInfo[1] { ri }; val6.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[1] { new MeshReplacement { renderer = (Renderer)(object)target, mesh = val4, meshAddress = new AssetReferenceT<Mesh>("") } }; SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>(); ((Object)val7).name = "skinRodaniusEngineerUnqualifiedPersonnel_" + assetName; val7.nameToken = "RODANIUS_ENGINEER_UNQUALIFIED_PERSONNEL_" + assetName.ToUpperInvariant().Replace('-', '_'); LanguageAPI.Add(val7.nameToken, (bodyName == "EngiBody") ? "Unqualified Personnel (Playtest)" : ("Unqualified Personnel " + assetName)); val7.icon = CreateIcon(Designs[0].Colors); val7.unlockableDef = null; val7.rootObject = model; val7.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin }; val7.skinDefParams = val6; if (!Object.op_Implicit((Object)(object)controller) || controller.skins == null) { throw new InvalidOperationException("Missing native skin controller/list: " + bodyName); } prepared.Add(new Prepared { BodyName = bodyName, Model = model, Controller = controller, Skin = val7, Mesh = val4, Reference = reference, Material = val5, OriginalSkins = controller.skins }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E2_PREPARED body=" + bodyName + " vertices=" + val4.vertexCount + " unlocked=true")); } private static void ValidateSkin(Prepared p) { //IL_00ee: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) SkinDef skin = p.Skin; SkinDefParams skinDefParams = skin.skinDefParams; if (!Object.op_Implicit((Object)(object)skin.rootObject) || !Object.op_Implicit((Object)(object)skinDefParams) || skin.baseSkins == null || skin.baseSkins.Any((SkinDef s) => !Object.op_Implicit((Object)(object)s) || s == skin)) { throw new InvalidOperationException("Invalid skin graph: " + p.BodyName); } if (skin.skinDefParamsAddress == null) { skin.skinDefParamsAddress = new AssetReferenceT<SkinDefParams>(""); } if (skinDefParams.rendererInfos == null || skinDefParams.meshReplacements == null || skinDefParams.gameObjectActivations == null || skinDefParams.lightReplacements == null || skinDefParams.projectileGhostReplacements == null || skinDefParams.minionSkinReplacements == null) { throw new InvalidOperationException("Null parameter collection: " + p.BodyName); } RendererInfo[] rendererInfos = skinDefParams.rendererInfos; foreach (RendererInfo val in rendererInfos) { if (!Object.op_Implicit((Object)(object)val.renderer) || !Object.op_Implicit((Object)(object)val.defaultMaterial) || !((Component)val.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid material/renderer root: " + p.BodyName); } } MeshReplacement[] meshReplacements = skinDefParams.meshReplacements; foreach (MeshReplacement val2 in meshReplacements) { if (!Object.op_Implicit((Object)(object)val2.renderer) || !Object.op_Implicit((Object)(object)val2.mesh) || !((Component)val2.renderer).transform.IsChildOf(skin.rootObject.transform)) { throw new InvalidOperationException("Invalid mesh/renderer root: " + p.BodyName); } } ProjectileGhostReplacement[] projectileGhostReplacements = skinDefParams.projectileGhostReplacements; foreach (ProjectileGhostReplacement val3 in projectileGhostReplacements) { if (!Object.op_Implicit((Object)(object)val3.projectilePrefab) || !Object.op_Implicit((Object)(object)val3.projectileGhostReplacementPrefab) || ProjectileCatalog.GetProjectileIndex(val3.projectilePrefab) < 0) { throw new InvalidOperationException("Unregistered mine projectile: " + p.BodyName); } } MinionSkinReplacement[] minionSkinReplacements = skinDefParams.minionSkinReplacements; foreach (MinionSkinReplacement val4 in minionSkinReplacements) { if (!Object.op_Implicit((Object)(object)val4.minionBodyPrefab) || !Object.op_Implicit((Object)(object)val4.minionSkin) || val4.minionSkin.runtimeSkin == null) { throw new InvalidOperationException("Unbaked turret skin: " + p.BodyName); } } } private static Sprite CreateIcon(Color32[] colors) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00c6: 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_0083: 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_0071: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = ((i > j) ? ((i <= 63 - j) ? 1 : 0) : ((i > 63 - j) ? 2 : 3)); array[i * 64 + j] = (Color32)((j < 2 || j > 61 || i < 2 || i > 61 || Math.Abs(i - j) < 2 || Math.Abs(i - (63 - j)) < 2) ? new Color32((byte)48, (byte)48, (byte)48, byte.MaxValue) : colors[num]); } } val.SetPixels32(array); val.Apply(false, true); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } private void CheckLoadDeadline(string asset) { if (Time.realtimeSinceStartup > registrationDeadline) { throw new TimeoutException("Stopped loading " + asset + "; continuing startup without the skin."); } } private void SyncDisplaySkins() { if (!registered) { return; } try { SyncDisplaySkinsChecked(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("ENGINEER_E2_DISPLAY_SYNC_FAILED version=0.3.1 " + ex)); } } private void SyncDisplaySkinsChecked() { SurvivorDef val = SurvivorCatalog.allSurvivorDefs.FirstOrDefault((Func<SurvivorDef, bool>)((SurvivorDef s) => Object.op_Implicit((Object)(object)s) && Object.op_Implicit((Object)(object)s.bodyPrefab) && ((Object)s.bodyPrefab).name == "EngiBody")); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab)) { return; } CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { ModelSkinController val2 = ((Component)componentInChildren).GetComponent<ModelSkinController>() ?? ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>(); val2.skins = (SkinDef[])modelPrefab.GetComponent<ModelSkinController>().skins.Clone(); if (!Object.op_Implicit((Object)(object)val.displayPrefab.GetComponent<PersonnelVisuals>())) { val.displayPrefab.AddComponent<PersonnelVisuals>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E2_DISPLAY_READY version=0.3.1 skins=" + val2.skins.Length + " catalogSkins=" + SkinCatalog.skinCount)); } } private Texture2D ReadTexture(string name, bool linear) { return textureCache.Load(Path.Combine(folder, name), linear); } private Mesh ReadMesh(string path, SkinnedMeshRenderer renderer, Mesh reference) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_0592: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Expected O, but got Unknown //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); if (new string(binaryReader.ReadChars(4)) != "PWE2") { throw new InvalidDataException("Invalid mesh signature."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num < 3 || num > 200000 || num2 < 3 || num2 > 1200000 || num2 % 3 != 0 || num3 != renderer.bones.Length) { throw new InvalidDataException("Invalid mesh dimensions."); } int[] array = new int[num3]; HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < num3; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 128) { throw new InvalidDataException("Invalid bone name."); } string name = Encoding.UTF8.GetString(binaryReader.ReadBytes(num4)); array[i] = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == name); if (array[i] < 0 || !hashSet.Add(array[i])) { throw new InvalidDataException("Missing/duplicate reference bone: " + name); } } Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num3]; for (int num5 = 0; num5 < num3; num5++) { Matrix4x4 val = default(Matrix4x4); for (int num6 = 0; num6 < 4; num6++) { for (int num7 = 0; num7 < 4; num7++) { float num8 = binaryReader.ReadSingle(); if (float.IsNaN(num8) || float.IsInfinity(num8)) { throw new InvalidDataException("Invalid bind matrix."); } ((Matrix4x4)(ref val))[num6, num7] = num8; } } if (Math.Abs(((Matrix4x4)(ref val)).determinant) < 1E-05f) { throw new InvalidDataException("Singular bind matrix."); } array2[array[num5]] = val; } Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector3[] array4 = (Vector3[])(object)new Vector3[num]; Vector2[] array5 = (Vector2[])(object)new Vector2[num]; BoneWeight[] array6 = (BoneWeight[])(object)new BoneWeight[num]; for (int num9 = 0; num9 < num; num9++) { array3[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num9] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); array5[num9] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); int[] array7 = new int[4]; for (int num10 = 0; num10 < 4; num10++) { int num11 = binaryReader.ReadInt32(); if (num11 < 0 || num11 >= num3) { throw new InvalidDataException("Bone out of range."); } array7[num10] = array[num11]; } float[] array8 = new float[4]; for (int num12 = 0; num12 < 4; num12++) { array8[num12] = binaryReader.ReadSingle(); } if (array8.Any((float n) => float.IsNaN(n) || float.IsInfinity(n) || n < 0f) || Math.Abs(array8.Sum() - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weight."); } if (!Finite(array3[num9]) || !Finite(array4[num9])) { throw new InvalidDataException("Non-finite vertex."); } int num13 = num9; BoneWeight val2 = default(BoneWeight); ((BoneWeight)(ref val2)).boneIndex0 = array7[0]; ((BoneWeight)(ref val2)).boneIndex1 = array7[1]; ((BoneWeight)(ref val2)).boneIndex2 = array7[2]; ((BoneWeight)(ref val2)).boneIndex3 = array7[3]; ((BoneWeight)(ref val2)).weight0 = array8[0]; ((BoneWeight)(ref val2)).weight1 = array8[1]; ((BoneWeight)(ref val2)).weight2 = array8[2]; ((BoneWeight)(ref val2)).weight3 = array8[3]; array6[num13] = val2; } int[] array9 = new int[num2]; for (int num14 = 0; num14 < num2; num14++) { array9[num14] = binaryReader.ReadInt32(); if (array9[num14] < 0 || array9[num14] >= num) { throw new InvalidDataException("Triangle out of range."); } } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Unexpected trailing mesh data."); } if (Object.op_Implicit((Object)(object)reference) && reference.bindposes.Length == num3) { Matrix4x4[] bindposes = reference.bindposes; int num15 = Array.FindIndex(renderer.bones, (Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Base"); if (num15 < 0) { num15 = 0; } Matrix4x4 b = ((Matrix4x4)(ref bindposes[num15])).inverse * array2[num15]; bool flag = true; for (int num16 = 0; num16 < num3; num16++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[num16])).inverse * array2[num16], b, 0.0002f)) { flag = false; } } if (!flag) { if (num3 != 2 && (num3 != 14 || !renderer.bones.Any((Transform t) => Object.op_Implicit((Object)(object)t) && ((Object)t).name == "Screw"))) { throw new InvalidDataException("Unsupported nonuniform bind variant: " + ((Object)renderer).name); } Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int num17 = 0; num17 < num; num17++) { array3[num17] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(array3[num17]); int num18 = num17; Vector3 val3 = ((Matrix4x4)(ref transpose)).MultiplyVector(array4[num17]); array4[num18] = ((Vector3)(ref val3)).normalized; } array2 = bindposes; ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E2_MINE_BIND_VARIANT renderer=" + ((Object)renderer).name + " reference=" + ((Object)reference).name)); } } Mesh val4 = new Mesh { name = "EclipsePlaytestEngineerUnqualifiedPersonnel", indexFormat = (IndexFormat)(num > 65535), vertices = array3, normals = array4, uv = array5, boneWeights = array6, bindposes = array2, triangles = array9 }; val4.RecalculateBounds(); val4.RecalculateTangents(); return val4; } private Material MakeMaterial(string asset, Material source) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (assetMaterials.TryGetValue(asset, out var value)) { return value; } if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)source.shader)) { throw new InvalidOperationException("Missing shader for " + asset); } value = new Material(source) { name = "matEclipsePlaytest_EngineerE2_" + asset }; value.SetTexture("_MainTex", (Texture)(object)ReadTexture(asset + "-albedo-spec.png", linear: false)); value.SetTexture("_NormalTex", (Texture)(object)ReadTexture(asset + "-normal.png", linear: true)); value.SetTexture("_EmTex", (Texture)(object)ReadTexture(asset + "-emission.png", linear: false)); value.SetColor("_Color", Color.white); value.SetFloat("_NormalStrength", 0.3f); value.SetFloat("_Smoothness", 0.28f); value.SetFloat("_SpecularStrength", 0.35f); value.SetFloat("_SpecularExponent", 8f); value.SetFloat("_EmPower", asset.EndsWith("mine", StringComparison.Ordinal) ? 0.4f : 0f); value.DisableKeyword("LIMBREMOVAL"); value.SetFloat("_LimbRemovalOn", 0f); assetMaterials.Add(asset, value); return value; } private static string MineAsset(Renderer r) { if (((Object)r).name == "EngiMineMesh") { return "pressure-mine"; } if (((Object)r).name == "EngiSpiderMineMesh") { return "spider-mine"; } return null; } private IEnumerator PrepareMineGhosts(SkinDef bodySkin) { cosmeticStorage = new GameObject("UnqualifiedPersonnelCosmeticPrefabs"); cosmeticStorage.SetActive(false); Object.DontDestroyOnLoad((Object)(object)cosmeticStorage); List<ProjectileGhostReplacement> replacements = new List<ProjectileGhostReplacement>(); string[] array = new string[2] { "EngiMine", "SpiderMine" }; foreach (string name in array) { AsyncOperationHandle<GameObject> h = Addressables.LoadAssetAsync<GameObject>((object)("RoR2/Base/Engi/" + name + ".prefab")); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(h)); while (!h.IsDone) { CheckLoadDeadline(name); yield return null; } if (!Object.op_Implicit((Object)(object)h.Result)) { throw new InvalidOperationException("Missing projectile " + name); } ProjectileController component = h.Result.GetComponent<ProjectileController>(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("Missing ProjectileController " + name); } GameObject val = component.ghostPrefab; if (!Object.op_Implicit((Object)(object)val) && component.ghostPrefabAddress != null && ((AssetReference)component.ghostPrefabAddress).RuntimeKeyIsValid()) { AsyncOperationHandle<GameObject> gh = Addressables.LoadAssetAsync<GameObject>(((AssetReference)component.ghostPrefabAddress).RuntimeKey); retainedAssets.Add(AsyncOperationHandle<GameObject>.op_Implicit(gh)); while (!gh.IsDone) { CheckLoadDeadline(name + " ghost"); yield return null; } val = gh.Result; } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Missing mine ghost " + name); } GameObject val2 = Object.Instantiate<GameObject>(val, cosmeticStorage.transform); ((Object)val2).name = "EclipseUnqualifiedPersonnel_" + name + "Ghost"; string asset = ((name == "EngiMine") ? "pressure-mine" : "spider-mine"); SkinnedMeshRenderer[] array2 = (from r in val2.GetComponentsInChildren<SkinnedMeshRenderer>(true) where MineAsset((Renderer)(object)r) == asset select r).ToArray(); if (array2.Length != 1) { throw new InvalidOperationException("Ambiguous mine renderer " + name + ": " + array2.Length); } SkinnedMeshRenderer val3 = array2[0]; int num = ((asset == "pressure-mine") ? 2 : 14); if (val3.bones.Length != num || !Object.op_Implicit((Object)(object)val3.sharedMesh)) { throw new InvalidOperationException("Missing native mine rig " + name); } Mesh sharedMesh = val3.sharedMesh; Mesh val4 = MeshFor(asset, val3); Material sharedMaterial = MakeMaterial(asset, ((Renderer)val3).sharedMaterial); canonicalBases[asset] = new MeshBasis { Reference = sharedMesh, Authored = val4 }; val3.sharedMesh = val4; ((Renderer)val3).sharedMaterial = sharedMaterial; Mesh val5 = new Mesh(); val3.BakeMesh(val5); Bounds localBounds = ((Renderer)val3).localBounds; Bounds bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).min); bounds = val5.bounds; ((Bounds)(ref localBounds)).Encapsulate(((Bounds)(ref bounds)).max); ((Bounds)(ref localBounds)).Expand(((Bounds)(ref localBounds)).size * 0.5f); ((Renderer)val3).localBounds = localBounds; Object.Destroy((Object)(object)val5); val3.updateWhenOffscreen = true; val2.SetActive(true); replacements.Add(new ProjectileGhostReplacement { projectilePrefab = h.Result, projectileGhostReplacementPrefab = val2, ghostReplacementAddress = new AssetReferenceT<GameObject>("") }); ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E2_MINE_READY asset=" + asset + " vertices=" + val4.vertexCount + " native effects/controller preserved")); } bodySkin.skinDefParams.projectileGhostReplacements = replacements.ToArray(); } private Mesh MeshFor(string asset, SkinnedMeshRenderer target, Mesh nativeReference = null) { if (!Object.op_Implicit((Object)(object)nativeReference)) { nativeReference = target.sharedMesh; } string key = asset + "|" + (Object.op_Implicit((Object)(object)nativeReference) ? ((Object)nativeReference).GetInstanceID() : 0) + "|" + string.Join("|", target.bones.Select((Transform b) => (!Object.op_Implicit((Object)(object)b)) ? "<null>" : ((Object)b).name)); if (!remappedMeshes.TryGetValue(key, out var value)) { value = ReadMesh(Path.Combine(folder, asset + ".meshbin"), target, nativeReference); remappedMeshes.Add(key, value); } return value; } private static bool SameMatrix(Matrix4x4 a, Matrix4x4 b, float tolerance) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (Math.Abs(((Matrix4x4)(ref a))[i, j] - ((Matrix4x4)(ref b))[i, j]) > tolerance) { return false; } } } return true; } private Mesh StaticMeshFor(string asset, Mesh reference) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)reference)) { throw new InvalidOperationException("Missing static reference " + asset); } string key = asset + "|" + ((Object)reference).GetInstanceID(); if (staticMeshes.TryGetValue(key, out var value)) { return value; } if (!canonicalBases.TryGetValue(asset, out var value2)) { throw new InvalidOperationException("Missing canonical rig " + asset); } Matrix4x4[] bindposes = reference.bindposes; Matrix4x4[] bindposes2 = value2.Authored.bindposes; if (bindposes.Length != bindposes2.Length || bindposes.Length == 0) { throw new InvalidOperationException("Static bind count " + asset); } Matrix4x4 b = ((Matrix4x4)(ref bindposes[0])).inverse * bindposes2[0]; for (int i = 1; i < bindposes.Length; i++) { if (!SameMatrix(((Matrix4x4)(ref bindposes[i])).inverse * bindposes2[i], b, 0.0002f)) { if (asset != "pressure-mine" && asset != "spider-mine") { throw new InvalidOperationException("Nonuniform static bind conversion " + asset + " bone " + i); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("ENGINEER_E2_STATIC_MINE_BIND_VARIANT " + asset + " uses canonical assembled rest shape")); break; } } value = Object.Instantiate<Mesh>(value2.Authored); ((Object)value).name = "EclipseEngineerE2Static_" + asset; Vector3[] vertices = value.vertices; Vector3[] normals = value.normals; Matrix4x4 inverse = ((Matrix4x4)(ref b)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int j = 0; j < vertices.Length; j++) { vertices[j] = ((Matrix4x4)(ref b)).MultiplyPoint3x4(vertices[j]); int num = j; Vector3 val = ((Matrix4x4)(ref transpose)).MultiplyVector(normals[j]); normals[num] = ((Vector3)(ref val)).normalized; } value.vertices = vertices; value.normals = normals; value.boneWeights = (BoneWeight[])(object)new BoneWeight[0]; value.bindposes = (Matrix4x4[])(object)new Matrix4x4[0]; value.RecalculateBounds(); value.RecalculateTangents(); staticMeshes.Add(key, value); return value; } private static bool Finite(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //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_0028: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(v.x + v.y + v.z)) { return !float.IsInfinity(v.x + v.y + v.z); } return false; } } internal static class SkinIdentity { internal static bool Owns(string name) { if (!(name == "skinRodaniusEngineerUnqualifiedPersonnel_unqualified-personnel") && !(name == "skinRodaniusEngineerUnqualifiedPersonnel_turret")) { return name == "skinRodaniusEngineerUnqualifiedPersonnel_walker"; } return true; } } internal static class StartupGuard { internal static IEnumerator Run(Func<IEnumerator> create, Func<bool> expired, Action<Exception> failed) { Stack<IEnumerator> stack = new Stack<IEnumerator>(); Exception failure = null; try { stack.Push(create()); } catch (Exception ex) { failure = ex; } try { while (failure == null && stack.Count > 0) { bool flag = false; object obj = null; try { if (expired()) { throw new TimeoutException("Unqualified Personnel startup deadline exceeded."); } IEnumerator enumerator = stack.Peek(); flag = enumerator.MoveNext(); if (flag) { obj = enumerator.Current; } else { stack.Pop(); (enumerator as IDisposable)?.Dispose(); } } catch (Exception ex2) { failure = ex2; } if (failure != null) { break; } if (flag) { if (obj is IEnumerator item) { stack.Push(item); } else { yield return obj; } } } } finally { if (stack.Count > 0 && failure == null) { failure = new OperationCanceledException("Unqualified Personnel startup iterator was cancelled."); } while (stack.Count > 0) { try { (stack.Pop() as IDisposable)?.Dispose(); } catch (Exception ex3) { if (failure == null) { failure = ex3; } } } if (failure != null) { try { failed(failure); } catch { } } } } } internal sealed class TextureAssetCache { private readonly Dictionary<string, Texture2D> values = new Dictionary<string, Texture2D>(); internal Texture2D Load(string path, bool linear) { //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_006f: 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_007e: Expected O, but got Unknown byte[] array = File.ReadAllBytes(path); string key; using (SHA256 sHA = SHA256.Create()) { key = (linear ? "linear:" : "srgb:") + Convert.ToBase64String(sHA.ComputeHash(array)); } if (values.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear) { name = Path.GetFileName(path), anisoLevel = 4, filterMode = (FilterMode)2 }; try { if (!ImageConversion.LoadImage(val, array, true)) { throw new InvalidDataException("Cannot decode " + Path.GetFileName(path)); } values[key] = val; return val; } catch { Object.Destroy((Object)(object)val); throw; } } }