Mod reloading that works for some ridiculous reason?

This commit is contained in:
Anuken
2019-10-02 23:09:35 -04:00
parent 89db08f4ed
commit 532926a9e3
7 changed files with 99 additions and 16 deletions

View File

@@ -72,6 +72,8 @@ mods = Mods
mods.none = [LIGHT_GRAY]No mods found! mods.none = [LIGHT_GRAY]No mods found!
mod.enabled = [lightgray]Enabled mod.enabled = [lightgray]Enabled
mod.disabled = [scarlet]Disabled mod.disabled = [scarlet]Disabled
mod.disable = Disable
mod.enable = Enable
mod.requiresrestart = The game will now close to apply the mod changes. mod.requiresrestart = The game will now close to apply the mod changes.
mod.import = Import Mod mod.import = Import Mod
mod.remove.confirm = This mod will be deleted. mod.remove.confirm = This mod will be deleted.
@@ -210,6 +212,7 @@ classic.export.text = [accent]Mindustry[] has just had a major update.\nClassic
quit.confirm = Are you sure you want to quit? quit.confirm = Are you sure you want to quit?
quit.confirm.tutorial = Are you sure you know what you're doing?\nThe tutorial can be re-taken in[accent] Settings->Game->Re-Take Tutorial.[] quit.confirm.tutorial = Are you sure you know what you're doing?\nThe tutorial can be re-taken in[accent] Settings->Game->Re-Take Tutorial.[]
loading = [accent]Loading... loading = [accent]Loading...
reloading = [accent]Reloading Mods...
saving = [accent]Saving... saving = [accent]Saving...
wave = [accent]Wave {0} wave = [accent]Wave {0}
wave.waiting = [lightgray]Wave in {0} wave.waiting = [lightgray]Wave in {0}

View File

@@ -42,6 +42,14 @@ public class ContentLoader{
new LegacyColorMapper(), new LegacyColorMapper(),
}; };
/** Clears all initialized content.*/
public void clear(){
contentNameMap = new ObjectMap[ContentType.values().length];
contentMap = new Array[ContentType.values().length];
initialization = new ObjectSet<>();
loaded = false;
}
/** Creates all content types. */ /** Creates all content types. */
public void createContent(){ public void createContent(){
if(loaded){ if(loaded){

View File

@@ -22,6 +22,11 @@ public class FileTree implements FileHandleResolver{
} }
} }
/** Clears all mod files.*/
public void clear(){
files.clear();
}
@Override @Override
public FileHandle resolve(String fileName){ public FileHandle resolve(String fileName){
return get(fileName); return get(fileName);

View File

@@ -83,6 +83,10 @@ public class EventType{
} }
public static class ContentReloadEvent{
}
public static class DisposeEvent{ public static class DisposeEvent{
} }

View File

@@ -15,8 +15,10 @@ import io.anuke.arc.util.*;
import io.anuke.arc.util.io.*; import io.anuke.arc.util.io.*;
import io.anuke.arc.util.serialization.*; import io.anuke.arc.util.serialization.*;
import io.anuke.mindustry.game.*; import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.plugin.*; import io.anuke.mindustry.plugin.*;
import io.anuke.mindustry.type.*; import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.*;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
@@ -33,8 +35,9 @@ public class Mods implements Loadable{
private PixmapPacker packer; private PixmapPacker packer;
private Array<LoadedMod> loaded = new Array<>(); private Array<LoadedMod> loaded = new Array<>();
private Array<LoadedMod> disabled = new Array<>();
private ObjectMap<Class<?>, ModMeta> metas = new ObjectMap<>(); private ObjectMap<Class<?>, ModMeta> metas = new ObjectMap<>();
private boolean requiresRestart; private boolean requiresReload;
/** Returns a file named 'config.json' in a special folder for the specified plugin. /** Returns a file named 'config.json' in a special folder for the specified plugin.
* Call this in init(). */ * Call this in init(). */
@@ -60,7 +63,7 @@ public class Mods implements Loadable{
file.copyTo(dest); file.copyTo(dest);
try{ try{
loaded.add(loadMod(file)); loaded.add(loadMod(file));
requiresRestart = true; requiresReload = true;
}catch(IOException e){ }catch(IOException e){
dest.delete(); dest.delete();
throw e; throw e;
@@ -137,6 +140,7 @@ public class Mods implements Loadable{
} }
packer.dispose(); packer.dispose();
packer = null;
} }
/** Removes a mod file and marks it for requiring a restart. */ /** Removes a mod file and marks it for requiring a restart. */
@@ -147,11 +151,11 @@ public class Mods implements Loadable{
mod.file.delete(); mod.file.delete();
} }
loaded.remove(mod); loaded.remove(mod);
requiresRestart = true; requiresReload = true;
} }
public boolean requiresRestart(){ public boolean requiresReload(){
return requiresRestart; return requiresReload;
} }
/** Loads all mods from the folder, but does call any methods on them.*/ /** Loads all mods from the folder, but does call any methods on them.*/
@@ -160,7 +164,12 @@ public class Mods implements Loadable{
if(!file.extension().equals("jar") && !file.extension().equals("zip") && !(file.isDirectory() && file.child("mod.json").exists())) continue; if(!file.extension().equals("jar") && !file.extension().equals("zip") && !(file.isDirectory() && file.child("mod.json").exists())) continue;
try{ try{
loaded.add(loadMod(file)); LoadedMod mod = loadMod(file);
if(mod.enabled()){
loaded.add(mod);
}else{
disabled.add(mod);
}
}catch(IllegalArgumentException ignored){ }catch(IllegalArgumentException ignored){
}catch(Exception e){ }catch(Exception e){
Log.err("Failed to load plugin file {0}. Skipping.", file); Log.err("Failed to load plugin file {0}. Skipping.", file);
@@ -212,6 +221,23 @@ public class Mods implements Loadable{
} }
} }
/** Reloads all mod content.*/
public void reloadContent(){
//epic memory leak
Core.atlas = new TextureAtlas(Core.files.internal("sprites/sprites.atlas"));
Tex.load();
Tex.loadStyles();
Styles.load();
content.clear();
content.createContent();
loadAsync();
loadSync();
buildFiles();
content.init();
content.load();
content.loadColors();
}
/** Creates all the content found in mod files. */ /** Creates all the content found in mod files. */
public void loadContent(){ public void loadContent(){
for(LoadedMod mod : loaded){ for(LoadedMod mod : loaded){
@@ -247,6 +273,11 @@ public class Mods implements Loadable{
return loaded; return loaded;
} }
/** @return all disabled mods. */
public Array<LoadedMod> disabled(){
return disabled;
}
/** @return a list of mod names only, without versions. */ /** @return a list of mod names only, without versions. */
public Array<String> getModNames(){ public Array<String> getModNames(){
return loaded.select(l -> !l.meta.hidden).map(l -> l.name + ":" + l.meta.version); return loaded.select(l -> !l.meta.hidden).map(l -> l.name + ":" + l.meta.version);
@@ -257,6 +288,21 @@ public class Mods implements Loadable{
return loaded.select(l -> !l.meta.hidden).map(l -> l.name + ":" + l.meta.version); return loaded.select(l -> !l.meta.hidden).map(l -> l.name + ":" + l.meta.version);
} }
/** Makes a mod enabled or disabled. shifts it.*/
public void setEnabled(LoadedMod mod, boolean enabled){
if(mod.enabled() != enabled){
Core.settings.putSave(mod.name + "-enabled", enabled);
requiresReload = true;
if(!enabled){
loaded.remove(mod);
disabled.add(mod);
}else{
loaded.add(mod);
disabled.remove(mod);
}
}
}
/** @return the mods that the client is missing. /** @return the mods that the client is missing.
* The inputted array is changed to contain the extra mods that the client has but the server doesn't.*/ * The inputted array is changed to contain the extra mods that the client has but the server doesn't.*/
public Array<String> getIncompatibility(Array<String> out){ public Array<String> getIncompatibility(Array<String> out){
@@ -335,9 +381,6 @@ public class Mods implements Loadable{
/** This mod's metadata. */ /** This mod's metadata. */
public final ModMeta meta; public final ModMeta meta;
//TODO implement
protected boolean enabled;
public LoadedMod(FileHandle file, FileHandle root, Mod mod, ModMeta meta){ public LoadedMod(FileHandle file, FileHandle root, Mod mod, ModMeta meta){
this.root = root; this.root = root;
this.file = file; this.file = file;
@@ -345,6 +388,10 @@ public class Mods implements Loadable{
this.meta = meta; this.meta = meta;
this.name = meta.name.toLowerCase().replace(" ", "-"); this.name = meta.name.toLowerCase().replace(" ", "-");
} }
public boolean enabled(){
return Core.settings.getBool(name + "-enabled", true);
}
} }
/** Plugin metadata information.*/ /** Plugin metadata information.*/

View File

@@ -40,7 +40,7 @@ public class ItemsDisplay extends Table{
private String format(Item item){ private String format(Item item){
builder.setLength(0); builder.setLength(0);
builder.append(ui.formatAmount(data.items().get(item, 0))); builder.append(ui.formatAmount(data.items().get(item, 0)));
if(!state.teams.get(player.getTeam()).cores.isEmpty() && state.teams.get(player.getTeam()).cores.first().entity != null && state.teams.get(player.getTeam()).cores.first().entity.items.get(item) > 0){ if(!state.is(State.menu) && !state.teams.get(player.getTeam()).cores.isEmpty() && state.teams.get(player.getTeam()).cores.first().entity != null && state.teams.get(player.getTeam()).cores.first().entity.items.get(item) > 0){
builder.append(" [unlaunched]+ "); builder.append(" [unlaunched]+ ");
builder.append(ui.formatAmount(state.teams.get(player.getTeam()).cores.first().entity.items.get(item))); builder.append(ui.formatAmount(state.teams.get(player.getTeam()).cores.first().entity.items.get(item)));
} }

View File

@@ -1,7 +1,9 @@
package io.anuke.mindustry.ui.dialogs; package io.anuke.mindustry.ui.dialogs;
import io.anuke.arc.*; import io.anuke.arc.*;
import io.anuke.arc.collection.*;
import io.anuke.mindustry.gen.*; import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.mod.Mods.*; import io.anuke.mindustry.mod.Mods.*;
import io.anuke.mindustry.ui.*; import io.anuke.mindustry.ui.*;
@@ -17,9 +19,9 @@ public class ModsDialog extends FloatingDialog{
shown(this::setup); shown(this::setup);
hidden(() -> { hidden(() -> {
if(mods.requiresRestart()){ if(mods.requiresReload()){
ui.showOkText("$mods", "$mod.requiresrestart", () -> { ui.loadAnd("$reloading", () -> {
Core.app.exit(); mods.reloadContent();
}); });
} }
}); });
@@ -34,18 +36,32 @@ public class ModsDialog extends FloatingDialog{
void setup(){ void setup(){
cont.clear(); cont.clear();
cont.defaults().width(520f).pad(4); cont.defaults().width(520f).pad(4);
if(!mods.all().isEmpty()){ if(!(mods.all().isEmpty() && mods.disabled().isEmpty())){
cont.pane(table -> { cont.pane(table -> {
table.margin(10f).top(); table.margin(10f).top();
for(LoadedMod mod : mods.all()){ Array<LoadedMod> all = Array.withArrays(mods.all(), mods.disabled());
boolean anyDisabled = false;
for(LoadedMod mod : all){
if(!mod.enabled() && !anyDisabled && mods.all().size > 0){
anyDisabled = true;
table.row();
table.addImage().growX().height(4f).pad(6f).color(Pal.gray);
}
table.table(Styles.black6, t -> { table.table(Styles.black6, t -> {
t.defaults().pad(2).left().top(); t.defaults().pad(2).left().top();
t.margin(14f).left(); t.margin(14f).left();
t.table(title -> { t.table(title -> {
title.left(); title.left();
title.add("[accent]" + mod.meta.name + "[lightgray] v" + mod.meta.version); title.add("[accent]" + mod.meta.name + "[lightgray] v" + mod.meta.version + (" | " + Core.bundle.get(mod.enabled() ? "mod.enabled" : "mod.disabled")));
title.add().growX(); title.add().growX();
title.addButton(mod.enabled() ? "$mod.disable" : "$mod.enable", Styles.cleart, () -> {
mods.setEnabled(mod, !mod.enabled());
setup();
}).height(50f).margin(8f).width(100f);
title.addImageButton(Icon.trash16Small, Styles.cleari, () -> ui.showConfirm("$confirm", "$mod.remove.confirm", () -> { title.addImageButton(Icon.trash16Small, Styles.cleari, () -> ui.showConfirm("$confirm", "$mod.remove.confirm", () -> {
mods.removeMod(mod); mods.removeMod(mod);
setup(); setup();