mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-01-27 23:11:12 -08:00
Better JSON null validation / Disable mods on startup crash
This commit is contained in:
parent
b46a5c0bda
commit
fa7697fc40
12 changed files with 93 additions and 16 deletions
|
|
@ -113,7 +113,7 @@ committingchanges = Committing Changes
|
|||
done = Done
|
||||
feature.unsupported = Your device does not support this feature.
|
||||
|
||||
mods.alphainfo = Keep in mind that mods are in alpha, and[scarlet] may be very buggy[].\nReport any issues you find to the Mindustry GitHub.
|
||||
mods.initfailed = [red]⚠[] The previous Mindustry instance failed to initialize. This was likely caused by misbehaving mods.\n\nTo prevent a crash loop, [red]all mods have been disabled.[]\n\nTo disable this feature, turn it off in [accent]Settings->Game->Disable Mods On Startup Crash[].
|
||||
mods = Mods
|
||||
mods.none = [lightgray]No mods found!
|
||||
mods.guide = Modding Guide
|
||||
|
|
@ -800,6 +800,7 @@ setting.logichints.name = Logic Hints
|
|||
setting.flow.name = Display Resource Flow Rate
|
||||
setting.backgroundpause.name = Pause In Background
|
||||
setting.buildautopause.name = Auto-Pause Building
|
||||
setting.modcrashdisable = Disable Mods On Startup Crash
|
||||
setting.animatedwater.name = Animated Surfaces
|
||||
setting.animatedshields.name = Animated Shields
|
||||
setting.antialias.name = Antialias[lightgray] (requires restart)[]
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
|||
|
||||
@Override
|
||||
public void setup(){
|
||||
checkLaunch();
|
||||
loadLogger();
|
||||
|
||||
loader = new LoadRenderer();
|
||||
|
|
@ -145,7 +146,12 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
|||
finished = true;
|
||||
Events.fire(new ClientLoadEvent());
|
||||
super.resize(graphics.getWidth(), graphics.getHeight());
|
||||
app.post(() -> app.post(() -> app.post(() -> app.post(() -> super.resize(graphics.getWidth(), graphics.getHeight())))));
|
||||
app.post(() -> app.post(() -> app.post(() -> app.post(() -> {
|
||||
super.resize(graphics.getWidth(), graphics.getHeight());
|
||||
|
||||
//mark initialization as complete
|
||||
finishLaunch();
|
||||
}))));
|
||||
}
|
||||
}else{
|
||||
asyncCore.begin();
|
||||
|
|
@ -168,6 +174,12 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
|||
lastTime = Time.nanos();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit(){
|
||||
//on graceful exit, finish the launch normally.
|
||||
Vars.finishLaunch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(){
|
||||
setup();
|
||||
|
|
@ -182,6 +194,11 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform
|
|||
|
||||
@Override
|
||||
public void pause(){
|
||||
//when the user tabs out on mobile, the exit() event doesn't fire reliably - in that case, just assume they're about to kill the app
|
||||
//this isn't 100% reliable but it should work for most cases
|
||||
if(mobile){
|
||||
Vars.finishLaunch();
|
||||
}
|
||||
if(finished){
|
||||
super.pause();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ import java.util.*;
|
|||
import static arc.Core.*;
|
||||
|
||||
public class Vars implements Loadable{
|
||||
/** Whether the game failed to launch last time. */
|
||||
public static boolean failedToLaunch = false;
|
||||
/** Whether to load locales.*/
|
||||
public static boolean loadLocales = true;
|
||||
/** Whether the logger is loaded. */
|
||||
|
|
@ -172,6 +174,8 @@ public class Vars implements Loadable{
|
|||
public static Fi schematicDirectory;
|
||||
/** data subdirectory used for bleeding edge build versions */
|
||||
public static Fi bebuildDirectory;
|
||||
/** file used to store launch ID */
|
||||
public static Fi launchIDFile;
|
||||
/** empty map, indicates no current map */
|
||||
public static Map emptyMap;
|
||||
/** map file extension */
|
||||
|
|
@ -284,6 +288,27 @@ public class Vars implements Loadable{
|
|||
maps.load();
|
||||
}
|
||||
|
||||
/** Checks if a launch failure occurred.
|
||||
* If this is the case, failedToLaunch is set to true. */
|
||||
public static void checkLaunch(){
|
||||
settings.setAppName(appName);
|
||||
launchIDFile = settings.getDataDirectory().child("launchid.dat");
|
||||
|
||||
if(launchIDFile.exists()){
|
||||
failedToLaunch = true;
|
||||
}else{
|
||||
failedToLaunch = false;
|
||||
launchIDFile.writeString("go away");
|
||||
}
|
||||
}
|
||||
|
||||
/** Cleans up after a successful launch. */
|
||||
public static void finishLaunch(){
|
||||
if(launchIDFile != null){
|
||||
launchIDFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadLogger(){
|
||||
if(loadedLogger) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,15 @@ public class Control implements ApplicationListener, Loadable{
|
|||
saves = new Saves();
|
||||
sound = new SoundControl();
|
||||
|
||||
//show dialog saying that mod loading was skipped.
|
||||
Events.on(ClientLoadEvent.class, e -> {
|
||||
if(Vars.mods.skipModLoading() && Vars.mods.list().any()){
|
||||
Time.runTask(4f, () -> {
|
||||
ui.showInfo("@mods.initfailed");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(StateChangeEvent.class, event -> {
|
||||
if((event.from == State.playing && event.to == State.menu) || (event.from == State.menu && event.to != State.menu)){
|
||||
Time.runTask(5f, platform::updateRPC);
|
||||
|
|
|
|||
|
|
@ -406,6 +406,12 @@ public class ContentParser{
|
|||
this.currentMod = mod;
|
||||
this.currentContent = cont;
|
||||
run.run();
|
||||
|
||||
//check nulls after parsing
|
||||
if(cont != null){
|
||||
toBeParsed.remove(cont);
|
||||
checkNullFields(cont);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -259,6 +259,11 @@ public class Mods implements Loadable{
|
|||
return requiresReload;
|
||||
}
|
||||
|
||||
/** @return whether to skip mod loading due to previous initialization failure. */
|
||||
public boolean skipModLoading(){
|
||||
return failedToLaunch && Core.settings.getBool("modcrashdisable", true);
|
||||
}
|
||||
|
||||
/** Loads all mods from the folder, but does not call any methods on them.*/
|
||||
public void load(){
|
||||
for(Fi file : modDirectory.list()){
|
||||
|
|
@ -683,8 +688,13 @@ public class Mods implements Loadable{
|
|||
|
||||
//make sure the main class exists before loading it; if it doesn't just don't put it there
|
||||
//if the mod is explicitly marked as java, try loading it anyway
|
||||
if((mainFile.exists() || meta.java) &&
|
||||
Core.settings.getBool("mod-" + baseName + "-enabled", true) && Version.isAtLeast(meta.minGameVersion) && (meta.getMinMajor() >= 105 || headless)){
|
||||
if(
|
||||
(mainFile.exists() || meta.java) &&
|
||||
!skipModLoading() &&
|
||||
Core.settings.getBool("mod-" + baseName + "-enabled", true) &&
|
||||
Version.isAtLeast(meta.minGameVersion) &&
|
||||
(meta.getMinMajor() >= 105 || headless)
|
||||
){
|
||||
|
||||
if(ios){
|
||||
throw new IllegalArgumentException("Java class mods are not supported on iOS.");
|
||||
|
|
@ -711,11 +721,16 @@ public class Mods implements Loadable{
|
|||
}
|
||||
}
|
||||
|
||||
//skip mod loading if it failed
|
||||
if(skipModLoading()){
|
||||
Core.settings.put("mod-" + baseName + "-enabled", false);
|
||||
}
|
||||
|
||||
if(!headless){
|
||||
Log.info("Loaded mod '@' in @ms", meta.name, Time.elapsed());
|
||||
}
|
||||
return new LoadedMod(sourceFile, zip, mainMod, loader, meta);
|
||||
|
||||
return new LoadedMod(sourceFile, zip, mainMod, loader, meta);
|
||||
}catch(Exception e){
|
||||
//delete root zip file so it can be closed on windows
|
||||
if(rootZip != null) rootZip.delete();
|
||||
|
|
|
|||
|
|
@ -106,11 +106,6 @@ public class ModsDialog extends BaseDialog{
|
|||
}
|
||||
});
|
||||
|
||||
shown(() -> Core.app.post(() -> {
|
||||
Core.settings.getBoolOnce("modsalpha", () -> {
|
||||
ui.showText("@mods", "@mods.alphainfo");
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
void modError(Throwable error){
|
||||
|
|
|
|||
|
|
@ -327,6 +327,10 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||
game.checkPref("buildautopause", false);
|
||||
}
|
||||
|
||||
if(!ios){
|
||||
game.checkPref("modcrashdisable", true);
|
||||
}
|
||||
|
||||
if(steam){
|
||||
game.sliderPref("playerlimit", 16, 2, 32, i -> {
|
||||
platform.updateLobby();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
package mindustry.world.blocks.environment;
|
||||
|
||||
import arc.util.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
//do not use in mods!
|
||||
/**
|
||||
* Do not use in mods. This class provides no new functionality, and is only used for the Mindustry sprite generator.
|
||||
* Use the standard Floor class instead.
|
||||
* */
|
||||
public class ShallowLiquid extends Floor{
|
||||
public Floor liquidBase, floorBase;
|
||||
public @Nullable Floor liquidBase, floorBase;
|
||||
public float liquidOpacity = 0.35f;
|
||||
|
||||
public ShallowLiquid(String name){
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ public class Drill extends Block{
|
|||
public float warmupSpeed = 0.02f;
|
||||
|
||||
//return variables for countOre
|
||||
protected Item returnItem;
|
||||
protected @Nullable Item returnItem;
|
||||
protected int returnCount;
|
||||
|
||||
/** Whether to draw the item this drill is mining. */
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package mindustry.world.blocks.production;
|
|||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.*;
|
||||
|
|
@ -13,8 +14,8 @@ import mindustry.world.draw.*;
|
|||
import mindustry.world.meta.*;
|
||||
|
||||
public class GenericCrafter extends Block{
|
||||
public ItemStack outputItem;
|
||||
public LiquidStack outputLiquid;
|
||||
public @Nullable ItemStack outputItem;
|
||||
public @Nullable LiquidStack outputLiquid;
|
||||
|
||||
public float craftTime = 80;
|
||||
public Effect craftEffect = Fx.none;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
org.gradle.daemon=true
|
||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||
archash=e402c9743e107fb53ed6f069ae72a19a59fbfd3b
|
||||
archash=f6caa903fd34c016a902b70c4d41690f5f022431
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue