Prepared BCLib Version warning screen

This commit is contained in:
Frank Bauer 2021-07-31 11:29:13 +02:00
parent 46a5603ff7
commit 4fc9c06204
7 changed files with 171 additions and 58 deletions

View file

@ -6,6 +6,8 @@ import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.worldselection.EditWorldScreen;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
@ -14,12 +16,15 @@ import ru.bclib.api.dataexchange.DataExchangeAPI;
import ru.bclib.api.dataexchange.DataHandler;
import ru.bclib.api.dataexchange.DataHandlerDescriptor;
import ru.bclib.api.datafixer.DataFixerAPI;
import ru.bclib.gui.screens.ConfirmFixScreen;
import ru.bclib.gui.screens.WarnBCLibVersionMismatch;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.Consumer;
public class HelloClient extends DataHandler {
public static DataHandlerDescriptor DESCRIPTOR = new DataHandlerDescriptor(new ResourceLocation(BCLib.MOD_ID, "hello_client"), HelloClient::new, true);
@ -86,7 +91,19 @@ public class HelloClient extends DataHandler {
@Environment(EnvType.CLIENT)
protected void showBCLibError(Minecraft client){
BCLib.LOGGER.error("BCLib differs on client and server. Stopping.");
client.pauseGame(false);
BCLib.LOGGER.error("BCLib differs on client and server.");
client.setScreen(new WarnBCLibVersionMismatch((download) -> {
Minecraft.getInstance().setScreen((Screen)null);
if (download){
requestDownloads((hadErrors)->{
client.stop();
});
}
}));
}
private void requestDownloads(Consumer<Boolean> whenFinished){
BCLib.LOGGER.warning("Starting download of BCLib");
}
}

View file

@ -227,9 +227,6 @@ public class DataFixerAPI {
@Environment(EnvType.CLIENT)
static void showBackupWarning(String levelID, Consumer<Boolean> whenFinished){
TranslatableComponent promptText = new TranslatableComponent("bclib.datafixer.backupWarning.prompt");
TranslatableComponent buttonTitle = new TranslatableComponent("bclib.datafixer.backupWarning.button");
Minecraft.getInstance().setScreen(new ConfirmFixScreen((Screen) null, (createBackup, applyFixes) -> {
if (createBackup) {
EditWorldScreen.makeBackupAndShowToast(Minecraft.getInstance().getLevelSource(), levelID);
@ -238,7 +235,6 @@ public class DataFixerAPI {
Minecraft.getInstance().setScreen((Screen)null);
whenFinished.accept(applyFixes);
}));
}
private static void runDataFixes(File dir, MigrationProfile profile, ProgressListener progress) {

View file

@ -5,9 +5,7 @@ import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.Button.OnPress;
import net.minecraft.client.gui.components.MultiLineLabel;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@ -27,72 +25,107 @@ public class GridLayout {
}
class ButtonPos {
final int top;
final int height;
final int width;
final float alpha;
final Component component;
final Button.OnPress onPress;
ButtonPos(float alpha, int width, int height, Component component, OnPress onPress) {
ButtonPos(float alpha, int top, int width, int height, Component component, OnPress onPress) {
this.height = height;
this.width = width;
this.top = top;
this.alpha = alpha;
this.component = component;
this.onPress = onPress;
}
}
public final int width;
public final int height;
@NotNull
private final Font font;
private final Consumer<Button> addButtonFunction;
public final int topStart;
private final int topStart;
private int topOffset;
private int top;
private int currentRowHeight = 0;
private int currentRowMargin = 6;
private int lastRowMargin = 0;
final private List<LablePos> labels;
final private List<ButtonPos> buttons;
final private List<List<ButtonPos>> buttons;
private List<ButtonPos> currentButtonRow;
public GridLayout(int topStart, int width, Font font, Consumer<Button> addButtonFunction){
public GridLayout(int topStart, int width, int height, Font font, Consumer<Button> addButtonFunction){
Objects.requireNonNull(font);
this.topStart = topStart;
top = topStart + 20;
this.topOffset = 0;
this.width = width;
this.height = height;
this.font = font;
this.addButtonFunction = addButtonFunction;
labels = new ArrayList<>(4);
buttons = new ArrayList<>(8);
buttons = new ArrayList<>(4);
}
public int getTopStart(){
return topStart + topOffset;
}
public void addMessageRow(Component text, int padding){
addMessageRow(MultiLineLabel.create(this.font, text, this.width - 2*padding));
}
public void addMessageRow(MultiLineLabel lb){
final int LABEL_MARGIN_BOTTOM = 12;
labels.add(new LablePos(lb, top));
int promptLines = lb.getLineCount() + 1;
int height = promptLines * 9;
currentRowHeight = height + LABEL_MARGIN_BOTTOM;;
currentRowMargin = 12;
currentRowHeight = height;
}
public void startRow(){
this.endRow();
top += currentRowHeight;
currentRowHeight = 0;
this.currentButtonRow = new ArrayList<>(8);
this.buttons.add(this.currentButtonRow);
}
public void endRow(){
final int BUTTON_SPACING = 10;
int count = buttons.size();
int rowWidth = buttons.stream().map(b -> b.width).reduce(0, (p, c) -> p+c) + (count-1) * BUTTON_SPACING;
int left = (width-rowWidth)/2;
lastRowMargin = currentRowMargin;
top += currentRowHeight + currentRowMargin;
currentRowHeight = 0;
currentRowMargin = 0;
}
for (ButtonPos bp:buttons){
Button customButton = new Button(left, top, bp.width, bp.height, bp.component, bp.onPress);
public void recenterVertically(){
int hg = (top - lastRowMargin) - topStart;
int targetTop = (height - hg)/2;
topOffset = targetTop - topStart;
}
void finalizeLayout(){
final int BUTTON_SPACING = 10;
for (List<ButtonPos> row : this.buttons) {
int count = row.size();
int rowWidth = row.stream()
.map(b -> b.width)
.reduce(0, (p, c) -> p + c) + (count - 1) * BUTTON_SPACING;
int left = (width - rowWidth) / 2;
for (ButtonPos bp : row) {
Button customButton = new Button(left, bp.top+topOffset, bp.width, bp.height, bp.component, bp.onPress);
customButton.setAlpha(bp.alpha);
addButtonFunction.accept(customButton);
left += BUTTON_SPACING + bp.width;
};
buttons.clear();
}
}
}
public void addButton(int width, int height, Component component, Button.OnPress onPress){
addButton(1.0f, width, height, component, onPress);
}
@ -108,15 +141,14 @@ public class GridLayout {
}
public void addButton(float alpha, int width, int height, Component component, Button.OnPress onPress){
final int BUTTON_MARGIN_BOTTOM = 6;
currentRowHeight = Math.max(currentRowHeight, height + BUTTON_MARGIN_BOTTOM);
buttons.add(new ButtonPos(alpha, width, height, component, onPress));
currentRowHeight = Math.max(currentRowHeight, height);
currentRowMargin = 6;
currentButtonRow.add(new ButtonPos(alpha, top, width, height, component, onPress));
}
public void render(PoseStack poseStack){
labels.forEach(lp -> {
lp.label.renderCentered(poseStack, this.width / 2, lp.top);
lp.label.renderCentered(poseStack, this.width / 2, lp.top + topOffset);
});
}
}

View file

@ -0,0 +1,34 @@
package ru.bclib.gui;
import com.mojang.blaze3d.vertex.PoseStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
@Environment(EnvType.CLIENT)
public abstract class GridScreen extends Screen {
protected GridLayout grid = null;
public final int topStart;
public GridScreen(int topStart, Component title) {
super(title);
this.topStart = topStart;
}
final protected void init() {
super.init();
this.grid = new GridLayout(topStart, this.width, this.height, this.font, this::addRenderableWidget);
initLayout();
grid.finalizeLayout();
}
protected abstract void initLayout();
public void render(PoseStack poseStack, int i, int j, float f) {
this.renderBackground(poseStack);
drawCenteredString(poseStack, this.font, this.title, grid.width / 2, grid.getTopStart(), 16777215);
if (grid!=null) grid.render(poseStack);
super.render(poseStack, i, j, f);
}
}

View file

@ -14,37 +14,30 @@ import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
import ru.bclib.BCLib;
import ru.bclib.gui.GridLayout;
import ru.bclib.gui.GridScreen;
@Environment(EnvType.CLIENT)
public class ConfirmFixScreen extends Screen {
public class ConfirmFixScreen extends GridScreen {
static final ResourceLocation BCLIB_LOGO_LOCATION = new ResourceLocation(BCLib.MOD_ID,
"icon.png");
@Nullable
private final Screen lastScreen;
protected final BackupConfirmScreen.Listener listener;
protected final ConfirmFixScreen.Listener listener;
private final Component description;
private MultiLineLabel message;
protected int id;
private GridLayout grid = null;
public ConfirmFixScreen(@Nullable Screen screen, BackupConfirmScreen.Listener listener) {
super(new TranslatableComponent("bclib.datafixer.backupWarning.title"));
this.message = MultiLineLabel.EMPTY;
public ConfirmFixScreen(@Nullable Screen screen, ConfirmFixScreen.Listener listener) {
super(30, new TranslatableComponent("bclib.datafixer.backupWarning.title"));
this.lastScreen = screen;
this.listener = listener;
this.description = new TranslatableComponent("bclib.datafixer.backupWarning.message");
}
protected void init() {
super.init();
this.grid = new GridLayout(30, this.width, this.font, this::addRenderableWidget);
final int BUTTON_WIDTH = 150;
final int BUTTON_SPACE = 10;
protected void initLayout() {
final int BUTTON_HEIGHT = 20;
grid.addMessageRow(MultiLineLabel.create(this.font, this.description, this.width - 50));
grid.addMessageRow(this.description, 25);
grid.startRow();
grid.addButton( BUTTON_HEIGHT, new TranslatableComponent("bclib.datafixer.backupWarning.backup"), (button) -> {
@ -67,13 +60,6 @@ public class ConfirmFixScreen extends Screen {
grid.endRow();
}
public void render(PoseStack poseStack, int i, int j, float f) {
this.renderBackground(poseStack);
drawCenteredString(poseStack, this.font, this.title, grid.width / 2, grid.topStart, 16777215);
if (grid!=null) grid.render(poseStack);
super.render(poseStack, i, j, f);
}
public boolean shouldCloseOnEsc() {
return false;
}
@ -89,6 +75,6 @@ public class ConfirmFixScreen extends Screen {
@Environment(EnvType.CLIENT)
public interface Listener {
void proceed(boolean bl, boolean bl2);
void proceed(boolean createBackup, boolean applyPatches);
}
}

View file

@ -0,0 +1,46 @@
package ru.bclib.gui.screens;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import ru.bclib.gui.GridScreen;
@Environment(EnvType.CLIENT)
public class WarnBCLibVersionMismatch extends GridScreen {
private final Component description;
private final Listener listener;
public WarnBCLibVersionMismatch(Listener listener) {
super(30, new TranslatableComponent("bclib.datafixer.bclibmissmatch.title"));
this.description = new TranslatableComponent("bclib.datafixer.bclibmissmatch.message");
this.listener = listener;
}
protected void initLayout() {
final int BUTTON_HEIGHT = 20;
grid.addMessageRow(this.description, 25);
grid.startRow();
grid.addButton( BUTTON_HEIGHT, CommonComponents.GUI_NO, (button) -> {
listener.proceed(false);
});
grid.addButton( BUTTON_HEIGHT, CommonComponents.GUI_YES, (button) -> {
listener.proceed(true);
});
grid.endRow();
grid.recenterVertically();
}
public boolean shouldCloseOnEsc() {
return false;
}
@Environment(EnvType.CLIENT)
public interface Listener {
void proceed(boolean download);
}
}

View file

@ -4,5 +4,7 @@
"bclib.datafixer.backupWarning.message": "The Guardian detected, that the internals of the following Mods did change since this world was last played.\n\nWe can automatically change the world for you. If you continue without applying the changes the world may not load correct. Before you continue, you should create a Backup.",
"bclib.datafixer.backupWarning.backup": "Create Backup and Continue",
"bclib.datafixer.backupWarning.nofixes": "Continue Without Fixes",
"bclib.datafixer.backupWarning.continue": "Continue Without Backup"
"bclib.datafixer.backupWarning.continue": "Continue Without Backup",
"bclib.datafixer.bclibmissmatch.title": "Version Mismatch",
"bclib.datafixer.bclibmissmatch.message": "The Version of BCLib on the server and this client do not match. This will cause problems when playing.\n\nDo you want to automatically download the BCLib-Version from the server. You will need to delete the old version from your Mods Directory and restart the game."
}