/// <param name="name"> /// The name of the API (f.e. ExampleAPI) without spaces. As backends get injected, they don't have any metadata files. /// </param> /// <param name="version"> /// The backend version. As backends get injected, they don't have any metadata files. /// /// Following rules when adding API backends as dependencies in game mods: /// The major (X.) version must be the same (breaking changes). /// The minor (.X) version can be lower in the game mod metadata. /// Example using ExampleAPI as API backend and UsingIt as game mod: /// DEPends INStalled /// UsingIt depends on ExampleAPI 1.0 and 1.0 is installed. Pass. /// UsingIt depends on ExampleAPI 2.0 and 1.0 is installed. Fail. /// UsingIt depends on ExampleAPI 1.0 and 2.0 is installed. Fail. /// UsingIt depends on ExampleAPI 1.5 and 1.5 is installed. Fail. /// UsingIt depends on ExampleAPI 1.5 and 1.6 is installed. Pass. /// UsingIt depends on ExampleAPI 1.5 and 1.0 is installed. Fail. /// </param> public ETGBackend(string name, Version version) { Metadata = new ETGModuleMetadata() { Name = name, Version = version }; }
protected virtual IEnumerator _RefreshMods() { ModListGroup.Children.Clear(); for (int i = 0; i < ETGMod.GameMods.Count; i++) { ETGModule mod = ETGMod.GameMods[i]; ETGModuleMetadata meta = mod.Metadata; ModListGroup.Children.Add(NewEntry(meta.Name, meta.Icon)); yield return(null); } DisabledListGroup.Children.Clear(); string[] files = Directory.GetFiles(ETGMod.ModsDirectory); for (int i = 0; i < files.Length; i++) { string file = Path.GetFileName(files[i]); if (!file.EndsWithInvariant(".zip")) { continue; } if (ETGMod.GameMods.Exists(mod => mod.Metadata.Archive == files[i])) { continue; } DisabledListGroup.Children.Add(NewEntry(file.Substring(0, file.Length - 4), IconZip)); yield return(null); } files = Directory.GetDirectories(ETGMod.ModsDirectory); for (int i = 0; i < files.Length; i++) { string file = Path.GetFileName(files[i]); if (file == "RelinkCache") { continue; } if (ETGMod.GameMods.Exists(mod => mod.Metadata.Directory == files[i])) { continue; } DisabledListGroup.Children.Add(NewEntry($"{file}/", IconDir)); yield return(null); } }
/// <summary> /// Checks if an dependency is loaded. /// Can be used by mods manually to f.e. activate / disable functionality if an API's (not) existing. /// Currently only checks the backends. /// </summary> /// <param name="dependency">Dependency to check for. Name and Version will be checked.</param> /// <returns></returns> public static bool DependencyLoaded(ETGModuleMetadata dependency) { string dependencyName = dependency.Name; Version dependencyVersion = dependency.Version; if (dependencyName == "Base") { if (BaseVersion.Major != dependencyVersion.Major) { return(false); } if (BaseVersion.Minor < dependencyVersion.Minor) { return(false); } return(true); } foreach (ETGBackend backend in Backends) { ETGModuleMetadata metadata = backend.Metadata; if (metadata.Name != dependencyName) { continue; } Version version = metadata.Version; if (version.Major != dependencyVersion.Major) { return(false); } if (version.Minor < dependencyVersion.Minor) { return(false); } return(true); } return(false); }
private static ResolveEventHandler GenerateModAssemblyResolver(this ETGModuleMetadata metadata) { if (!string.IsNullOrEmpty(metadata.Archive)) { return(delegate(object sender, ResolveEventArgs args) { string asmName = new AssemblyName(args.Name).Name + ".dll"; using (ZipFile zip = ZipFile.Read(metadata.Archive)) { foreach (ZipEntry entry in zip.Entries) { if (entry.FileName != asmName) { continue; } using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); ms.Seek(0, SeekOrigin.Begin); return Assembly.Load(ms.GetBuffer()); } } } return null; }); } if (!string.IsNullOrEmpty(metadata.Directory)) { return(delegate(object sender, ResolveEventArgs args) { string asmPath = Path.Combine(metadata.Directory, new AssemblyName(args.Name).Name + ".dll"); if (!File.Exists(asmPath)) { return null; } return Assembly.LoadFrom(asmPath); }); } return(null); }
internal static ETGModuleMetadata Parse(string archive, string directory, Stream stream) { ETGModuleMetadata metadata = new ETGModuleMetadata(); metadata._archive = archive; metadata._directory = directory; metadata._prelinked = false; metadata._dependencies = new List <ETGModuleMetadata>(); using (StreamReader reader = new StreamReader(stream)) { int lineN = -1; while (!reader.EndOfStream) { ++lineN; string line = reader.ReadLine(); if (string.IsNullOrEmpty(line)) { continue; } line = line.Trim(); if (line[0] == '#') { continue; } if (!line.Contains(":")) { Debug.LogWarning("INVALID METADATA LINE #" + lineN); continue; } string[] data = line.Split(':'); if (data.Length < 2) { Debug.LogWarning("INVALID METADATA LINE #" + lineN); continue; } if (2 < data.Length) { StringBuilder newData = new StringBuilder(); for (int i = 1; i < data.Length; i++) { newData.Append(data[i]); if (i < data.Length - 1) { newData.Append(':'); } } data = new string[] { data[0], newData.ToString() }; } string prop = data[0].Trim(); data[1] = data[1].Trim(); if (prop == "Name") { metadata._name = data[1]; } else if (prop == "Version") { metadata._version = new Version(data[1]); } else if (prop == "DLL") { metadata._dll = data[1].Replace("\\", "/"); } else if (prop == "Prelinked") { metadata._prelinked = data[1].ToLowerInvariant() == "true"; } else if (prop == "Depends" || prop == "Dependency") { ETGModuleMetadata dep = new ETGModuleMetadata(); dep._name = data[1]; dep._version = new Version(0, 0); if (data[1].Contains(" ")) { string[] depData = data[1].Split(' '); dep._name = depData[0].Trim(); dep._version = new Version(depData[1].Trim()); } metadata._dependencies.Add(dep); } } } // Set the DLL path to be absolute in folder mods if not already absolute if (!string.IsNullOrEmpty(directory) && !File.Exists(metadata._dll)) { metadata._dll = Path.Combine(directory, metadata._dll.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar)); } // Add dependency to Base 1.0 if missing. bool dependsOnBase = false; foreach (ETGModuleMetadata dependency in metadata.Dependencies) { if (dependency.Name == "Base") { dependsOnBase = true; break; } } if (!dependsOnBase) { Debug.Log("WARNING: No dependency to Base found in " + metadata + "! Adding dependency to Base 1.0..."); metadata._dependencies.Insert(0, new ETGModuleMetadata() { _name = "Base", _version = new Version(1, 0) }); } return(metadata); }
public static void InitModDir(string dir) { Debug.Log("Initializing mod directory " + dir + " with Mods.txt is bad"); if (!Directory.Exists(dir)) { dir = Path.Combine(ETGMod.ModsDirectory, dir); } ETGModuleMetadata etgmoduleMetadata = new ETGModuleMetadata { Name = Path.GetFileName(dir), Version = new Version(0, 0), DLL = "mod.dll" }; Assembly assembly = null; string path = Path.Combine(dir, "metadata.txt"); if (File.Exists(path)) { using (FileStream fileStream = File.OpenRead(path)) { etgmoduleMetadata = (ETGModuleMetadata)parseMethod.Invoke(null, new object[] { "", dir, fileStream }); } } foreach (ETGModuleMetadata etgmoduleMetadata2 in etgmoduleMetadata.Dependencies) { if (!ETGMod.DependencyLoaded(etgmoduleMetadata2)) { Debug.LogWarning(string.Concat(new object[] { "DEPENDENCY ", etgmoduleMetadata2, " OF ", etgmoduleMetadata, " NOT LOADED with Mods.txt is bad!" })); return; } } AppDomain.CurrentDomain.AssemblyResolve += (ResolveEventHandler)generateModAssemblyMethod.Invoke(null, new object[] { etgmoduleMetadata }); if (!File.Exists(etgmoduleMetadata.DLL)) { return; } if (etgmoduleMetadata.Prelinked) { assembly = Assembly.LoadFrom(etgmoduleMetadata.DLL); } else { using (FileStream fileStream2 = File.OpenRead(etgmoduleMetadata.DLL)) { assembly = etgmoduleMetadata.GetRelinkedAssembly(fileStream2); } } assembly.MapAssets(); ETGMod.Assets.Crawl(dir, null); foreach (Type type in assembly.GetTypes()) { if (typeof(ETGModule).IsAssignableFrom(type) && !type.IsAbstract) { ETGModule etgmodule = (ETGModule)type.GetConstructor((Type[])emptyTypeArrayInfo.GetValue(null)).Invoke((object[])emptyObjectArrayInfo.GetValue(null)); if (!ETGMod.AllMods.Contains(etgmodule)) { etgmodule.Metadata = etgmoduleMetadata; ETGMod.GameMods.Add(etgmodule); ETGMod.AllMods.Add(etgmodule); loadedMods.Add(etgmodule); addedModuleTypes.Add(type); addedModuleMethods.Add(new Dictionary <string, MethodInfo>()); } } } Debug.Log("Mod " + etgmoduleMetadata.Name + " initialized with Mods.txt is bad."); }
public static void InitModZIP(string archive) { Debug.Log("Initializing mod ZIP " + archive + " with Mods.txt is bad."); if (!File.Exists(archive)) { archive = Path.Combine(ETGMod.ModsDirectory, archive); } ETGModuleMetadata etgmoduleMetadata = new ETGModuleMetadata { Name = Path.GetFileNameWithoutExtension(archive), Version = new Version(0, 0), DLL = "mod.dll" }; Assembly assembly = null; using (ZipFile zipFile = ZipFile.Read(archive)) { Texture2D texture2D = null; foreach (ZipEntry zipEntry in zipFile.Entries) { if (zipEntry.FileName == "metadata.txt") { using (MemoryStream memoryStream = new MemoryStream()) { zipEntry.Extract(memoryStream); memoryStream.Seek(0L, SeekOrigin.Begin); etgmoduleMetadata = (ETGModuleMetadata)parseMethod.Invoke(null, new object[] { archive, "", memoryStream }); continue; } } if (zipEntry.FileName == "icon.png") { texture2D = new Texture2D(2, 2); texture2D.name = "icon"; using (MemoryStream memoryStream2 = new MemoryStream()) { zipEntry.Extract(memoryStream2); memoryStream2.Seek(0L, SeekOrigin.Begin); texture2D.LoadImage(memoryStream2.GetBuffer()); } texture2D.filterMode = FilterMode.Point; } } if (texture2D != null) { etgmoduleMetadata.Icon = texture2D; } if (!etgmoduleMetadata.Profile.RunsOn(ETGMod.BaseProfile)) { return; } foreach (ETGModuleMetadata etgmoduleMetadata2 in etgmoduleMetadata.Dependencies) { if (!ETGMod.DependencyLoaded(etgmoduleMetadata2)) { Debug.LogWarning(string.Concat(new object[] { "DEPENDENCY ", etgmoduleMetadata2, " OF ", etgmoduleMetadata, " NOT LOADED with Mods.txt is bad!" })); return; } } AppDomain.CurrentDomain.AssemblyResolve += (ResolveEventHandler)generateModAssemblyMethod.Invoke(null, new object[] { etgmoduleMetadata }); foreach (ZipEntry zipEntry2 in zipFile.Entries) { string text = zipEntry2.FileName.Replace("\\", "/"); if (text == etgmoduleMetadata.DLL) { using (MemoryStream memoryStream3 = new MemoryStream()) { zipEntry2.Extract(memoryStream3); memoryStream3.Seek(0L, SeekOrigin.Begin); if (etgmoduleMetadata.Prelinked) { assembly = Assembly.Load(memoryStream3.GetBuffer()); continue; } assembly = etgmoduleMetadata.GetRelinkedAssembly(memoryStream3); continue; } } ETGMod.Assets.AddMapping(text, new AssetMetadata(archive, text) { AssetType = (zipEntry2.IsDirectory ? ETGMod.Assets.t_AssetDirectory : null) }); } } if (assembly == null) { return; } assembly.MapAssets(); foreach (Type type in assembly.GetTypes()) { if (typeof(ETGModule).IsAssignableFrom(type) && !type.IsAbstract) { ETGModule etgmodule = (ETGModule)type.GetConstructor((Type[])emptyTypeArrayInfo.GetValue(null)).Invoke((object[])emptyObjectArrayInfo.GetValue(null)); if (!ETGMod.AllMods.Contains(etgmodule)) { etgmodule.Metadata = etgmoduleMetadata; ETGMod.GameMods.Add(etgmodule); ETGMod.AllMods.Add(etgmodule); loadedMods.Add(etgmodule); addedModuleTypes.Add(type); addedModuleMethods.Add(new Dictionary <string, MethodInfo>()); } } } Debug.Log("Mod " + etgmoduleMetadata.Name + " initialized with Mods.txt is bad."); }
public override void Start() { try { ETGModConsole.Log("Once More Into The Breach started initialising..."); //Rooms ZipFilePath = this.Metadata.Archive; FilePath = this.Metadata.Directory + "/rooms"; ModName = this.Metadata.Name; //Tools and Toolboxes StaticReferences.Init(); ExoticPlaceables.Init(); DungeonHandler.Init(); Tools.Init(); ShrineFakePrefabHooks.Init(); ShrineFactory.Init(); OldShrineFactory.Init(); FakePrefabHooks.Init(); ItemBuilder.Init(); CharApi.Init("nn"); CustomClipAmmoTypeToolbox.Init(); EnemyTools.Init(); NpcApi.Hooks.Init(); EnemyAPI.Hooks.Init(); SaveAPIManager.Setup("nn"); AudioResourceLoader.InitAudio(); CurseManager.Init(); ETGModMainBehaviour.Instance.gameObject.AddComponent <GlobalUpdate>(); ETGModMainBehaviour.Instance.gameObject.AddComponent <CustomDarknessHandler>(); GameOfLifeHandler.Init(); //ETGModMainBehaviour.Instance.gameObject.AddComponent<GameOfLifeHandler>(); //ETGModConsole.Log(Assembly.GetExecutingAssembly().FullName); //Challenges Challenges.Init(); //Hooks n Shit PlayerToolsSetup.Init(); EnemyHooks.InitEnemyHooks(); CompanionisedEnemyUtility.InitHooks(); MiscUnlockHooks.InitHooks(); FloorAndGenerationToolbox.Init(); PedestalHooks.Init(); ExplosionHooks.Init(); ChestToolbox.Inithooks(); UIHooks.Init(); ComplexProjModBeamCompatibility.Init(); ReloadBreachShrineHooks.Init(); metadata = this.Metadata; //VFX Setup VFXToolbox.InitVFX(); EasyVFXDatabase.Init(); //Needs to occur before goop definition ShadeFlightHookFix.Init(); //Status Effect Setup StaticStatusEffects.InitCustomEffects(); PlagueStatusEffectSetup.Init(); Confusion.Init(); //Goop Setup EasyGoopDefinitions.DefineDefaultGoops(); DoGoopEffectHook.Init(); //Commands and Other Console Utilities Commands.Init(); //Hats HatUtility.NecessarySetup(); HatDefinitions.Init(); //Gamemodes AllJammedState.Init(); JammedChests.Init(); //Exotic Object Shit //VFX LockdownStatusEffect.Initialise(); //Testing / Debug Items ActiveTestingItem.Init(); PassiveTestingItem.Init(); BulletComponentLister.Init(); ObjectComponentLister.Init(); //-----------------------------------------------------ITEMS GET INITIALISED #region ItemInitialisation //Character Starters ShadeHand.Init(); ShadeHeart.Init(); //Egg Salad and Prima Bean can go here, because they were the first EggSalad.Init(); PrimaBean.Init(); //Bullet modifiers BashingBullets.Init(); TitanBullets.Init(); MistakeBullets.Init(); FiftyCalRounds.Init(); UnengravedBullets.Init(); EngravedBullets.Init(); HardReloadBullets.Init(); NitroBullets.Init(); SupersonicShots.Init(); GlassRounds.Init(); Junkllets.Init(); BloodthirstyBullets.Init(); CleansingRounds.Init(); HallowedBullets.Init(); PromethianBullets.Init(); EpimethianBullets.Init(); RandoRounds.Init(); IngressBullets.Init(); //Unfinished HematicRounds.Init(); FullArmourJacket.Init(); MirrorBullets.Init(); CrowdedClip.Init(); BashfulShot.Init(); OneShot.Init(); BulletBullets.Init(); AntimatterBullets.Init(); SpectreBullets.Init(); Tabullets.Init(); TierBullets.Init(); //Unfinished BombardierShells.Init(); GildedLead.Init(); DemoterBullets.Init(); Voodoollets.Init(); TracerRound.Init(); EndlessBullets.Init(); HellfireRounds.Init(); Birdshot.Init(); Unpredictabullets.Init(); WarpBullets.Init(); BulletsWithGuns.Init(); LaserBullets.Init(); BalancedBullets.Init(); //Unfinished WoodenBullets.Init(); ComicallyGiganticBullets.Init(); //Excluded KnightlyBullets.Init(); EmptyRounds.Init(); LongswordShot.Init(); DrillBullets.Init(); FoamDarts.Init(); BatterBullets.Init(); ElectrumRounds.Init(); BreachingRounds.Init(); MagnetItem.Init(); EargesplittenLoudenboomerRounds.Init(); TheShell.Init(); //Status Effect Bullet Mods SnailBullets.Init(); LockdownBullets.Init(); PestiferousLead.Init(); Shrinkshot.Init(); //Volley Modifying Bullet Mods Splattershot.Init(); BackwardsBullets.Init(); CrossBullets.Init(); ShadeShot.Init(); //Insta-Kill Bullet Modifiers MinersBullets.Init(); AntimagicRounds.Init(); AlkaliBullets.Init(); ShutdownShells.Init(); ERRORShells.Init(); OsteoporosisBullets.Init(); //NonBullet Stat Changers MicroAIContact.Init(); LuckyCoin.Init(); IronSights.Init(); Lewis.Init(); MysticOil.Init(); VenusianBars.Init(); NumberOneBossMug.Init(); LibramOfTheChambers.Init(); OrganDonorCard.Init(); GlassGod.Init(); ChaosRuby.Init(); BlobulonRage.Init(); OverpricedHeadband.Init(); GunslingerEmblem.Init(); MobiusClip.Init(); ClipOnAmmoPouch.Init(); JawsOfDefeat.Init(); //Armour ArmourBandage.Init(); GoldenArmour.Init(); ExoskeletalArmour.Init(); PowerArmour.Init(); ArmouredArmour.Init(); //Consumable Givers LooseChange.Init(); SpaceMetal.Init(); //Blank Themed Items TrueBlank.Init(); FalseBlank.Init(); SpareBlank.Init(); OpulentBlank.Init(); GrimBlanks.Init(); NNBlankPersonality.Init(); Blombk.Init(); Blankh.Init(); //Key Themed Items BlankKey.Init(); SharpKey.Init(); SpareKey.Init(); KeyChain.Init(); KeyBullwark.Init(); KeyBulletEffigy.Init(); FrostKey.Init(); ShadowKey.Init(); Keygen.Init(); CursedTumbler.Init(); //Ammo Box Themed Items TheShellactery.Init(); BloodyAmmo.Init(); MengerAmmoBox.Init(); AmmoTrap.Init(); //Boxes and Stuff BloodyBox.Init(); MaidenShapedBox.Init(); Toolbox.Init(); PocketChest.Init(); DeliveryBox.Init(); Wonderchest.Init(); //Heart themed items HeartPadlock.Init(); Mutagen.Init(); ForsakenHeart.Init(); HeartOfGold.Init(); GooeyHeart.Init(); ExaltedHeart.Init(); CheeseHeart.Init(); TinHeart.Init(); //Chambers BarrelChamber.Init(); GlassChamber.Init(); FlameChamber.Init(); Recyclinder.Init(); Nitroglycylinder.Init(); SpringloadedChamber.Init(); WitheringChamber.Init(); HeavyChamber.Init(); CyclopeanChamber.Init(); //Table Techs TableTechTable.Init(); TableTechSpeed.Init(); TableTechInvulnerability.Init(); TableTechAmmo.Init(); TableTechGuon.Init(); TableTechNology.Init(); UnsTableTech.Init(); //Guon Stones WoodGuonStone.Init(); YellowGuonStone.Init(); GreyGuonStone.Init(); GoldGuonStone.Init(); BrownGuonStone.Init(); CyanGuonStone.Init(); IndigoGuonStone.Init(); SilverGuonStone.Init(); MaroonGuonStone.Init(); UltraVioletGuonStone.Init(); InfraredGuonStone.Init(); RainbowGuonStone.Init(); KaleidoscopicGuonStone.Init(); GuonBoulder.Init(); BloodglassGuonStone.Init(); //Ammolets GlassAmmolet.Init(); WickerAmmolet.Init(); FuriousAmmolet.Init(); SilverAmmolet.Init(); IvoryAmmolet.Init(); KinAmmolet.Init(); Autollet.Init(); Keymmolet.Init(); Ammolock.Init(); HepatizonAmmolet.Init(); BronzeAmmolet.Init(); PearlAmmolet.Init(); NeutroniumAmmolet.Init(); Shatterblank.Init(); // Boots CycloneCylinder.Init(); BootLeg.Init(); BlankBoots.Init(); BulletBoots.Init(); //Bracelets and Jewelry DiamondBracelet.Init(); PearlBracelet.Init(); PanicPendant.Init(); GunknightAmulet.Init(); AmuletOfShelltan.Init(); //Rings RingOfOddlySpecificBenefits.Init(); FowlRing.Init(); RingOfAmmoRedemption.Init(); RiskyRing.Init(); WidowsRing.Init(); ShadowRing.Init(); RingOfInvisibility.Init(); //Holsters BlackHolster.Init(); TheBeholster.Init(); HiveHolster.Init(); ShoulderHolster.Init(); ArtilleryBelt.Init(); BulletShuffle.Init(); //Companions MolotovBuddy.Init(); BabyGoodChanceKin.Init(); Potty.Init(); Peanut.Init(); DarkPrince.Init(); Diode.Init(); DroneCompanion.Init(); GregTheEgg.Init(); FunGuy.Init(); BabyGoodDet.Init(); AngrySpirit.Init(); Gusty.Init(); ScrollOfExactKnowledge.Init(); LilMunchy.Init(); //Potions / Jars SpeedPotion.Init(); LovePotion.Init(); HoneyPot.Init(); ChemicalBurn.Init(); WitchsBrew.Init(); Nigredo.Init(); Albedo.Init(); Citrinitas.Init(); Rubedo.Init(); HoleyWater.Init(); //Remotes ReinforcementRadio.Init(); //Medicine BloodThinner.Init(); BoosterShot.Init(); ShotInTheArm.Init(); //Knives and Blades DaggerOfTheAimgel.Init(); CombatKnife.Init(); Bayonet.Init(); //Books BookOfMimicAnatomy.Init(); KalibersPrayer.Init(); GunidaeSolvitHaatelis.Init(); //Maps MapFragment.Init(); TatteredMap.Init(); //Clothing CloakOfDarkness.Init(); TimeFuddlersRobe.Init(); //Eyes CartographersEye.Init(); BloodshotEye.Init(); ShadesEye.Init(); KalibersEye.Init(); //Hands Lefthandedness.Init(); NecromancersRightHand.Init(); //Bombs InfantryGrenade.Init(); DiceGrenade.Init(); //True Misc Lvl2Molotov.Init(); GoldenAppleCore.Init(); AppleCore.Init(); AppleActive.Init(); LibationtoIcosahedrax.Init(); //Unfinished BagOfHolding.Init(); ItemCoupon.Init(); IdentityCrisis.Init(); LiquidMetalBody.Init(); GunGrease.Init(); BomberJacket.Init(); DragunsScale.Init(); GTCWTVRP.Init(); BlightShell.Init(); BulletKinPlushie.Init(); Kevin.Init(); PurpleProse.Init(); RustyCasing.Init(); HikingPack.Init(); GunpowderPheromones.Init(); GunsmokePerfume.Init(); Pestilence.Init(); ElevatorButton.Init(); Bullut.Init(); GSwitch.Init(); FaultyHoverboots.Init(); //Unfinished AcidAura.Init(); HornedHelmet.Init(); RocketMan.Init(); Roulette.Init(); //Unfinished FinishedBullet.Init(); ChanceKinEffigy.Init(); MagickeCauldron.Init(); Bombinomicon.Init(); ClaySculpture.Init(); GracefulGoop.Init(); MrFahrenheit.Init(); MagicQuiver.Init(); FocalLenses.Init(); MagicMissile.Init(); AmberDie.Init(); ObsidianPistol.Init(); Showdown.Init(); LootEngineItem.Init(); Ammolite.Init(); PortableHole.Init(); CardinalsMitre.Init(); GunjurersBelt.Init(); GoomperorsCrown.Init(); ChemGrenade.Init(); EightButton.Init(); TitaniumClip.Init(); PaperBadge.Init(); Permafrost.Init(); GlassShard.Init(); EqualityItem.Init(); BitBucket.Init(); Eraser.Init(); TackShooter.Init(); Moonrock.Init(); Telekinesis.Init(); TabletOfOrder.Init(); LeadSoul.Init(); LeadOfLife.Init(); AWholeBulletKin.Init(); #endregion //-----------------------------------------------------GUNS GET INITIALISED #region GunInitialisation //UNFINISHED / TEST GUNS WailingMagnum.Add(); Defender.Add(); TestGun.Add(); Gunycomb.Add(); GlobbitSMALL.Add(); GlobbitMED.Add(); GlobbitMEGA.Add(); //GUNS //CHARACTERSTARTERS ElderMagnum.Add(); //REVOLVERS FlayedRevolver.Add(); G20.Add(); MamaGun.Add(); LovePistol.Add(); DiscGun.Add(); Repeatovolver.Add(); Pista.Add(); NNGundertale.Add(); DiamondGun.Add(); NNMinigun.Add(); ShroomedGun.Add(); GoldenRevolver.Add(); Nocturne.Add(); BackWarder.Add(); Redhawk.Add(); ToolGun.Add(); //GENERAL HANDGUNS StickGun.Add(); Glock42.Add(); StarterPistol.Add(); PopGun.Add(); UnusCentum.Add(); StunGun.Add(); CopperSidearm.Add(); Rekeyter.Add(); HotGlueGun.Add(); UpNUp.Add(); RedRobin.Add(); VariableGun.Add(); CrescendoBlaster.Add(); Glasster.Add(); HandGun.Add(); Viper.Add(); DiamondCutter.Add(); MarchGun.Add(); RebarGun.Add(); MinuteGun.Add(); Ulfberht.Add(); HeadOfTheOrder.Add(); GunOfAThousandSins.Add(); DoubleGun.Add(); //SHOTGUNS JusticeGun.Add(); Orgun.Add(); Octagun.Add(); ClownShotgun.Add(); Ranger.Add(); RustyShotgun.Add(); TheBride.Add(); TheGroom.Add(); IrregularShotgun.Add(); GrenadeShotgun.Add(); Jackhammer.Add(); SaltGun.Add(); SoapGun.Add(); //CANNONS Felissile.Add(); HandCannon.Add(); Lantaka.Add(); GreekFire.Add(); EmberCannon.Add(); ElysiumCannon.Add(); DisplacerCannon.Add(); //SCI-FI GUNS Blasmaster.Add(); St4ke.Add(); RedBlaster.Add(); BeamBlade.Add(); Neutrino.Add(); Rico.Add(); TheThinLine.Add(); RocketPistol.Add(); Repetitron.Add(); Dimensionaliser.Add(); Purpler.Add(); VacuumGun.Add(); Oxygun.Add(); TriBeam.Add(); KineticBlaster.Add(); LaserWelder.Add(); QBeam.Add(); HighVelocityRifle.Add(); Demolitionist.Add(); PumpChargeShotgun.Add(); TheOutbreak.Add(); Multiplicator.Add(); PunishmentRay.Add(); YBeam.Add(); WallRay.Add(); BolaGun.Add(); AlphaBeam.Add(); Glazerbeam.Add(); StasisRifle.Add(); Gravitron.Add(); Ferrobolt.Add(); TauCannon.Add(); GravityGun.Add(); GalaxyCrusher.Add(); //ARC Weapons ARCPistol.Add(); ARCShotgun.Add(); ARCRifle.Add(); ARCTactical.Add(); ARCCannon.Add(); //BOWS AND CROSSBOWS IceBow.Add(); Boltcaster.Add(); Clicker.Add(); //ANTIQUES WheelLock.Add(); Welrod.Add(); Welgun.Add(); TheLodger.Add(); Gonne.Add(); Hwacha.Add(); FireLance.Add(); HandMortar.Add(); GrandfatherGlock.Add(); GatlingGun.Add(); Blowgun.Add(); Gaxe.Add(); WoodenHorse.Add(); AgarGun.Add(); //KNIVES AND BLADES Carnwennan.Add(); MantidAugment.Add(); //REALISTIC GUNS HeatRay.Add(); BarcodeScanner.Add(); AntimaterielRifle.Add(); Primos1.Add(); DartRifle.Add(); AM0.Add(); RiskRifle.Add(); RiotGun.Add(); Kalashnirang.Add(); MaidenRifle.Add(); Blizzkrieg.Add(); Copygat.Add(); Skorpion.Add(); HeavyAssaultRifle.Add(); DynamiteLauncher.Add(); MarbledUzi.Add(); BurstRifle.Add(); OlReliable.Add(); //MISSILE LAUNCHERS BottleRocket.Add(); NNBazooka.Add(); BoomBeam.Add(); Pillarocket.Add(); //ANIMAL / ORGANIC GUNS SporeLauncher.Add(); PoisonDartFrog.Add(); Corgun.Add(); FungoCannon.Add(); PhaserSpiderling.Add(); Guneonate.Add(); KillithidTendril.Add(); Gunger.Add(); SickWorm.Add(); MiniMonger.Add(); CarrionFormeTwo.Add(); CarrionFormeThree.Add(); Carrion.Add(); UterinePolyp.Add(); Wrinkler.Add(); //BLADES ButchersKnife.Add(); RapidRiposte.Add(); //FUN GUNS Gumgun.Add(); Glooper.Add(); Accelerator.Add(); PaintballGun.Add(); Converter.Add(); Spiral.Add(); Gunshark.Add(); FingerGuns.Add(); OBrienFist.Add(); GolfRifle.Add(); Pandephonium.Add(); Sweeper.Add(); DeskFan.Add(); Pencil.Add(); SquarePeg.Add(); Ringer.Add(); Snaker.Add(); GayK47.Add(); DecretionCarbine.Add(); RC360.Add(); UziSpineMM.Add(); Autogun.Add(); Rebondir.Add(); BigShot.Add(); W3irdstar.Add(); Seismograph.Add(); BioTranstater2100.Add(); //MAGICAL GUNS Icicle.Add(); GunjurersStaff.Add(); InitiateWand.Add(); LightningRod.Add(); OrbOfTheGun.Add(); SpearOfJustice.Add(); Protean.Add(); BulletBlade.Add(); Bookllet.Add(); Lorebook.Add(); Beastclaw.Add(); Bullatterer.Add(); Entropew.Add(); Missinguno.Add(); Paraglocks.Add(); //CONSUMABLE FIRING GUNS Creditor.Add(); Blankannon.Add(); Viscerifle.Add(); //ENDPAGE GUNS MastersGun.Add(); Wrench.Add(); Pumhart.Add(); //SYNERGY FORME GUNS GunsharkMegasharkSynergyForme.Add(); DiscGunSuperDiscForme.Add(); OrgunHeadacheSynergyForme.Add(); Wolfgun.Add(); MinigunMiniShotgunSynergyForme.Add(); PenPencilSynergy.Add(); ReShelletonKeyter.Add(); AM0SpreadForme.Add(); BulletBladeGhostForme.Add(); GlueGunGlueGunnerSynergy.Add(); KingBullatterer.Add(); WrenchNullRefException.Add(); GatlingGunGatterUp.Add(); GravityGunNegativeMatterForm.Add(); GonneElder.Add(); UterinePolypWombular.Add(); DiamondGaxe.Add(); RedRebondir.Add(); DiamondCutterRangerClass.Add(); StickGunQuickDraw.Add(); StormRod.Add(); UnrustyShotgun.Add(); #endregion //-----------------------------------------------------SHRINES GET INITIALISED #region ShrineInitialisation InvestmentShrine.Add(); RelodinShrine.Add(); DagunShrine.Add(); ArtemissileShrine.Add(); ExecutionerShrine.Add(); TurtleShrine.Add(); KliklokShrine.Add(); #endregion //-----------------------------------------------------NPCS GET INITIALISED #region NPCInitialisation Rusty.Init(); Ironside.Init(); Boomhildr.Init(); #endregion ChromaGun.Add(); //GOOD MIMIC (NEEDS TO BE INITIALISED LATER) GoodMimic.Add(); //Characters var data = Loader.BuildCharacter("NevernamedsItems/Characters/Shade", CustomPlayableCharacters.Shade, new Vector3(12.3f, 21.3f), false, new Vector3(13.1f, 19.1f), false, false, true, true, //Sprites used by paradox false, //Glows null, //Glow Mat null, //Alt Skin Glow Mat 0, //Hegemony Cost false, //HasPast ""); //Past ID String //Other Features MasteryReplacementOub.InitDungeonHook(); CadenceAndOxShopPoolAdditions.Init(); CustomHuntingQuest.Init(); //NPCS TheJammomaster.Add(); //Carto.Add(); ShrineFactory.PlaceBreachShrines(); //Synergy Setup, Synergy Formes, Dual Wielding, and any changes to Basegame Guns InitialiseSynergies.DoInitialisation(); SynergyFormInitialiser.AddSynergyForms(); ExistantGunModifiers.Init(); ChamberGunAPI.Init("OnceMoreIntoTheBreach"); //Late Hooks AmmoPickupHooks.Init(); HealthPickupHooks.Init(); ETGModConsole.Commands.AddUnit("nndebugflow", (args) => { DungeonHandler.debugFlow = !DungeonHandler.debugFlow; string status = DungeonHandler.debugFlow ? "enabled" : "disabled"; string color = DungeonHandler.debugFlow ? "00FF00" : "FF0000"; ETGModConsole.Log($"OMITB flow {status}", false); }); //PoopySchloopy /* Dungeon keepDungeon = DungeonDatabase.GetOrLoadByName("base_jungle"); * if (keepDungeon == null) ETGModConsole.Log("Jungle null!"); * if (keepDungeon && keepDungeon.PatternSettings != null) * { * if (keepDungeon.PatternSettings.flows != null && keepDungeon.PatternSettings.flows.Count > 0) * { * if (keepDungeon.PatternSettings.flows[0].fallbackRoomTable) * { * if (keepDungeon.PatternSettings.flows[0].fallbackRoomTable.includedRooms != null) * { * if (keepDungeon.PatternSettings.flows[0].fallbackRoomTable.includedRooms.elements != null) * { * foreach (WeightedRoom wRoom in keepDungeon.PatternSettings.flows[0].fallbackRoomTable.includedRooms.elements) * { * * if (wRoom.room != null && !string.IsNullOrEmpty(wRoom.room.name)) * { * ETGModConsole.Log(wRoom.room.name); * } * } * } * else ETGModConsole.Log("No elements"); * } * else ETGModConsole.Log("No included rooms"); * } * else ETGModConsole.Log("No fallback room table"); * } * else ETGModConsole.Log("Flow was null or empty"); * } * else ETGModConsole.Log("Pattern settings null"); * keepDungeon = null;*/ ETGMod.StartGlobalCoroutine(this.delayedstarthandler()); ETGModConsole.Log("'If you're reading this, I must have done something right' - NN"); } catch (Exception e) { ETGModConsole.Log(e.Message); ETGModConsole.Log(e.StackTrace); } }
public static Assembly GetRelinkedAssembly(this ETGModuleMetadata metadata, Stream stream) { if (ETGModule == null) { ETGModule = ModuleDefinition.ReadModule(Assembly.GetAssembly(typeof(ETGModRelinker)).Location, new ReaderParameters(ReadingMode.Immediate)); } if (!Directory.Exists(ETGMod.RelinkCacheDirectory)) { Directory.CreateDirectory(ETGMod.RelinkCacheDirectory); } string cachedName = metadata.DLL.Substring(0, metadata.DLL.Length - 3) + "dat"; string cachedPath = Path.Combine( ETGMod.RelinkCacheDirectory, cachedName ); string cachedChecksumPath = Path.Combine( ETGMod.RelinkCacheDirectory, cachedName + ".sum" ); string[] checksums = new string[2]; using (MD5 md5 = MD5.Create()) { if (ETGChecksum == null) { using (FileStream fs = File.OpenRead(Assembly.GetAssembly(typeof(ETGModRelinker)).Location)) { ETGChecksum = md5.ComputeHash(fs).ToHexadecimalString(); } } checksums[0] = ETGChecksum; string modPath = metadata.Archive; if (modPath.Length == 0) { modPath = metadata.DLL; } using (FileStream fs = File.OpenRead(modPath)) { checksums[1] = md5.ComputeHash(fs).ToHexadecimalString(); } } if (File.Exists(cachedPath) && File.Exists(cachedChecksumPath)) { if (checksums.ChecksumsEqual(File.ReadAllLines(cachedChecksumPath))) { return(Assembly.LoadFrom(cachedPath)); } } ModuleDefinition md = ModuleDefinition.ReadModule(stream, new ReaderParameters(ReadingMode.Immediate)); foreach (TypeDefinition type in md.Types) { RelinkType(type); } if (File.Exists(cachedPath)) { File.Delete(cachedPath); } using (FileStream fs = File.OpenWrite(cachedPath)) { md.Write(fs); } md = ModuleDefinition.ReadModule(cachedPath, new ReaderParameters(ReadingMode.Immediate)); if (File.Exists(cachedChecksumPath)) { File.Delete(cachedChecksumPath); } File.WriteAllLines(cachedChecksumPath, checksums); return(Assembly.LoadFrom(cachedPath)); }
public static void InitModDir(string dir) { Debug.Log("Initializing mod directory " + dir); if (!Directory.Exists(dir)) { // Probably a mod in the mod directory dir = Path.Combine(ModsDirectory, dir); } // Fallback metadata in case none is found ETGModuleMetadata metadata = new ETGModuleMetadata() { Name = Path.GetFileName(dir), Version = new Version(0, 0), DLL = "mod.dll" }; Assembly asm = null; // First read the metadata, ... string metadataPath = Path.Combine(dir, "metadata.txt"); if (File.Exists(metadataPath)) { using (FileStream fs = File.OpenRead(metadataPath)) { metadata = ETGModuleMetadata.Parse("", dir, fs); } } // ... then check if the dependencies are loaded ... foreach (ETGModuleMetadata dependency in metadata.Dependencies) { if (!DependencyLoaded(dependency)) { Debug.LogWarning("DEPENDENCY " + dependency + " OF " + metadata + " NOT LOADED!"); return; } } // ... then add an AssemblyResolve handler for all the .zip-ped libraries AppDomain.CurrentDomain.AssemblyResolve += metadata.GenerateModAssemblyResolver(); // ... then everything else if (!File.Exists(metadata.DLL)) { return; } if (metadata.Prelinked) { asm = Assembly.LoadFrom(metadata.DLL); } else { using (FileStream fs = File.OpenRead(metadata.DLL)) { asm = metadata.GetRelinkedAssembly(fs); } } Assets.Crawl(dir); Type[] types = asm.GetTypes(); for (int i = 0; i < types.Length; i++) { Type type = types[i]; if (!typeof(ETGModule).IsAssignableFrom(type) || type.IsAbstract) { continue; } ETGModule module = (ETGModule)type.GetConstructor(a_Type_0).Invoke(a_object_0); module.Metadata = metadata; GameMods.Add(module); AllMods.Add(module); ModuleTypes.Add(type); ModuleMethods.Add(new Dictionary <string, MethodInfo>()); } Debug.Log("Mod " + metadata.Name + " initialized."); }
public static void InitModZIP(string archive) { Debug.Log("Initializing mod ZIP " + archive); if (!File.Exists(archive)) { // Probably a mod in the mod directory archive = Path.Combine(ModsDirectory, archive); } // Fallback metadata in case none is found ETGModuleMetadata metadata = new ETGModuleMetadata() { Name = Path.GetFileNameWithoutExtension(archive), Version = new Version(0, 0), DLL = "mod.dll" }; Assembly asm = null; using (ZipFile zip = ZipFile.Read(archive)) { // First read the metadata, ... foreach (ZipEntry entry in zip.Entries) { if (entry.FileName == "metadata.txt") { using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); ms.Seek(0, SeekOrigin.Begin); metadata = ETGModuleMetadata.Parse(archive, "", ms); } break; } } // ... then check if the dependencies are loaded ... foreach (ETGModuleMetadata dependency in metadata.Dependencies) { if (!DependencyLoaded(dependency)) { Debug.LogWarning("DEPENDENCY " + dependency + " OF " + metadata + " NOT LOADED!"); return; } } // ... then add an AssemblyResolve handler for all the .zip-ped libraries AppDomain.CurrentDomain.AssemblyResolve += metadata.GenerateModAssemblyResolver(); // ... then everything else foreach (ZipEntry entry in zip.Entries) { string entryName = entry.FileName.Replace("\\", "/"); if (entryName == metadata.DLL) { using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); ms.Seek(0, SeekOrigin.Begin); if (metadata.Prelinked) { asm = Assembly.Load(ms.GetBuffer()); } else { asm = metadata.GetRelinkedAssembly(ms); } } } else { Assets.Map[Assets.RemoveExtension(entryName)] = new ETGModAssetMetadata(archive, entryName); } } } if (asm == null) { return; } Type[] types = asm.GetTypes(); for (int i = 0; i < types.Length; i++) { Type type = types[i]; if (!typeof(ETGModule).IsAssignableFrom(type) || type.IsAbstract) { continue; } ETGModule module = (ETGModule)type.GetConstructor(a_Type_0).Invoke(a_object_0); module.Metadata = metadata; GameMods.Add(module); AllMods.Add(module); ModuleTypes.Add(type); ModuleMethods.Add(new Dictionary <string, MethodInfo>()); } Debug.Log("Mod " + metadata.Name + " initialized."); }