Partial 7.0 merge - API preview

This commit is contained in:
Anuken
2021-06-02 11:08:08 -04:00
parent ea75a357ca
commit 28b235ef07
531 changed files with 12356 additions and 6286 deletions

View File

@@ -1,20 +1,26 @@
package mindustry.mod;
import arc.struct.*;
import mindustry.world.blocks.environment.*;
/** Generated class. Maps simple class names to concrete classes. For use in JSON mods. */
@SuppressWarnings("deprecation")
public class ClassMap{
public static final ObjectMap<String, Class<?>> classes = new ObjectMap<>();
static{
classes.put("BuilderAI", mindustry.ai.types.BuilderAI.class);
classes.put("DefenderAI", mindustry.ai.types.DefenderAI.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("HugAI", mindustry.ai.types.HugAI.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("Ability", mindustry.entities.abilities.Ability.class);
classes.put("EnergyFieldAbility", mindustry.entities.abilities.EnergyFieldAbility.class);
classes.put("ForceFieldAbility", mindustry.entities.abilities.ForceFieldAbility.class);
classes.put("MoveLightningAbility", mindustry.entities.abilities.MoveLightningAbility.class);
classes.put("RepairFieldAbility", mindustry.entities.abilities.RepairFieldAbility.class);
@@ -26,6 +32,7 @@ public class ClassMap{
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("EmpBulletType", mindustry.entities.bullet.EmpBulletType.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);
@@ -37,6 +44,7 @@ public class ClassMap{
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("ExplosionEffect", mindustry.entities.effect.ExplosionEffect.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);
@@ -45,8 +53,36 @@ public class ClassMap{
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("AmmoType", mindustry.type.AmmoType.class);
classes.put("AmmoTypes", mindustry.type.AmmoTypes.class);
classes.put("ItemAmmoType", mindustry.type.AmmoTypes.ItemAmmoType.class);
classes.put("PowerAmmoType", mindustry.type.AmmoTypes.PowerAmmoType.class);
classes.put("Category", mindustry.type.Category.class);
classes.put("ErrorContent", mindustry.type.ErrorContent.class);
classes.put("Item", mindustry.type.Item.class);
classes.put("ItemSeq", mindustry.type.ItemSeq.class);
classes.put("ItemStack", mindustry.type.ItemStack.class);
classes.put("Liquid", mindustry.type.Liquid.class);
classes.put("LiquidStack", mindustry.type.LiquidStack.class);
classes.put("Planet", mindustry.type.Planet.class);
classes.put("Publishable", mindustry.type.Publishable.class);
classes.put("Satellite", mindustry.type.Satellite.class);
classes.put("Sector", mindustry.type.Sector.class);
classes.put("SectorRect", mindustry.type.Sector.SectorRect.class);
classes.put("SectorPreset", mindustry.type.SectorPreset.class);
classes.put("StatusEffect", mindustry.type.StatusEffect.class);
classes.put("TransitionHandler", mindustry.type.StatusEffect.TransitionHandler.class);
classes.put("UnitType", mindustry.type.UnitType.class);
classes.put("Weapon", mindustry.type.Weapon.class);
classes.put("Weather", mindustry.type.Weather.class);
classes.put("WeatherEntry", mindustry.type.Weather.WeatherEntry.class);
classes.put("PointDefenseWeapon", mindustry.type.weapons.PointDefenseWeapon.class);
classes.put("RepairBeamWeapon", mindustry.type.weapons.RepairBeamWeapon.class);
classes.put("HealBeamMount", mindustry.type.weapons.RepairBeamWeapon.HealBeamMount.class);
classes.put("MagneticStorm", mindustry.type.weather.MagneticStorm.class);
classes.put("ParticleWeather", mindustry.type.weather.ParticleWeather.class);
classes.put("RainWeather", mindustry.type.weather.RainWeather.class);
classes.put("SolarFlare", mindustry.type.weather.SolarFlare.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);
@@ -59,6 +95,8 @@ public class ClassMap{
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("PayloadLaunchPad", mindustry.world.blocks.campaign.PayloadLaunchPad.class);
classes.put("PayloadLaunchPadBuild", mindustry.world.blocks.campaign.PayloadLaunchPad.PayloadLaunchPadBuild.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);
@@ -76,6 +114,7 @@ public class ClassMap{
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("ItemEntry", mindustry.world.blocks.defense.turrets.ItemTurret.ItemEntry.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);
@@ -99,6 +138,12 @@ public class ClassMap{
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("Duct", mindustry.world.blocks.distribution.Duct.class);
classes.put("DuctBuild", mindustry.world.blocks.distribution.Duct.DuctBuild.class);
classes.put("DuctBridge", mindustry.world.blocks.distribution.DuctBridge.class);
classes.put("DuctBridgeBuild", mindustry.world.blocks.distribution.DuctBridge.DuctBridgeBuild.class);
classes.put("DuctRouter", mindustry.world.blocks.distribution.DuctRouter.class);
classes.put("DuctBuild", mindustry.world.blocks.distribution.DuctRouter.DuctBuild.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);
@@ -122,19 +167,22 @@ public class ClassMap{
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("Prop", mindustry.world.blocks.environment.Prop.class);
classes.put("Bush", Bush.class);
classes.put("WavingProp", WavingProp.class);
classes.put("ShallowLiquid", mindustry.world.blocks.environment.ShallowLiquid.class);
classes.put("SpawnBlock", mindustry.world.blocks.environment.SpawnBlock.class);
classes.put("StaticClusterWall", StaticClusterWall.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("WallOreBlock", mindustry.world.blocks.environment.WallOreBlock.class);
classes.put("WobbleProp", mindustry.world.blocks.environment.WobbleProp.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);
@@ -170,8 +218,26 @@ public class ClassMap{
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("BallisticSilo", mindustry.world.blocks.payloads.BallisticSilo.class);
classes.put("BallisticSiloBuild", mindustry.world.blocks.payloads.BallisticSilo.BallisticSiloBuild.class);
classes.put("BlockForge", mindustry.world.blocks.payloads.BlockForge.class);
classes.put("BlockForgeBuild", mindustry.world.blocks.payloads.BlockForge.BlockForgeBuild.class);
classes.put("BlockProducer", mindustry.world.blocks.payloads.BlockProducer.class);
classes.put("BlockProducerBuild", mindustry.world.blocks.payloads.BlockProducer.BlockProducerBuild.class);
classes.put("BuildPayload", mindustry.world.blocks.payloads.BuildPayload.class);
classes.put("NuclearWarhead", mindustry.world.blocks.payloads.NuclearWarhead.class);
classes.put("NuclearWarheadBuild", mindustry.world.blocks.payloads.NuclearWarhead.NuclearWarheadBuild.class);
classes.put("Payload", mindustry.world.blocks.payloads.Payload.class);
classes.put("PayloadBlock", mindustry.world.blocks.payloads.PayloadBlock.class);
classes.put("PayloadBlockBuild", mindustry.world.blocks.payloads.PayloadBlock.PayloadBlockBuild.class);
classes.put("PayloadMassDriver", mindustry.world.blocks.payloads.PayloadMassDriver.class);
classes.put("PayloadDriverBuild", mindustry.world.blocks.payloads.PayloadMassDriver.PayloadDriverBuild.class);
classes.put("PayloadDriverState", mindustry.world.blocks.payloads.PayloadMassDriver.PayloadDriverState.class);
classes.put("PayloadMassDriverData", mindustry.world.blocks.payloads.PayloadMassDriver.PayloadMassDriverData.class);
classes.put("PayloadSource", mindustry.world.blocks.payloads.PayloadSource.class);
classes.put("PayloadSourceBuild", mindustry.world.blocks.payloads.PayloadSource.PayloadSourceBuild.class);
classes.put("PayloadVoid", mindustry.world.blocks.payloads.PayloadVoid.class);
classes.put("BlockLoaderBuild", mindustry.world.blocks.payloads.PayloadVoid.BlockLoaderBuild.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);
@@ -201,8 +267,12 @@ public class ClassMap{
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("AttributeCrafter", mindustry.world.blocks.production.AttributeCrafter.class);
classes.put("AttributeCrafterBuild", mindustry.world.blocks.production.AttributeCrafter.AttributeCrafterBuild.class);
classes.put("AttributeSmelter", mindustry.world.blocks.production.AttributeSmelter.class);
classes.put("AttributeSmelterBuild", mindustry.world.blocks.production.AttributeSmelter.AttributeSmelterBuild.class);
classes.put("BeamDrill", mindustry.world.blocks.production.BeamDrill.class);
classes.put("BeamDrillBuild", mindustry.world.blocks.production.BeamDrill.BeamDrillBuild.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);
@@ -223,6 +293,8 @@ public class ClassMap{
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("SingleBlockProducer", mindustry.world.blocks.production.SingleBlockProducer.class);
classes.put("SingleBlockProducerBuild", mindustry.world.blocks.production.SingleBlockProducer.SingleBlockProducerBuild.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);
@@ -256,10 +328,14 @@ public class ClassMap{
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("DrawArcSmelter", mindustry.world.draw.DrawArcSmelter.class);
classes.put("DrawBlock", mindustry.world.draw.DrawBlock.class);
classes.put("DrawCells", mindustry.world.draw.DrawCells.class);
classes.put("DrawCultivator", mindustry.world.draw.DrawCultivator.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("DrawSmelter", mindustry.world.draw.DrawSmelter.class);
classes.put("DrawWeave", mindustry.world.draw.DrawWeave.class);
classes.put("Block", mindustry.world.Block.class);
}

View File

@@ -26,6 +26,7 @@ import mindustry.entities.effect.*;
import mindustry.game.*;
import mindustry.game.Objectives.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.mod.Mods.*;
import mindustry.type.*;
import mindustry.type.weather.*;
@@ -59,6 +60,7 @@ public class ContentParser{
return result;
});
put(Interp.class, (type, data) -> field(Interp.class, data));
put(CacheLayer.class, (type, data) -> field(CacheLayer.class, data));
put(Schematic.class, (type, data) -> {
Object result = fieldOpt(Loadouts.class, data);
if(result != null){
@@ -132,7 +134,9 @@ public class ContentParser{
return obj;
});
put(Weapon.class, (type, data) -> {
Weapon weapon = new Weapon();
var oc = resolve(data.getString("type", ""), Weapon.class);
data.remove("type");
var weapon = make(oc);
readFields(weapon, data);
weapon.name = currentMod.name + "-" + weapon.name;
return weapon;
@@ -325,8 +329,17 @@ public class ContentParser{
return item;
},
ContentType.item, parser(ContentType.item, Item::new),
ContentType.liquid, parser(ContentType.liquid, Liquid::new)
//ContentType.sector, parser(ContentType.sector, SectorPreset::new)
ContentType.liquid, parser(ContentType.liquid, Liquid::new),
ContentType.status, parser(ContentType.status, StatusEffect::new),
ContentType.sector, (TypeParser<SectorPreset>)(mod, name, value) -> {
if(value.isString()){
return locate(ContentType.sector, name);
}
if(!value.has("sector") || !value.get("sector").isNumber()) throw new RuntimeException("SectorPresets must have a sector number.");
return new SectorPreset(name, locate(ContentType.planet, value.getString("planet", "serpulo")), value.getInt("sector"));
}
);
private Prov<Unit> unitType(JsonValue value){
@@ -714,14 +727,10 @@ public class ContentParser{
try{
return (Class<T>)Class.forName(base);
}catch(Exception ignored){
//try to load from a mod's class loader
for(LoadedMod mod : mods.mods){
if(mod.loader != null){
try{
return (Class<T>)Class.forName(base, true, mod.loader);
}catch(Exception ignore){}
}
}
//try to use mod class loader
try{
return (Class<T>)Class.forName(base, true, mods.mainLoader());
}catch(Exception ignore){}
}
}

View File

@@ -0,0 +1,35 @@
package mindustry.mod;
import arc.struct.*;
public class ModClassLoader extends ClassLoader{
private Seq<ClassLoader> children = new Seq<>();
private volatile boolean inChild = false;
public void addChild(ClassLoader child){
children.add(child);
}
@Override
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{
//always try the superclass first
try{
return super.loadClass(name, resolve);
}catch(ClassNotFoundException error){
//a child may try to delegate class loading to its parent, which is *this class loader* - do not let that happen
if(inChild) throw error;
int size = children.size;
//if it doesn't exist in the main class loader, try all the children
for(int i = 0; i < size; i++){
try{
inChild = true;
var out = children.get(i).loadClass(name);
inChild = false;
return out;
}catch(ClassNotFoundException ignored){
}
}
throw error;
}
}
}

View File

@@ -11,6 +11,7 @@ import arc.graphics.g2d.TextureAtlas.*;
import arc.scene.ui.*;
import arc.struct.*;
import arc.util.*;
import arc.util.async.*;
import arc.util.io.*;
import arc.util.serialization.*;
import arc.util.serialization.Jval.*;
@@ -29,6 +30,7 @@ import java.util.*;
import static mindustry.Vars.*;
public class Mods implements Loadable{
private AsyncExecutor async = new AsyncExecutor();
private Json json = new Json();
private @Nullable Scripts scripts;
private ContentParser parser = new ContentParser();
@@ -37,15 +39,21 @@ public class Mods implements Loadable{
private int totalSprites;
private MultiPacker packer;
private ModClassLoader mainLoader = new ModClassLoader();
Seq<LoadedMod> mods = new Seq<>();
private ObjectMap<Class<?>, ModMeta> metas = new ObjectMap<>();
private boolean requiresReload, createdAtlas;
private boolean requiresReload;
public Mods(){
Events.on(ClientLoadEvent.class, e -> Core.app.post(this::checkWarnings));
}
/** @return the main class loader for all mods */
public ClassLoader mainLoader(){
return mainLoader;
}
/** Returns a file named 'config.json' in a special folder for the specified plugin.
* Call this in init(). */
public Fi getConfig(Mod mod){
@@ -97,9 +105,7 @@ public class Mods implements Loadable{
Core.settings.put("mod-" + loaded.name + "-enabled", true);
sortMods();
//try to load the mod's icon so it displays on import
Core.app.post(() -> {
loadIcon(loaded);
});
Core.app.post(() -> loadIcon(loaded));
return loaded;
}catch(IOException e){
dest.delete();
@@ -117,16 +123,37 @@ public class Mods implements Loadable{
Time.mark();
packer = new MultiPacker();
//all packing tasks to await
var tasks = new Seq<AsyncResult<Runnable>>();
eachEnabled(mod -> {
Seq<Fi> sprites = mod.root.child("sprites").findAll(f -> f.extension().equals("png"));
Seq<Fi> overrides = mod.root.child("sprites-override").findAll(f -> f.extension().equals("png"));
packSprites(sprites, mod, true);
packSprites(overrides, mod, false);
packSprites(sprites, mod, true, tasks);
packSprites(overrides, mod, false, tasks);
Log.debug("Packed @ images for mod '@'.", sprites.size + overrides.size, mod.meta.name);
totalSprites += sprites.size + overrides.size;
});
for(var result : tasks){
try{
var packRun = result.get();
if(packRun != null){ //can be null for very strange reasons, ignore if that's the case
try{
//actually pack the image
packRun.run();
}catch(Exception e){ //the image can fail to fit in the spritesheet
Log.err("Failed to fit image into the spritesheet, skipping.");
Log.err(e);
}
}
}catch(Exception e){ //this means loading the image failed, log it and move on
Log.err(e);
}
}
Log.debug("Time to pack textures: @", Time.elapsed());
}
@@ -148,23 +175,29 @@ public class Mods implements Loadable{
}
}
private void packSprites(Seq<Fi> sprites, LoadedMod mod, boolean prefix){
private void packSprites(Seq<Fi> sprites, LoadedMod mod, boolean prefix, Seq<AsyncResult<Runnable>> tasks){
boolean linear = Core.settings.getBool("linear");
for(Fi file : sprites){
try(InputStream stream = file.read()){
byte[] bytes = Streams.copyBytes(stream, Math.max((int)file.length(), 512));
Pixmap pixmap = new Pixmap(bytes, 0, bytes.length);
packer.add(getPage(file), (prefix ? mod.name + "-" : "") + file.nameWithoutExtension(), new PixmapRegion(pixmap));
pixmap.dispose();
}catch(IOException e){
Core.app.post(() -> {
Log.err("Error packing images for mod: @", mod.meta.name);
Log.err(e);
if(!headless) ui.showException(e);
});
break;
}
//read and bleed pixmaps in parallel
tasks.add(async.submit(() -> {
try{
Pixmap pix = new Pixmap(file.readBytes());
//only bleeds when linear filtering is on at startup
if(linear){
Pixmaps.bleed(pix);
}
//this returns a *runnable* which actually packs the resulting pixmap; this has to be done synchronously outside the method
return () -> {
packer.add(getPage(file), (prefix ? mod.name + "-" : "") + file.nameWithoutExtension(), new PixmapRegion(pix));
pix.dispose();
};
}catch(Exception e){
//rethrow exception with details about the cause of failure
throw new Exception("Failed to load image " + file + " for mod " + mod.name, e);
}
}));
}
totalSprites += sprites.size;
}
@Override
@@ -176,32 +209,77 @@ public class Mods implements Loadable{
//get textures packed
if(totalSprites > 0){
if(!createdAtlas) Core.atlas = new TextureAtlas(Core.files.internal("sprites/sprites.atlas"));
createdAtlas = true;
for(AtlasRegion region : Core.atlas.getRegions()){
//TODO PageType completely breaks down with multiple pages.
PageType type = getPage(region);
if(!packer.has(type, region.name)){
packer.add(type, region.name, Core.atlas.getPixmap(region));
packer.add(type, region.name, Core.atlas.getPixmap(region), region.splits, region.pads);
}
}
TextureFilter filter = Core.settings.getBool("linear") ? TextureFilter.linear : TextureFilter.nearest;
Core.atlas.dispose();
//flush so generators can use these sprites
packer.flush(filter, Core.atlas);
//dead shadow-atlas for getting regions, but not pixmaps
var shadow = Core.atlas;
//dummy texture atlas that returns the 'shadow' regions; used for mod loading
Core.atlas = new TextureAtlas(){
@Override
public AtlasRegion find(String name){
var base = packer.get(name);
if(base != null){
var reg = new AtlasRegion(shadow.find(name).texture, base.x, base.y, base.width, base.height);
reg.name = name;
reg.pixmapRegion = base;
return reg;
}
return shadow.find(name);
}
@Override
public boolean isFound(TextureRegion region){
return region != shadow.find("error");
}
@Override
public TextureRegion find(String name, TextureRegion def){
return !has(name) ? def : find(name);
}
@Override
public boolean has(String s){
return shadow.has(s) || packer.get(s) != null;
}
//return the *actual* pixmap regions, not the disposed ones.
@Override
public PixmapRegion getPixmap(AtlasRegion region){
PixmapRegion out = packer.get(region.name);
//this should not happen in normal situations
if(out == null) return packer.get("error");
return out;
}
};
TextureFilter filter = Core.settings.getBool("linear") ? TextureFilter.linear : TextureFilter.nearest;
//generate new icons
for(Seq<Content> arr : content.getContentMap()){
arr.each(c -> {
if(c instanceof UnlockableContent u && c.minfo.mod != null){
u.load();
u.loadIcon();
u.createIcons(packer);
}
});
}
//dispose old atlas data
Core.atlas = packer.flush(filter, new TextureAtlas());
Core.atlas.setErrorRegion("error");
Log.debug("Total pages: @", Core.atlas.getTextures().size);
}
@@ -217,6 +295,7 @@ public class Mods implements Loadable{
region.texture == Core.atlas.find("stone1").texture ? PageType.environment :
region.texture == Core.atlas.find("clear-editor").texture ? PageType.editor :
region.texture == Core.atlas.find("whiteui").texture ? PageType.ui :
region.texture == Core.atlas.find("rubble-1-0").texture ? PageType.rubble :
PageType.main;
}
@@ -225,6 +304,7 @@ public class Mods implements Loadable{
return
parent.equals("environment") ? PageType.environment :
parent.equals("editor") ? PageType.editor :
parent.equals("rubble") ? PageType.editor :
parent.equals("ui") || file.parent().parent().name().equals("ui") ? PageType.ui :
PageType.main;
}
@@ -696,12 +776,12 @@ public class Mods implements Loadable{
Version.isAtLeast(meta.minGameVersion) &&
(meta.getMinMajor() >= 105 || headless)
){
if(ios){
throw new IllegalArgumentException("Java class mods are not supported on iOS.");
}
loader = platform.loadJar(sourceFile, mainClass);
loader = platform.loadJar(sourceFile, mainLoader);
mainLoader.addChild(loader);
Class<?> main = Class.forName(mainClass, true, loader);
metas.put(main, meta);
mainMod = (Mod)main.getDeclaredConstructor().newInstance();

View File

@@ -25,12 +25,13 @@ public class Scripts implements Disposable{
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.", "mod.classmap");
private static final Seq<String> whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "jdk.proxy1", "mindustry.gen.",
"mindustry.logic.", "mindustry.async.", "saveio", "systemcursor", "filetreeinitevent");
private static final Seq<String> whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "jdk.proxy", "mindustry.gen.",
"mindustry.logic.", "mindustry.async.", "saveio", "systemcursor", "filetreeinitevent", "asyncexecutor");
private final Context context;
private final Scriptable scope;
private boolean errored;
LoadedMod currentMod = null;
public static boolean allowClass(String type){
@@ -41,10 +42,6 @@ public class Scripts implements Disposable{
Time.mark();
context = Vars.platform.getScriptContext();
context.setClassShutter(Scripts::allowClass);
context.getWrapFactory().setJavaPrimitiveWrap(false);
context.setLanguageVersion(Context.VERSION_ES6);
scope = new ImporterTopLevel(context);
new RequireBuilder()