Add UI that presents Fixer Errors to the User(paulevsGitch/BetterNether#436)
This commit is contained in:
parent
03bef36a45
commit
03e8733ba0
6 changed files with 127 additions and 15 deletions
|
@ -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();
|
||||
}
|
||||
|
|
60
src/main/java/ru/bclib/gui/screens/LevelFixErrorScreen.java
Normal file
60
src/main/java/ru/bclib/gui/screens/LevelFixErrorScreen.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -208,7 +208,6 @@ public class ModListScreen extends BCLibScreen {
|
|||
row.addFiller();
|
||||
row.addButton(buttonTitle, 20, font, (n)-> {
|
||||
onClose();
|
||||
System.out.println("Closing");
|
||||
});
|
||||
row.addFiller();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue