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

@@ -42,6 +42,14 @@ public class ContentLoader{
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. */
public void createContent(){
if(loaded){

View File

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

View File

@@ -83,6 +83,10 @@ public class EventType{
}
public static class ContentReloadEvent{
}
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.serialization.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.plugin.*;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.*;
import java.io.*;
import java.net.*;
@@ -33,8 +35,9 @@ public class Mods implements Loadable{
private PixmapPacker packer;
private Array<LoadedMod> loaded = new Array<>();
private Array<LoadedMod> disabled = new Array<>();
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.
* Call this in init(). */
@@ -60,7 +63,7 @@ public class Mods implements Loadable{
file.copyTo(dest);
try{
loaded.add(loadMod(file));
requiresRestart = true;
requiresReload = true;
}catch(IOException e){
dest.delete();
throw e;
@@ -137,6 +140,7 @@ public class Mods implements Loadable{
}
packer.dispose();
packer = null;
}
/** Removes a mod file and marks it for requiring a restart. */
@@ -147,11 +151,11 @@ public class Mods implements Loadable{
mod.file.delete();
}
loaded.remove(mod);
requiresRestart = true;
requiresReload = true;
}
public boolean requiresRestart(){
return requiresRestart;
public boolean requiresReload(){
return requiresReload;
}
/** 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;
try{
loaded.add(loadMod(file));
LoadedMod mod = loadMod(file);
if(mod.enabled()){
loaded.add(mod);
}else{
disabled.add(mod);
}
}catch(IllegalArgumentException ignored){
}catch(Exception e){
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. */
public void loadContent(){
for(LoadedMod mod : loaded){
@@ -247,6 +273,11 @@ public class Mods implements Loadable{
return loaded;
}
/** @return all disabled mods. */
public Array<LoadedMod> disabled(){
return disabled;
}
/** @return a list of mod names only, without versions. */
public Array<String> getModNames(){
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);
}
/** 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.
* 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){
@@ -335,9 +381,6 @@ public class Mods implements Loadable{
/** This mod's metadata. */
public final ModMeta meta;
//TODO implement
protected boolean enabled;
public LoadedMod(FileHandle file, FileHandle root, Mod mod, ModMeta meta){
this.root = root;
this.file = file;
@@ -345,6 +388,10 @@ public class Mods implements Loadable{
this.meta = meta;
this.name = meta.name.toLowerCase().replace(" ", "-");
}
public boolean enabled(){
return Core.settings.getBool(name + "-enabled", true);
}
}
/** Plugin metadata information.*/

View File

@@ -40,7 +40,7 @@ public class ItemsDisplay extends Table{
private String format(Item item){
builder.setLength(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(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;
import io.anuke.arc.*;
import io.anuke.arc.collection.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.mod.Mods.*;
import io.anuke.mindustry.ui.*;
@@ -17,9 +19,9 @@ public class ModsDialog extends FloatingDialog{
shown(this::setup);
hidden(() -> {
if(mods.requiresRestart()){
ui.showOkText("$mods", "$mod.requiresrestart", () -> {
Core.app.exit();
if(mods.requiresReload()){
ui.loadAnd("$reloading", () -> {
mods.reloadContent();
});
}
});
@@ -34,18 +36,32 @@ public class ModsDialog extends FloatingDialog{
void setup(){
cont.clear();
cont.defaults().width(520f).pad(4);
if(!mods.all().isEmpty()){
if(!(mods.all().isEmpty() && mods.disabled().isEmpty())){
cont.pane(table -> {
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 -> {
t.defaults().pad(2).left().top();
t.margin(14f).left();
t.table(title -> {
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.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", () -> {
mods.removeMod(mod);
setup();