Add UI that presents Fixer Errors to the User(paulevsGitch/BetterNether#436)

This commit is contained in:
Frank 2021-11-06 11:25:48 +01:00
parent 03bef36a45
commit 03e8733ba0
6 changed files with 127 additions and 15 deletions

View file

@ -25,6 +25,7 @@ import ru.bclib.api.WorldDataAPI;
import ru.bclib.config.Configs;
import ru.bclib.gui.screens.AtomicProgressListener;
import ru.bclib.gui.screens.ConfirmFixScreen;
import ru.bclib.gui.screens.LevelFixErrorScreen;
import ru.bclib.gui.screens.ProgressScreen;
import ru.bclib.util.Logger;
@ -47,6 +48,24 @@ public class DataFixerAPI {
static final Logger LOGGER = new Logger("DataFixerAPI");
static class State {
public boolean didFail = false;
protected ArrayList<String> errors = new ArrayList<>();
public void addError(String s){
errors.add(s);
}
public boolean hasError(){
return errors.size()>0;
}
public String getErrorMessage(){
return errors.stream().reduce("", (a, b) -> a + " - " + b + "\n");
}
public String[] getErrorMessages(){
String[] res = new String[errors.size()];
return errors.toArray(res);
}
}
@FunctionalInterface
@ -200,30 +219,51 @@ public class DataFixerAPI {
progress = null;
}
Runnable runner = () -> {
Supplier<State> runner = () -> {
if (createBackup) {
progress.progressStage(new TranslatableComponent("message.bclib.datafixer.progress.waitbackup"));
EditWorldScreen.makeBackupAndShowToast(Minecraft.getInstance().getLevelSource(), levelID);
}
if (applyFixes) {
runDataFixes(dir, profile, progress);
return runDataFixes(dir, profile, progress);
}
return new State();
};
if (showUI) {
Thread fixerThread = new Thread(() -> {
runner.run();
Minecraft.getInstance().execute(() -> {
if (profile != null && showUI) {
onResume.accept(applyFixes);
}
});
State state = runner.get();
for (int i=0; i<20; i++)
state.addError("Hello World");
Minecraft.getInstance()
.execute(() -> {
if (profile != null && showUI) {
//something went wrong, show the user our error
if (state.didFail || state.hasError()){
Minecraft.getInstance()
.setScreen(new LevelFixErrorScreen(Minecraft.getInstance().screen, state.getErrorMessages(), (markFixed)->{
if (markFixed) {
profile.markApplied();
}
onResume.accept(applyFixes);
}));
} else {
onResume.accept(applyFixes);
}
}
});
});
fixerThread.start();
} else {
runner.run();
State state = runner.get();
if (state.hasError()){
LOGGER.error("There were Errors while fixing the Level:");
LOGGER.error(state.getErrorMessage());
}
}
};
@ -270,7 +310,7 @@ public class DataFixerAPI {
Minecraft.getInstance().setScreen(new ConfirmFixScreen((Screen) null, whenFinished::accept));
}
private static void runDataFixes(File dir, MigrationProfile profile, AtomicProgressListener progress) {
private static State runDataFixes(File dir, MigrationProfile profile, AtomicProgressListener progress) {
State state = new State();
progress.resetAtomic();
@ -295,6 +335,7 @@ public class DataFixerAPI {
profile.patchWorldData();
} catch (PatchDidiFailException e){
state.didFail = true;
state.addError("Failed fixing worldconfig (" + e.getMessage() + ")");
BCLib.LOGGER.error(e.getMessage());
}
progress.incAtomic(maxProgress);
@ -313,6 +354,8 @@ public class DataFixerAPI {
progress.incAtomic(maxProgress);
progress.stop();
return state;
}
private static void fixLevel(MigrationProfile profile, State state, File levelBaseDir) {
@ -342,6 +385,7 @@ public class DataFixerAPI {
}
catch (Exception e) {
BCLib.LOGGER.error("Failed fixing Level-Data.");
state.addError("Failed fixing Level-Data in level.dat (" + e.getMessage() + ")");
state.didFail = true;
e.printStackTrace();
}
@ -361,6 +405,7 @@ public class DataFixerAPI {
}
catch (Exception e) {
BCLib.LOGGER.error("Failed fixing Player-Data.");
state.addError("Failed fixing Player-Data in " + file.getName() + " (" + e.getMessage() + ")");
state.didFail = true;
e.printStackTrace();
}
@ -448,6 +493,7 @@ public class DataFixerAPI {
}
catch (PatchDidiFailException e) {
BCLib.LOGGER.error("Failed fixing BlockState in " + pos);
state.addError("Failed fixing BlockState in " + pos + " (" + e.getMessage() + ")");
state.didFail = true;
changed[0] = false;
e.printStackTrace();
@ -468,6 +514,7 @@ public class DataFixerAPI {
}
catch (Exception e) {
BCLib.LOGGER.error("Failed fixing Region.");
state.addError("Failed fixing Region in " + file.getName() + " (" + e.getMessage() + ")");
state.didFail = true;
e.printStackTrace();
}

View file

@ -0,0 +1,60 @@
package ru.bclib.gui.screens;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import ru.bclib.gui.gridlayout.GridColumn;
import ru.bclib.gui.gridlayout.GridLayout;
import ru.bclib.gui.gridlayout.GridRow;
@Environment(EnvType.CLIENT)
public class LevelFixErrorScreen extends BCLibScreen {
private final String[] errors;
final Listener onContinue;
public LevelFixErrorScreen(Screen parent, String[] errors, Listener onContinue) {
super(parent, new TranslatableComponent("title.bclib.datafixer.error"), 10, true);
this.errors = errors;
this.onContinue = onContinue;
}
@Override
protected void initLayout() {
grid.addSpacerRow();
grid.addRow().addMessage(new TranslatableComponent("message.bclib.datafixer.error"), font, GridLayout.Alignment.CENTER);
grid.addSpacerRow(8);
GridRow row = grid.addRow();
row.addSpacer(10);
GridColumn col = row.addColumn(300, GridLayout.GridValueType.CONSTANT);
for (String error : errors){
TextComponent dash = new TextComponent("-");
row = col.addRow();
row.addString(dash, this);
row.addSpacer(4);
row.addString(new TextComponent(error), this);
}
grid.addSpacerRow(8);
row = grid.addRow();
row.addFiller();
row.addButton(new TranslatableComponent("title.bclib.datafixer.error.continue"), 0.5f, 20, font, (n)-> {
onClose();
onContinue.doContinue(true);
});
row.addSpacer();
row.addButton(CommonComponents.GUI_CANCEL, 20, font, (n)-> {
this.minecraft.setScreen(null);
});
row.addFiller();
}
@Environment(EnvType.CLIENT)
public interface Listener {
void doContinue(boolean markFixed);
}
}

View file

@ -208,7 +208,6 @@ public class ModListScreen extends BCLibScreen {
row.addFiller();
row.addButton(buttonTitle, 20, font, (n)-> {
onClose();
System.out.println("Closing");
});
row.addFiller();
}

View file

@ -61,7 +61,7 @@ public abstract class MinecraftMixin {
DataExchangeAPI.prepareServerside();
if (DataFixerAPI.fixData(this.levelSource, levelID, true, (appliedFixes) -> {
this.doLoadLevel(levelID, RegistryAccess.builtin(), Minecraft::loadDataPacks, Minecraft::loadWorldData, false, Minecraft.ExperimentalDialogType.BACKUP);
this.doLoadLevel(levelID, RegistryAccess.builtin(), Minecraft::loadDataPacks, Minecraft::loadWorldData, false, appliedFixes?ExperimentalDialogType.NONE:ExperimentalDialogType.BACKUP);
})) {
ci.cancel();
}

View file

@ -43,5 +43,8 @@
"message.bclib.datafixer.progress.regions": "Alle Regionen reparieren",
"message.bclib.datafixer.progress.saving": "Patch-Status speichern",
"title.bclib.datafixer.progress": "Welt in Ordnung bringen",
"message.bclib.datafixer.progress": "Anwenden aller Änderungen"
"message.bclib.datafixer.progress": "Anwenden aller Änderungen",
"title.bclib.datafixer.error": "Fehler beim Reparieren der Welt",
"message.bclib.datafixer.error": "Es gab Fehler beim Reparieren der Welt. Das bedeutet, dass dieser Level wahrscheinlich in einem inkonsistenten Zustand ist und Sie ihn nicht spielen sollten. Bitte stellen Sie Ihr Backup wieder her und beheben Sie die unten aufgeführten Fehler, bevor Sie es erneut versuchen.",
"title.bclib.datafixer.error.continue": "Continue and Mark as Fixed"
}

View file

@ -43,5 +43,8 @@
"message.bclib.datafixer.progress.regions": "Repairing all Regions",
"message.bclib.datafixer.progress.saving": "Saving Patch State",
"title.bclib.datafixer.progress": "Fixing World",
"message.bclib.datafixer.progress": "Applying all Patches to your World."
"message.bclib.datafixer.progress": "Applying all Patches to your World.",
"title.bclib.datafixer.error": "Errors while fixing World",
"message.bclib.datafixer.error": "There were errors while repairing the world. This means that this level is probably in an inconsistent state and you should not play it. Please restore your backup and fix the errors below before trying again.",
"title.bclib.datafixer.error.continue": "Fortfahren und als behoben markieren"
}