Content parser class discovery improvements

This commit is contained in:
Anuken 2021-02-18 13:11:20 -05:00
parent f8f9bf228b
commit a7188c4884
6 changed files with 379 additions and 72 deletions

View File

@ -35,7 +35,7 @@ allprojects{
if(!project.hasProperty("versionType")) versionType = 'official'
appName = 'Mindustry'
steamworksVersion = '891ed912791e01fe9ee6237a6497e5212b85c256'
rhinoVersion = '2617981f706e50b8753155d8e15e326308be3b22'
rhinoVersion = '378626d8abc552bba57864358358045d2f2dbe9b'
loadVersionProps = {
return new Properties().with{p -> p.load(file('../core/assets/version.properties').newReader()); return p }

View File

@ -0,0 +1,259 @@
package mindustry.mod;
import arc.struct.*;
/** Generated class. Maps simple class names to concrete classes. For use in JSON mods. */
public class ClassMap{
public static final ObjectMap<String, Class<?>> classes = new ObjectMap<>();
static{
classes.put("BuilderAI", mindustry.ai.types.BuilderAI.class);
classes.put("FlyingAI", mindustry.ai.types.FlyingAI.class);
classes.put("FormationAI", mindustry.ai.types.FormationAI.class);
classes.put("GroundAI", mindustry.ai.types.GroundAI.class);
classes.put("LogicAI", mindustry.ai.types.LogicAI.class);
classes.put("MinerAI", mindustry.ai.types.MinerAI.class);
classes.put("RepairAI", mindustry.ai.types.RepairAI.class);
classes.put("SuicideAI", mindustry.ai.types.SuicideAI.class);
classes.put("ArtilleryBulletType", mindustry.entities.bullet.ArtilleryBulletType.class);
classes.put("BasicBulletType", mindustry.entities.bullet.BasicBulletType.class);
classes.put("BombBulletType", mindustry.entities.bullet.BombBulletType.class);
classes.put("BulletType", mindustry.entities.bullet.BulletType.class);
classes.put("ContinuousLaserBulletType", mindustry.entities.bullet.ContinuousLaserBulletType.class);
classes.put("FlakBulletType", mindustry.entities.bullet.FlakBulletType.class);
classes.put("LaserBoltBulletType", mindustry.entities.bullet.LaserBoltBulletType.class);
classes.put("LaserBulletType", mindustry.entities.bullet.LaserBulletType.class);
classes.put("LightningBulletType", mindustry.entities.bullet.LightningBulletType.class);
classes.put("LiquidBulletType", mindustry.entities.bullet.LiquidBulletType.class);
classes.put("MassDriverBolt", mindustry.entities.bullet.MassDriverBolt.class);
classes.put("MissileBulletType", mindustry.entities.bullet.MissileBulletType.class);
classes.put("PointBulletType", mindustry.entities.bullet.PointBulletType.class);
classes.put("RailBulletType", mindustry.entities.bullet.RailBulletType.class);
classes.put("SapBulletType", mindustry.entities.bullet.SapBulletType.class);
classes.put("ShrapnelBulletType", mindustry.entities.bullet.ShrapnelBulletType.class);
classes.put("MultiEffect", mindustry.entities.effect.MultiEffect.class);
classes.put("ParticleEffect", mindustry.entities.effect.ParticleEffect.class);
classes.put("WaveEffect", mindustry.entities.effect.WaveEffect.class);
classes.put("Objectives", mindustry.game.Objectives.class);
classes.put("Objective", mindustry.game.Objectives.Objective.class);
classes.put("Produce", mindustry.game.Objectives.Produce.class);
classes.put("Research", mindustry.game.Objectives.Research.class);
classes.put("SectorComplete", mindustry.game.Objectives.SectorComplete.class);
classes.put("ParticleWeather", mindustry.type.weather.ParticleWeather.class);
classes.put("RainWeather", mindustry.type.weather.RainWeather.class);
classes.put("Attributes", mindustry.world.blocks.Attributes.class);
classes.put("Autotiler", mindustry.world.blocks.Autotiler.class);
classes.put("AutotilerHolder", mindustry.world.blocks.Autotiler.AutotilerHolder.class);
classes.put("SliceMode", mindustry.world.blocks.Autotiler.SliceMode.class);
classes.put("ConstructBlock", mindustry.world.blocks.ConstructBlock.class);
classes.put("ConstructBuild", mindustry.world.blocks.ConstructBlock.ConstructBuild.class);
classes.put("ControlBlock", mindustry.world.blocks.ControlBlock.class);
classes.put("ItemSelection", mindustry.world.blocks.ItemSelection.class);
classes.put("Accelerator", mindustry.world.blocks.campaign.Accelerator.class);
classes.put("AcceleratorBuild", mindustry.world.blocks.campaign.Accelerator.AcceleratorBuild.class);
classes.put("LaunchPad", mindustry.world.blocks.campaign.LaunchPad.class);
classes.put("LaunchPadBuild", mindustry.world.blocks.campaign.LaunchPad.LaunchPadBuild.class);
classes.put("Door", mindustry.world.blocks.defense.Door.class);
classes.put("DoorBuild", mindustry.world.blocks.defense.Door.DoorBuild.class);
classes.put("ForceProjector", mindustry.world.blocks.defense.ForceProjector.class);
classes.put("ForceBuild", mindustry.world.blocks.defense.ForceProjector.ForceBuild.class);
classes.put("MendProjector", mindustry.world.blocks.defense.MendProjector.class);
classes.put("MendBuild", mindustry.world.blocks.defense.MendProjector.MendBuild.class);
classes.put("OverdriveProjector", mindustry.world.blocks.defense.OverdriveProjector.class);
classes.put("OverdriveBuild", mindustry.world.blocks.defense.OverdriveProjector.OverdriveBuild.class);
classes.put("ShockMine", mindustry.world.blocks.defense.ShockMine.class);
classes.put("ShockMineBuild", mindustry.world.blocks.defense.ShockMine.ShockMineBuild.class);
classes.put("Thruster", mindustry.world.blocks.defense.Thruster.class);
classes.put("ThrusterBuild", mindustry.world.blocks.defense.Thruster.ThrusterBuild.class);
classes.put("Wall", mindustry.world.blocks.defense.Wall.class);
classes.put("WallBuild", mindustry.world.blocks.defense.Wall.WallBuild.class);
classes.put("BaseTurret", mindustry.world.blocks.defense.turrets.BaseTurret.class);
classes.put("BaseTurretBuild", mindustry.world.blocks.defense.turrets.BaseTurret.BaseTurretBuild.class);
classes.put("ItemTurret", mindustry.world.blocks.defense.turrets.ItemTurret.class);
classes.put("ItemTurretBuild", mindustry.world.blocks.defense.turrets.ItemTurret.ItemTurretBuild.class);
classes.put("LaserTurret", mindustry.world.blocks.defense.turrets.LaserTurret.class);
classes.put("LaserTurretBuild", mindustry.world.blocks.defense.turrets.LaserTurret.LaserTurretBuild.class);
classes.put("LiquidTurret", mindustry.world.blocks.defense.turrets.LiquidTurret.class);
classes.put("LiquidTurretBuild", mindustry.world.blocks.defense.turrets.LiquidTurret.LiquidTurretBuild.class);
classes.put("PointDefenseTurret", mindustry.world.blocks.defense.turrets.PointDefenseTurret.class);
classes.put("PointDefenseBuild", mindustry.world.blocks.defense.turrets.PointDefenseTurret.PointDefenseBuild.class);
classes.put("PowerTurret", mindustry.world.blocks.defense.turrets.PowerTurret.class);
classes.put("PowerTurretBuild", mindustry.world.blocks.defense.turrets.PowerTurret.PowerTurretBuild.class);
classes.put("ReloadTurret", mindustry.world.blocks.defense.turrets.ReloadTurret.class);
classes.put("ReloadTurretBuild", mindustry.world.blocks.defense.turrets.ReloadTurret.ReloadTurretBuild.class);
classes.put("TractorBeamTurret", mindustry.world.blocks.defense.turrets.TractorBeamTurret.class);
classes.put("TractorBeamBuild", mindustry.world.blocks.defense.turrets.TractorBeamTurret.TractorBeamBuild.class);
classes.put("Turret", mindustry.world.blocks.defense.turrets.Turret.class);
classes.put("AmmoEntry", mindustry.world.blocks.defense.turrets.Turret.AmmoEntry.class);
classes.put("TurretBuild", mindustry.world.blocks.defense.turrets.Turret.TurretBuild.class);
classes.put("ArmoredConveyor", mindustry.world.blocks.distribution.ArmoredConveyor.class);
classes.put("ArmoredConveyorBuild", mindustry.world.blocks.distribution.ArmoredConveyor.ArmoredConveyorBuild.class);
classes.put("BufferedItemBridge", mindustry.world.blocks.distribution.BufferedItemBridge.class);
classes.put("BufferedItemBridgeBuild", mindustry.world.blocks.distribution.BufferedItemBridge.BufferedItemBridgeBuild.class);
classes.put("ChainedBuilding", mindustry.world.blocks.distribution.ChainedBuilding.class);
classes.put("Conveyor", mindustry.world.blocks.distribution.Conveyor.class);
classes.put("ConveyorBuild", mindustry.world.blocks.distribution.Conveyor.ConveyorBuild.class);
classes.put("ExtendingItemBridge", mindustry.world.blocks.distribution.ExtendingItemBridge.class);
classes.put("ExtendingItemBridgeBuild", mindustry.world.blocks.distribution.ExtendingItemBridge.ExtendingItemBridgeBuild.class);
classes.put("ItemBridge", mindustry.world.blocks.distribution.ItemBridge.class);
classes.put("ItemBridgeBuild", mindustry.world.blocks.distribution.ItemBridge.ItemBridgeBuild.class);
classes.put("Junction", mindustry.world.blocks.distribution.Junction.class);
classes.put("JunctionBuild", mindustry.world.blocks.distribution.Junction.JunctionBuild.class);
classes.put("MassDriver", mindustry.world.blocks.distribution.MassDriver.class);
classes.put("DriverBulletData", mindustry.world.blocks.distribution.MassDriver.DriverBulletData.class);
classes.put("DriverState", mindustry.world.blocks.distribution.MassDriver.DriverState.class);
classes.put("MassDriverBuild", mindustry.world.blocks.distribution.MassDriver.MassDriverBuild.class);
classes.put("OverflowGate", mindustry.world.blocks.distribution.OverflowGate.class);
classes.put("OverflowGateBuild", mindustry.world.blocks.distribution.OverflowGate.OverflowGateBuild.class);
classes.put("PayloadConveyor", mindustry.world.blocks.distribution.PayloadConveyor.class);
classes.put("PayloadConveyorBuild", mindustry.world.blocks.distribution.PayloadConveyor.PayloadConveyorBuild.class);
classes.put("PayloadRouter", mindustry.world.blocks.distribution.PayloadRouter.class);
classes.put("PayloadRouterBuild", mindustry.world.blocks.distribution.PayloadRouter.PayloadRouterBuild.class);
classes.put("Router", mindustry.world.blocks.distribution.Router.class);
classes.put("RouterBuild", mindustry.world.blocks.distribution.Router.RouterBuild.class);
classes.put("Sorter", mindustry.world.blocks.distribution.Sorter.class);
classes.put("SorterBuild", mindustry.world.blocks.distribution.Sorter.SorterBuild.class);
classes.put("StackConveyor", mindustry.world.blocks.distribution.StackConveyor.class);
classes.put("StackConveyorBuild", mindustry.world.blocks.distribution.StackConveyor.StackConveyorBuild.class);
classes.put("AirBlock", mindustry.world.blocks.environment.AirBlock.class);
classes.put("Boulder", mindustry.world.blocks.environment.Boulder.class);
classes.put("Cliff", mindustry.world.blocks.environment.Cliff.class);
classes.put("DoubleOverlayFloor", mindustry.world.blocks.environment.DoubleOverlayFloor.class);
classes.put("Floor", mindustry.world.blocks.environment.Floor.class);
classes.put("OreBlock", mindustry.world.blocks.environment.OreBlock.class);
classes.put("OverlayFloor", mindustry.world.blocks.environment.OverlayFloor.class);
classes.put("ShallowLiquid", mindustry.world.blocks.environment.ShallowLiquid.class);
classes.put("SpawnBlock", mindustry.world.blocks.environment.SpawnBlock.class);
classes.put("StaticTree", mindustry.world.blocks.environment.StaticTree.class);
classes.put("StaticWall", mindustry.world.blocks.environment.StaticWall.class);
classes.put("TreeBlock", mindustry.world.blocks.environment.TreeBlock.class);
classes.put("BlockForge", mindustry.world.blocks.experimental.BlockForge.class);
classes.put("BlockForgeBuild", mindustry.world.blocks.experimental.BlockForge.BlockForgeBuild.class);
classes.put("BlockLoader", mindustry.world.blocks.experimental.BlockLoader.class);
classes.put("BlockLoaderBuild", mindustry.world.blocks.experimental.BlockLoader.BlockLoaderBuild.class);
classes.put("BlockUnloader", mindustry.world.blocks.experimental.BlockUnloader.class);
classes.put("BlockUnloaderBuild", mindustry.world.blocks.experimental.BlockUnloader.BlockUnloaderBuild.class);
classes.put("LegacyBlock", mindustry.world.blocks.legacy.LegacyBlock.class);
classes.put("LegacyMechPad", mindustry.world.blocks.legacy.LegacyMechPad.class);
classes.put("LegacyMechPadBuild", mindustry.world.blocks.legacy.LegacyMechPad.LegacyMechPadBuild.class);
classes.put("LegacyUnitFactory", mindustry.world.blocks.legacy.LegacyUnitFactory.class);
classes.put("LegacyUnitFactoryBuild", mindustry.world.blocks.legacy.LegacyUnitFactory.LegacyUnitFactoryBuild.class);
classes.put("ArmoredConduit", mindustry.world.blocks.liquid.ArmoredConduit.class);
classes.put("ArmoredConduitBuild", mindustry.world.blocks.liquid.ArmoredConduit.ArmoredConduitBuild.class);
classes.put("Conduit", mindustry.world.blocks.liquid.Conduit.class);
classes.put("ConduitBuild", mindustry.world.blocks.liquid.Conduit.ConduitBuild.class);
classes.put("LiquidBlock", mindustry.world.blocks.liquid.LiquidBlock.class);
classes.put("LiquidBuild", mindustry.world.blocks.liquid.LiquidBlock.LiquidBuild.class);
classes.put("LiquidBridge", mindustry.world.blocks.liquid.LiquidBridge.class);
classes.put("LiquidBridgeBuild", mindustry.world.blocks.liquid.LiquidBridge.LiquidBridgeBuild.class);
classes.put("LiquidExtendingBridge", mindustry.world.blocks.liquid.LiquidExtendingBridge.class);
classes.put("LiquidExtendingBridgeBuild", mindustry.world.blocks.liquid.LiquidExtendingBridge.LiquidExtendingBridgeBuild.class);
classes.put("LiquidJunction", mindustry.world.blocks.liquid.LiquidJunction.class);
classes.put("LiquidJunctionBuild", mindustry.world.blocks.liquid.LiquidJunction.LiquidJunctionBuild.class);
classes.put("LiquidRouter", mindustry.world.blocks.liquid.LiquidRouter.class);
classes.put("LiquidRouterBuild", mindustry.world.blocks.liquid.LiquidRouter.LiquidRouterBuild.class);
classes.put("LogicBlock", mindustry.world.blocks.logic.LogicBlock.class);
classes.put("LogicBuild", mindustry.world.blocks.logic.LogicBlock.LogicBuild.class);
classes.put("LogicLink", mindustry.world.blocks.logic.LogicBlock.LogicLink.class);
classes.put("LogicDisplay", mindustry.world.blocks.logic.LogicDisplay.class);
classes.put("GraphicsType", mindustry.world.blocks.logic.LogicDisplay.GraphicsType.class);
classes.put("LogicDisplayBuild", mindustry.world.blocks.logic.LogicDisplay.LogicDisplayBuild.class);
classes.put("MemoryBlock", mindustry.world.blocks.logic.MemoryBlock.class);
classes.put("MemoryBuild", mindustry.world.blocks.logic.MemoryBlock.MemoryBuild.class);
classes.put("MessageBlock", mindustry.world.blocks.logic.MessageBlock.class);
classes.put("MessageBuild", mindustry.world.blocks.logic.MessageBlock.MessageBuild.class);
classes.put("SwitchBlock", mindustry.world.blocks.logic.SwitchBlock.class);
classes.put("SwitchBuild", mindustry.world.blocks.logic.SwitchBlock.SwitchBuild.class);
classes.put("BuildPayload", mindustry.world.blocks.payloads.BuildPayload.class);
classes.put("Payload", mindustry.world.blocks.payloads.Payload.class);
classes.put("UnitPayload", mindustry.world.blocks.payloads.UnitPayload.class);
classes.put("Battery", mindustry.world.blocks.power.Battery.class);
classes.put("BatteryBuild", mindustry.world.blocks.power.Battery.BatteryBuild.class);
classes.put("BurnerGenerator", mindustry.world.blocks.power.BurnerGenerator.class);
classes.put("BurnerGeneratorBuild", mindustry.world.blocks.power.BurnerGenerator.BurnerGeneratorBuild.class);
classes.put("ConditionalConsumePower", mindustry.world.blocks.power.ConditionalConsumePower.class);
classes.put("DecayGenerator", mindustry.world.blocks.power.DecayGenerator.class);
classes.put("ImpactReactor", mindustry.world.blocks.power.ImpactReactor.class);
classes.put("ImpactReactorBuild", mindustry.world.blocks.power.ImpactReactor.ImpactReactorBuild.class);
classes.put("ItemLiquidGenerator", mindustry.world.blocks.power.ItemLiquidGenerator.class);
classes.put("ItemLiquidGeneratorBuild", mindustry.world.blocks.power.ItemLiquidGenerator.ItemLiquidGeneratorBuild.class);
classes.put("LightBlock", mindustry.world.blocks.power.LightBlock.class);
classes.put("LightBuild", mindustry.world.blocks.power.LightBlock.LightBuild.class);
classes.put("NuclearReactor", mindustry.world.blocks.power.NuclearReactor.class);
classes.put("NuclearReactorBuild", mindustry.world.blocks.power.NuclearReactor.NuclearReactorBuild.class);
classes.put("PowerBlock", mindustry.world.blocks.power.PowerBlock.class);
classes.put("PowerDiode", mindustry.world.blocks.power.PowerDiode.class);
classes.put("PowerDiodeBuild", mindustry.world.blocks.power.PowerDiode.PowerDiodeBuild.class);
classes.put("PowerDistributor", mindustry.world.blocks.power.PowerDistributor.class);
classes.put("PowerGenerator", mindustry.world.blocks.power.PowerGenerator.class);
classes.put("GeneratorBuild", mindustry.world.blocks.power.PowerGenerator.GeneratorBuild.class);
classes.put("PowerGraph", mindustry.world.blocks.power.PowerGraph.class);
classes.put("PowerNode", mindustry.world.blocks.power.PowerNode.class);
classes.put("PowerNodeBuild", mindustry.world.blocks.power.PowerNode.PowerNodeBuild.class);
classes.put("SingleTypeGenerator", mindustry.world.blocks.power.SingleTypeGenerator.class);
classes.put("SolarGenerator", mindustry.world.blocks.power.SolarGenerator.class);
classes.put("SolarGeneratorBuild", mindustry.world.blocks.power.SolarGenerator.SolarGeneratorBuild.class);
classes.put("ThermalGenerator", mindustry.world.blocks.power.ThermalGenerator.class);
classes.put("ThermalGeneratorBuild", mindustry.world.blocks.power.ThermalGenerator.ThermalGeneratorBuild.class);
classes.put("AttributeSmelter", mindustry.world.blocks.production.AttributeSmelter.class);
classes.put("AttributeSmelterBuild", mindustry.world.blocks.production.AttributeSmelter.AttributeSmelterBuild.class);
classes.put("Cultivator", mindustry.world.blocks.production.Cultivator.class);
classes.put("CultivatorBuild", mindustry.world.blocks.production.Cultivator.CultivatorBuild.class);
classes.put("Drill", mindustry.world.blocks.production.Drill.class);
classes.put("DrillBuild", mindustry.world.blocks.production.Drill.DrillBuild.class);
classes.put("Fracker", mindustry.world.blocks.production.Fracker.class);
classes.put("FrackerBuild", mindustry.world.blocks.production.Fracker.FrackerBuild.class);
classes.put("GenericCrafter", mindustry.world.blocks.production.GenericCrafter.class);
classes.put("GenericCrafterBuild", mindustry.world.blocks.production.GenericCrafter.GenericCrafterBuild.class);
classes.put("GenericSmelter", mindustry.world.blocks.production.GenericSmelter.class);
classes.put("SmelterBuild", mindustry.world.blocks.production.GenericSmelter.SmelterBuild.class);
classes.put("Incinerator", mindustry.world.blocks.production.Incinerator.class);
classes.put("IncineratorBuild", mindustry.world.blocks.production.Incinerator.IncineratorBuild.class);
classes.put("LiquidConverter", mindustry.world.blocks.production.LiquidConverter.class);
classes.put("LiquidConverterBuild", mindustry.world.blocks.production.LiquidConverter.LiquidConverterBuild.class);
classes.put("PayloadAcceptor", mindustry.world.blocks.production.PayloadAcceptor.class);
classes.put("PayloadAcceptorBuild", mindustry.world.blocks.production.PayloadAcceptor.PayloadAcceptorBuild.class);
classes.put("Pump", mindustry.world.blocks.production.Pump.class);
classes.put("PumpBuild", mindustry.world.blocks.production.Pump.PumpBuild.class);
classes.put("Separator", mindustry.world.blocks.production.Separator.class);
classes.put("SeparatorBuild", mindustry.world.blocks.production.Separator.SeparatorBuild.class);
classes.put("SolidPump", mindustry.world.blocks.production.SolidPump.class);
classes.put("SolidPumpBuild", mindustry.world.blocks.production.SolidPump.SolidPumpBuild.class);
classes.put("ItemSource", mindustry.world.blocks.sandbox.ItemSource.class);
classes.put("ItemSourceBuild", mindustry.world.blocks.sandbox.ItemSource.ItemSourceBuild.class);
classes.put("ItemVoid", mindustry.world.blocks.sandbox.ItemVoid.class);
classes.put("ItemVoidBuild", mindustry.world.blocks.sandbox.ItemVoid.ItemVoidBuild.class);
classes.put("LiquidSource", mindustry.world.blocks.sandbox.LiquidSource.class);
classes.put("LiquidSourceBuild", mindustry.world.blocks.sandbox.LiquidSource.LiquidSourceBuild.class);
classes.put("LiquidVoid", mindustry.world.blocks.sandbox.LiquidVoid.class);
classes.put("LiquidVoidBuild", mindustry.world.blocks.sandbox.LiquidVoid.LiquidVoidBuild.class);
classes.put("PowerSource", mindustry.world.blocks.sandbox.PowerSource.class);
classes.put("PowerSourceBuild", mindustry.world.blocks.sandbox.PowerSource.PowerSourceBuild.class);
classes.put("PowerVoid", mindustry.world.blocks.sandbox.PowerVoid.class);
classes.put("CoreBlock", mindustry.world.blocks.storage.CoreBlock.class);
classes.put("CoreBuild", mindustry.world.blocks.storage.CoreBlock.CoreBuild.class);
classes.put("StorageBlock", mindustry.world.blocks.storage.StorageBlock.class);
classes.put("StorageBuild", mindustry.world.blocks.storage.StorageBlock.StorageBuild.class);
classes.put("Unloader", mindustry.world.blocks.storage.Unloader.class);
classes.put("UnloaderBuild", mindustry.world.blocks.storage.Unloader.UnloaderBuild.class);
classes.put("CommandCenter", mindustry.world.blocks.units.CommandCenter.class);
classes.put("CommandBuild", mindustry.world.blocks.units.CommandCenter.CommandBuild.class);
classes.put("Reconstructor", mindustry.world.blocks.units.Reconstructor.class);
classes.put("ReconstructorBuild", mindustry.world.blocks.units.Reconstructor.ReconstructorBuild.class);
classes.put("RepairPoint", mindustry.world.blocks.units.RepairPoint.class);
classes.put("RepairPointBuild", mindustry.world.blocks.units.RepairPoint.RepairPointBuild.class);
classes.put("ResupplyPoint", mindustry.world.blocks.units.ResupplyPoint.class);
classes.put("ResupplyPointBuild", mindustry.world.blocks.units.ResupplyPoint.ResupplyPointBuild.class);
classes.put("UnitBlock", mindustry.world.blocks.units.UnitBlock.class);
classes.put("UnitBuild", mindustry.world.blocks.units.UnitBlock.UnitBuild.class);
classes.put("UnitFactory", mindustry.world.blocks.units.UnitFactory.class);
classes.put("UnitFactoryBuild", mindustry.world.blocks.units.UnitFactory.UnitFactoryBuild.class);
classes.put("UnitPlan", mindustry.world.blocks.units.UnitFactory.UnitPlan.class);
classes.put("DrawAnimation", mindustry.world.draw.DrawAnimation.class);
classes.put("DrawBlock", mindustry.world.draw.DrawBlock.class);
classes.put("DrawGlow", mindustry.world.draw.DrawGlow.class);
classes.put("DrawMixer", mindustry.world.draw.DrawMixer.class);
classes.put("DrawRotator", mindustry.world.draw.DrawRotator.class);
classes.put("DrawWeave", mindustry.world.draw.DrawWeave.class);
classes.put("Block", mindustry.world.Block.class);
}
}

View File

@ -15,10 +15,12 @@ import arc.util.serialization.*;
import arc.util.serialization.Json.*;
import arc.util.serialization.Jval.*;
import mindustry.*;
import mindustry.ai.types.*;
import mindustry.content.*;
import mindustry.content.TechTree.*;
import mindustry.ctype.*;
import mindustry.entities.*;
import mindustry.entities.abilities.*;
import mindustry.entities.bullet.*;
import mindustry.entities.effect.*;
import mindustry.game.*;
@ -26,6 +28,7 @@ import mindustry.game.Objectives.*;
import mindustry.gen.*;
import mindustry.mod.Mods.*;
import mindustry.type.*;
import mindustry.type.weather.*;
import mindustry.world.*;
import mindustry.world.blocks.units.*;
import mindustry.world.blocks.units.UnitFactory.*;
@ -42,14 +45,14 @@ public class ContentParser{
private static final boolean ignoreUnknownFields = true;
ObjectMap<Class<?>, ContentType> contentTypes = new ObjectMap<>();
ObjectSet<Class<?>> implicitNullable = ObjectSet.with(TextureRegion.class, TextureRegion[].class, TextureRegion[][].class);
ObjectMap<String, AssetDescriptor> sounds = new ObjectMap<>();
ObjectMap<String, AssetDescriptor<?>> sounds = new ObjectMap<>();
ObjectMap<Class<?>, FieldParser> classParsers = new ObjectMap<>(){{
put(Effect.class, (type, data) -> {
if(data.isString()){
return field(Fx.class, data);
}
Class<? extends Effect> bc = data.has("type") ? resolve(data.getString("type"), "mindustry.entities.effect") : ParticleEffect.class;
Class<? extends Effect> bc = resolve(data.getString("type", ""), ParticleEffect.class);
data.remove("type");
Effect result = make(bc);
readFields(result, data);
@ -83,12 +86,23 @@ public class ContentParser{
if(data.isString()){
return field(Bullets.class, data);
}
Class<? extends BulletType> bc = data.has("type") ? resolve(data.getString("type"), "mindustry.entities.bullet") : BasicBulletType.class;
var bc = resolve(data.getString("type", ""), BasicBulletType.class);
data.remove("type");
BulletType result = make(bc);
readFields(result, data);
return result;
});
put(DrawBlock.class, (type, data) -> {
if(data.isString()){
//try to instantiate
return make(resolve(data.asString()));
}
var bc = resolve(data.getString("type", ""), DrawBlock.class);
data.remove("type");
var result = make(bc);
readFields(result, data);
return result;
});
put(Sound.class, (type, data) -> {
if(fieldOpt(Sounds.class, data) != null) return fieldOpt(Sounds.class, data);
if(Vars.headless) return new Sound();
@ -104,12 +118,19 @@ public class ContentParser{
return sound;
});
put(Objectives.Objective.class, (type, data) -> {
Class<? extends Objectives.Objective> oc = data.has("type") ? resolve(data.getString("type"), "mindustry.game.Objectives") : SectorComplete.class;
var oc = resolve(data.getString("type", ""), SectorComplete.class);
data.remove("type");
Objectives.Objective obj = make(oc);
readFields(obj, data);
return obj;
});
put(Ability.class, (type, data) -> {
Class<? extends Ability> oc = resolve(data.getString("type", ""));
data.remove("type");
Ability obj = make(oc);
readFields(obj, data);
return obj;
});
put(Weapon.class, (type, data) -> {
Weapon weapon = new Weapon();
readFields(weapon, data);
@ -118,12 +139,13 @@ public class ContentParser{
});
}};
/** Stores things that need to be parsed fully, e.g. reading fields of content.
* This is done to accomodate binding of content names first.*/
* This is done to accommodate binding of content names first.*/
private Seq<Runnable> reads = new Seq<>();
private Seq<Runnable> postreads = new Seq<>();
private ObjectSet<Object> toBeParsed = new ObjectSet<>();
LoadedMod currentMod;
private Content currentContent;
Content currentContent;
private Json parser = new Json(){
@Override
@ -160,11 +182,6 @@ public class ContentParser{
}
}
//try to load DrawBlock by instantiating it
if(type == DrawBlock.class && jsonData.isString()){
return Reflect.make("mindustry.world.draw." + Strings.capitalize(jsonData.asString()));
}
if(Content.class.isAssignableFrom(type)){
ContentType ctype = contentTypes.getThrow(type, () -> new IllegalArgumentException("No content type for class: " + type.getSimpleName()));
String prefix = currentMod != null ? currentMod.name + "-" : "";
@ -194,30 +211,7 @@ public class ContentParser{
throw new IllegalArgumentException("When defining properties for an existing block, you must not re-declare its type. The original type will be used. Block: " + name);
}
}else{
//TODO generate dynamically instead of doing.. this
Class<? extends Block> type;
try{
type = resolve(getType(value),
"mindustry.world",
"mindustry.world.blocks",
"mindustry.world.blocks.defense",
"mindustry.world.blocks.defense.turrets",
"mindustry.world.blocks.distribution",
"mindustry.world.blocks.environment",
"mindustry.world.blocks.liquid",
"mindustry.world.blocks.logic",
"mindustry.world.blocks.power",
"mindustry.world.blocks.production",
"mindustry.world.blocks.sandbox",
"mindustry.world.blocks.storage",
"mindustry.world.blocks.units"
);
}catch(IllegalArgumentException e){
type = Block.class;
}
block = make(type, mod + "-" + name);
block = make(resolve(getType(value), Block.class), mod + "-" + name);
}
currentContent = block;
@ -225,22 +219,19 @@ public class ContentParser{
read(() -> {
if(value.has("consumes") && value.get("consumes").isObject()){
for(JsonValue child : value.get("consumes")){
if(child.name.equals("item")){
block.consumes.item(find(ContentType.item, child.asString()));
}else if(child.name.equals("items")){
block.consumes.add((Consume)parser.readValue(ConsumeItems.class, child));
}else if(child.name.equals("liquid")){
block.consumes.add((Consume)parser.readValue(ConsumeLiquid.class, child));
}else if(child.name.equals("power")){
if(child.isNumber()){
block.consumes.power(child.asFloat());
}else{
block.consumes.add((Consume)parser.readValue(ConsumePower.class, child));
switch(child.name){
case "item" -> block.consumes.item(find(ContentType.item, child.asString()));
case "items" -> block.consumes.add((Consume)parser.readValue(ConsumeItems.class, child));
case "liquid" -> block.consumes.add((Consume)parser.readValue(ConsumeLiquid.class, child));
case "power" -> {
if(child.isNumber()){
block.consumes.power(child.asFloat());
}else{
block.consumes.add((Consume)parser.readValue(ConsumePower.class, child));
}
}
}else if(child.name.equals("powerBuffered")){
block.consumes.powerBuffered(child.asFloat());
}else{
throw new IllegalArgumentException("Unknown consumption type: '" + child.name + "' for block '" + block.name + "'.");
case "powerBuffered" -> block.consumes.powerBuffered(child.asFloat());
default -> throw new IllegalArgumentException("Unknown consumption type: '" + child.name + "' for block '" + block.name + "'.");
}
}
value.remove("consumes");
@ -308,7 +299,7 @@ public class ContentParser{
}
if(value.has("controller")){
unit.defaultController = make(resolve(value.getString("controller"), "mindustry.ai.types"));
unit.defaultController = supply(resolve(value.getString("controller"), FlyingAI.class));
}
//read extra default waves
@ -334,8 +325,7 @@ public class ContentParser{
readBundle(ContentType.weather, name, value);
}else{
readBundle(ContentType.weather, name, value);
Class<? extends Weather> type = resolve(getType(value), "mindustry.type.weather");
item = make(type);
item = make(resolve(getType(value), ParticleWeather.class));
}
currentContent = item;
read(() -> readFields(item, value));
@ -624,8 +614,8 @@ public class ContentParser{
JsonValue research = jsonMap.remove("research");
toBeParsed.remove(object);
Class type = object.getClass();
ObjectMap<String, FieldMetadata> fields = parser.getFields(type);
var type = object.getClass();
var fields = parser.getFields(type);
for(JsonValue child = jsonMap.child; child != null; child = child.next){
FieldMetadata metadata = fields.get(child.name().replace(" ", "_"));
if(metadata == null){
@ -654,7 +644,6 @@ public class ContentParser{
}
}
if(object instanceof UnlockableContent unlock && research != null){
//add research tech node
@ -706,21 +695,34 @@ public class ContentParser{
}
}
/** Tries to resolve a class from a list of potential class names. */
<T> Class<T> resolve(String base, String... potentials){
/** Tries to resolve a class from the class type map. */
<T> Class<T> resolve(String base){
return resolve(base, null);
}
/** Tries to resolve a class from the class type map. */
<T> Class<T> resolve(String base, Class<T> def){
//no base class specified
if(base.isEmpty() && def != null) return def;
if(!base.isEmpty() && Character.isLowerCase(base.charAt(0))) base = Strings.capitalize(base);
for(String type : potentials){
//return mapped class if found in the global map
var out = ClassMap.classes.get(base);
if(out != null) return (Class<T>)out;
//try to resolve it as a raw class name if it's allowed
if(base.indexOf('.') != -1 && Scripts.allowClass(base)){
try{
return (Class<T>)Class.forName(type + '.' + base);
return (Class<T>)Class.forName(base);
}catch(Exception ignored){
try{
return (Class<T>)Class.forName(type + '$' + base);
}catch(Exception ignored2){
}
}
}
throw new IllegalArgumentException("Types not found: " + base + "." + potentials[0]);
if(def != null){
Log.warn("[@] No type '" + base + "' found, defaulting to type '" + def.getSimpleName() + "'", currentContent == null ? currentMod.name : "");
return def;
}
throw new IllegalArgumentException("Type not found: " + base);
}
private interface FieldParser{

View File

@ -21,20 +21,25 @@ import java.net.*;
import java.util.regex.*;
public class Scripts implements Disposable{
private final Seq<String> blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk",
private static final Seq<String> blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk",
"runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system",
".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org.");
private final Seq<String> whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.", "saveio", "systemcursor", "filetreeinitevent");
".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org.", "mod.classmap");
private static final Seq<String> whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.", "saveio", "systemcursor", "filetreeinitevent");
private final Context context;
private final Scriptable scope;
private boolean errored;
LoadedMod currentMod = null;
public static boolean allowClass(String type){
return !blacklist.contains(type.toLowerCase()::contains) || whitelist.contains(type.toLowerCase()::contains);
}
public Scripts(){
Time.mark();
context = Vars.platform.getScriptContext();
context.setClassShutter(type -> !blacklist.contains(type.toLowerCase()::contains) || whitelist.contains(type.toLowerCase()::contains));
context.setClassShutter(Scripts::allowClass);
context.getWrapFactory().setJavaPrimitiveWrap(false);
context.setLanguageVersion(Context.VERSION_ES6);

View File

@ -335,7 +335,11 @@ public class Block extends UnlockableContent{
super.setStats();
stats.add(Stat.size, "@x@", size, size);
stats.add(Stat.health, health, StatUnit.none);
if(synthetic()){
stats.add(Stat.health, health, StatUnit.none);
}
if(canBeBuilt()){
stats.add(Stat.buildTime, buildCost / 60, StatUnit.seconds);
stats.add(Stat.buildCost, new ItemListValue(false, requirements));

View File

@ -14,6 +14,7 @@ import mindustry.game.*;
import mindustry.gen.*;
import mindustry.io.*;
import mindustry.net.*;
import mindustry.world.*;
import java.io.*;
import java.lang.reflect.*;
@ -70,6 +71,40 @@ public class ScriptMainGenerator{
}
new Fi("core/assets/scripts/global.js").writeString(result.toString());
//map simple name to type
Seq<String> packages = Seq.with(
"mindustry.entities.effect",
"mindustry.entities.bullet",
"mindustry.ai.types",
"mindustry.type.weather",
"mindustry.game.Objectives",
"mindustry.world.blocks",
"mindustry.world.draw"
);
String classTemplate = "package mindustry.mod;\n" +
"\n" +
"import arc.struct.*;\n" +
"/** Generated class. Maps simple class names to concrete classes. For use in JSON mods. */\n" +
"public class ClassMap{\n" +
" public static final ObjectMap<String, Class<?>> classes = new ObjectMap<>();\n" +
" \n" +
" static{\n$CLASSES$" +
" }\n" +
"}\n";
StringBuilder cdef = new StringBuilder();
Seq<Class<?>> mapped = classes.select(c -> Modifier.isPublic(c.getModifiers()) && packages.contains(c.getCanonicalName()::startsWith))
.and(Block.class); //special case
for(Class<?> c : mapped){
cdef.append(" classes.put(\"").append(c.getSimpleName()).append("\", ").append(c.getCanonicalName()).append(".class);\n");
}
new Fi("core/src/mindustry/mod/ClassMap.java").writeString(classTemplate.replace("$CLASSES$", cdef.toString()));
Log.info("Generated @ class mappings.", mapped.size);
}
public static Seq<Class> getClasses(String packageName) throws Exception{
@ -103,7 +138,9 @@ public class ScriptMainGenerator{
String className = entry.getName().replace('/', '.');
className = className.substring(0, className.length() - ".class".length());
if(className.startsWith(packageName)){
classes.add(Class.forName(className, false, Thread.currentThread().getContextClassLoader()));
Class res = Class.forName(className, false, Thread.currentThread().getContextClassLoader());
classes.add(res);
//classes.addAll(res.getDeclaredClasses()); //????
}
}
}