From 7cca445cf783138fc4060ab90a9a389e0732dffc Mon Sep 17 00:00:00 2001 From: FlorianMichael <60033407+FlorianMichael@users.noreply.github.com> Date: Tue, 21 Feb 2023 00:21:52 +0100 Subject: [PATCH] cleaned loading system, added saving system, finished screens --- LICENSE | 1 - .../viafabricplus/ViaFabricPlus.java | 27 +++-- .../injection/mixin/base/MixinMain.java | 4 +- .../mixin/base/MixinMinecraftClient.java | 18 +++ .../mixin/base/MixinMultiplayerScreen.java | 2 +- .../screen/ProtocolSelectionScreen.java | 34 +++--- .../viafabricplus/screen/ValuesScreen.java | 103 ++++++++++++++++++ .../viafabricplus/value/AbstractValue.java | 7 +- .../viafabricplus/value/ValueHolder.java | 30 ++++- .../value/impl/BooleanValue.java | 11 ++ .../value/impl/ProtocolSyncBooleanValue.java | 19 ++++ src/main/resources/fabric.mod.json | 5 - src/main/resources/viafabricplus.mixins.json | 1 + 13 files changed, 229 insertions(+), 33 deletions(-) create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMinecraftClient.java create mode 100644 src/main/java/de/florianmichael/viafabricplus/screen/ValuesScreen.java diff --git a/LICENSE b/LICENSE index 29d8c027..6c7d36fa 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,3 @@ - --FLORIAN MICHAEL PRIVATE LICENCE v1.2-- This file / project is protected and is the intellectual property of Florian Michael (aka. EnZaXD), diff --git a/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java b/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java index 27045359..ce1f6b4b 100644 --- a/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java +++ b/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java @@ -38,7 +38,6 @@ import de.florianmichael.vialoadingbase.ViaLoadingBase; import de.florianmichael.vialoadingbase.api.SubPlatform; import io.netty.channel.DefaultEventLoop; import io.netty.util.AttributeKey; -import net.fabricmc.api.ClientModInitializer; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.metadata.Person; @@ -53,10 +52,11 @@ import java.io.File; import java.util.ArrayList; import java.util.List; -public class ViaFabricPlus implements ClientModInitializer { - public static final AttributeKey LOCAL_USER_CONNECTION = AttributeKey.newInstance("via-version-user-connection"); +public class ViaFabricPlus { + public final static File RUN_DIRECTORY = new File(".viafabricplus"); + public final static AttributeKey LOCAL_USER_CONNECTION = AttributeKey.newInstance("via-version-user-connection"); - private static final ViaFabricPlus self = new ViaFabricPlus(); + private final static ViaFabricPlus self = new ViaFabricPlus(); private final SubPlatform SUB_PLATFORM_VIA_LEGACY = new SubPlatform("ViaLegacy", () -> true, ViaLegacyPlatformImpl::new, protocolVersions -> protocolVersions.addAll(LegacyProtocolVersion.PROTOCOLS)); private final SubPlatform SUB_PLATFORM_VIA_APRIL_FOOLS = new SubPlatform("ViaAprilFools", () -> true, ViaAprilFoolsPlatformImpl::new, this::invokeAprilFoolsProtocols); @@ -73,13 +73,13 @@ public class ViaFabricPlus implements ClientModInitializer { origin.add(v1_16_2Index - 1, AprilFoolsProtocolVersion.sCombatTest8c); } - public void preInit() { + public void preLoad() { ViaLoadingBase.ViaLoadingBaseBuilder builder = ViaLoadingBase.ViaLoadingBaseBuilder.create(); builder = builder.subPlatform(SUB_PLATFORM_VIA_LEGACY); builder = builder.subPlatform(SUB_PLATFORM_VIA_APRIL_FOOLS); - builder = builder.runDirectory(new File("ViaFabricPlus")); + builder = builder.runDirectory(RUN_DIRECTORY); builder = builder.nativeVersion(SharedConstants.getProtocolVersion()); builder = builder.singlePlayerProvider(() -> MinecraftClient.getInstance().isInSingleplayer()); builder = builder.eventLoop(new DefaultEventLoop()); @@ -123,12 +123,23 @@ public class ViaFabricPlus implements ClientModInitializer { builder.build(); } - @Override - public void onInitializeClient() { + public void postLoad() throws Exception { ValueHolder.setup(); PackFormatsDefinition.load(); ItemReleaseVersionDefinition.load(); + + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + this.close(); + } catch (Exception e) { + throw new RuntimeException(e); + } + })); + } + + public void close() throws Exception { + ValueHolder.save(); } public List getAvailableItemsInTargetVersion() { diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMain.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMain.java index 29b05f84..f7901c86 100644 --- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMain.java +++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMain.java @@ -32,7 +32,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; public class MixinMain { @Inject(method = "main([Ljava/lang/String;Z)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/crash/CrashReport;initCrashReport()V")) - private static void loadViaLoadingBase(CallbackInfo ci) { - ViaFabricPlus.getClassWrapper().preInit(); + private static void preLoad(CallbackInfo ci) { + ViaFabricPlus.getClassWrapper().preLoad(); } } diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMinecraftClient.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMinecraftClient.java new file mode 100644 index 00000000..d0ea267b --- /dev/null +++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMinecraftClient.java @@ -0,0 +1,18 @@ +package de.florianmichael.viafabricplus.injection.mixin.base; + +import de.florianmichael.viafabricplus.ViaFabricPlus; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.RunArgs; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MinecraftClient.class) +public class MixinMinecraftClient { + + @Inject(method = "", at = @At("RETURN")) + public void postLoad(RunArgs args, CallbackInfo ci) throws Exception { + ViaFabricPlus.getClassWrapper().postLoad(); + } +} diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMultiplayerScreen.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMultiplayerScreen.java index abf78508..86f52696 100644 --- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMultiplayerScreen.java +++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/MixinMultiplayerScreen.java @@ -19,6 +19,6 @@ public class MixinMultiplayerScreen extends Screen { @Inject(method = "init", at = @At("RETURN")) public void addProtocolSelectionButton(CallbackInfo ci) { - this.addDrawableChild(ButtonWidget.builder(Text.literal("ViaFabricPlus"), button -> client.setScreen(ProtocolSelectionScreen.INSTANCE)).position(3, 3).size(98, 20).build()); + this.addDrawableChild(ButtonWidget.builder(Text.literal("ViaFabricPlus"), button -> ProtocolSelectionScreen.open(this)).position(3, 3).size(98, 20).build()); } } diff --git a/src/main/java/de/florianmichael/viafabricplus/screen/ProtocolSelectionScreen.java b/src/main/java/de/florianmichael/viafabricplus/screen/ProtocolSelectionScreen.java index 98d610c0..3a84b4f5 100644 --- a/src/main/java/de/florianmichael/viafabricplus/screen/ProtocolSelectionScreen.java +++ b/src/main/java/de/florianmichael/viafabricplus/screen/ProtocolSelectionScreen.java @@ -15,21 +15,27 @@ import net.minecraft.text.Text; import java.awt.*; +@SuppressWarnings("DataFlowIssue") public class ProtocolSelectionScreen extends Screen { - public final static ProtocolSelectionScreen INSTANCE = new ProtocolSelectionScreen(); + private final static ProtocolSelectionScreen INSTANCE = new ProtocolSelectionScreen(); + public Screen prevScreen; protected ProtocolSelectionScreen() { super(Text.literal("Protocol selection")); } + public static void open(final Screen current) { + INSTANCE.prevScreen = current; + MinecraftClient.getInstance().setScreen(INSTANCE); + } + @Override protected void init() { super.init(); - this.addDrawableChild(new SlotList(this.client, width, height, 30, height - 20, textRenderer.fontHeight + 2)); + this.addDrawableChild(new SlotList(this.client, width, height, 3 + 3 /* start offset */ + (textRenderer.fontHeight + 2) * 3 /* title is 2 */, height + 5, textRenderer.fontHeight + 2)); - this.addDrawableChild(ButtonWidget.builder(Text.literal("Values"), button -> { - }).position(3, 3).size(98, 20).build()); + this.addDrawableChild(ButtonWidget.builder(Text.literal("Values"), button -> ValuesScreen.open(this)).position(0, 0).size(98, 20).build()); } @Override @@ -40,9 +46,15 @@ public class ProtocolSelectionScreen extends Screen { matrices.scale(2F, 2F, 2F); drawCenteredText(matrices, textRenderer, "ViaFabricPlus", width / 4, 3, -1); matrices.pop(); + drawCenteredText(matrices, textRenderer, "https://github.com/FlorianMichael/ViaFabricPlus", width / 2, (textRenderer.fontHeight + 2) * 2 + 3, -1); - drawStringWithShadow(matrices, textRenderer, "by EnZaXD/FlorianMichael", 1, height - (textRenderer.fontHeight) * 2, -1); - drawStringWithShadow(matrices, textRenderer, "https://github.com/FlorianMichael/ViaFabricPlus", 1, height - textRenderer.fontHeight, -1); + final String authorString = "by EnZaXD/FlorianMichael"; + drawStringWithShadow(matrices, textRenderer, authorString, width - textRenderer.getWidth(authorString), 0, -1); + } + + @Override + public void close() { + client.setScreen(prevScreen); } public static class SlotList extends AlwaysSelectedEntryListWidget { @@ -50,18 +62,14 @@ public class ProtocolSelectionScreen extends Screen { public SlotList(MinecraftClient minecraftClient, int width, int height, int top, int bottom, int entryHeight) { super(minecraftClient, width, height, top, bottom, entryHeight); - for (ProtocolVersion protocol : InternalProtocolList.getProtocols()) { - addEntry(new ProtocolSlot(this, protocol)); - } + InternalProtocolList.getProtocols().stream().map(ProtocolSlot::new).forEach(this::addEntry); } } public static class ProtocolSlot extends AlwaysSelectedEntryListWidget.Entry { - private final SlotList slotList; private final ProtocolVersion protocolVersion; - public ProtocolSlot(final SlotList slotList, final ProtocolVersion protocolVersion) { - this.slotList = slotList; + public ProtocolSlot(final ProtocolVersion protocolVersion) { this.protocolVersion = protocolVersion; } @@ -86,8 +94,6 @@ public class ProtocolSelectionScreen extends Screen { final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; drawCenteredText(matrices, textRenderer, this.protocolVersion.getName(), entryWidth / 2, entryHeight / 2 - textRenderer.fontHeight / 2, isSelected ? Color.GREEN.getRGB() : Color.RED.getRGB()); matrices.pop(); - - if (isSelected) this.slotList.setSelected(this); } } } diff --git a/src/main/java/de/florianmichael/viafabricplus/screen/ValuesScreen.java b/src/main/java/de/florianmichael/viafabricplus/screen/ValuesScreen.java new file mode 100644 index 00000000..d47cc019 --- /dev/null +++ b/src/main/java/de/florianmichael/viafabricplus/screen/ValuesScreen.java @@ -0,0 +1,103 @@ +package de.florianmichael.viafabricplus.screen; + +import de.florianmichael.viafabricplus.value.AbstractValue; +import de.florianmichael.viafabricplus.value.ValueHolder; +import de.florianmichael.viafabricplus.value.impl.BooleanValue; +import de.florianmichael.viafabricplus.value.impl.ProtocolSyncBooleanValue; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget; +import net.minecraft.client.sound.PositionedSoundInstance; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.sound.SoundEvents; +import net.minecraft.text.Text; +import org.lwjgl.glfw.GLFW; + +import java.awt.*; + +@SuppressWarnings("DataFlowIssue") +public class ValuesScreen extends Screen { + private final static ValuesScreen INSTANCE = new ValuesScreen(); + public Screen prevScreen; + + protected ValuesScreen() { + super(Text.literal("Values")); + } + + public static void open(final Screen current) { + INSTANCE.prevScreen = current; + MinecraftClient.getInstance().setScreen(INSTANCE); + } + + @Override + protected void init() { + super.init(); + + this.addDrawableChild(new SlotList(this.client, width, height, 3 + 3 /* start offset */ + (textRenderer.fontHeight + 2) * 3 /* title is 2 */, height + 5, (textRenderer.fontHeight + 2) * 2)); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + super.render(matrices, mouseX, mouseY, delta); + + matrices.push(); + matrices.scale(2F, 2F, 2F); + drawCenteredText(matrices, textRenderer, "ViaFabricPlus", width / 4, 3, -1); + matrices.pop(); + drawCenteredText(matrices, textRenderer, "https://github.com/FlorianMichael/ViaFabricPlus", width / 2, (textRenderer.fontHeight + 2) * 2 + 3, -1); + } + + @Override + public void close() { + client.setScreen(prevScreen); + } + + public static class SlotList extends AlwaysSelectedEntryListWidget { + + public SlotList(MinecraftClient minecraftClient, int width, int height, int top, int bottom, int entryHeight) { + super(minecraftClient, width, height, top, bottom, entryHeight); + + ValueHolder.values.stream().map(ValueSlot::new).forEach(this::addEntry); + } + } + + public static class ValueSlot extends AlwaysSelectedEntryListWidget.Entry { + private final AbstractValue value; + + public ValueSlot(AbstractValue value) { + this.value = value; + } + + @Override + public Text getNarration() { + return Text.literal(this.value.getName()); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (value instanceof BooleanValue booleanValue) booleanValue.setValue(!booleanValue.getValue()); + if (value instanceof ProtocolSyncBooleanValue protocolSyncBooleanValue) { + if (button == GLFW.GLFW_MOUSE_BUTTON_LEFT) protocolSyncBooleanValue.setValue(!protocolSyncBooleanValue.getValue()); + if (button == GLFW.GLFW_MOUSE_BUTTON_RIGHT) protocolSyncBooleanValue.setSyncWithProtocol(!protocolSyncBooleanValue.isSyncWithProtocol()); + } + MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F)); + return super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + matrices.push(); + matrices.translate(x, y, 0); + final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + if (value instanceof BooleanValue booleanValue) { + final boolean isEnabled = booleanValue.getValue(); + drawCenteredText(matrices, textRenderer, booleanValue.getName(), entryWidth / 2, entryHeight / 2 - textRenderer.fontHeight / 2, isEnabled ? Color.GREEN.getRGB() : Color.RED.getRGB()); + } else if (value instanceof ProtocolSyncBooleanValue protocolSyncBooleanValue) { + final boolean isEnabled = protocolSyncBooleanValue.getValue(); + drawCenteredText(matrices, textRenderer, protocolSyncBooleanValue.getName(), entryWidth / 2, entryHeight / 2 - textRenderer.fontHeight / 2, protocolSyncBooleanValue.isSyncWithProtocol() ? Color.ORANGE.getRGB() : isEnabled ? Color.GREEN.getRGB() : Color.RED.getRGB()); + } + matrices.pop(); + } + } +} diff --git a/src/main/java/de/florianmichael/viafabricplus/value/AbstractValue.java b/src/main/java/de/florianmichael/viafabricplus/value/AbstractValue.java index bf6f550b..46799e4c 100644 --- a/src/main/java/de/florianmichael/viafabricplus/value/AbstractValue.java +++ b/src/main/java/de/florianmichael/viafabricplus/value/AbstractValue.java @@ -21,13 +21,15 @@ package de.florianmichael.viafabricplus.value; +import com.google.gson.JsonObject; + public abstract class AbstractValue { private final String name; private final T defaultValue; private T value; - public AbstractValue(String name, T defaultValue) { + public AbstractValue(final String name, final T defaultValue) { this.name = name; this.defaultValue = defaultValue; @@ -36,6 +38,9 @@ public abstract class AbstractValue { ValueHolder.values.add(this); } + public abstract void write(final JsonObject object); + public abstract void read(final JsonObject object); + public String getName() { return name; } diff --git a/src/main/java/de/florianmichael/viafabricplus/value/ValueHolder.java b/src/main/java/de/florianmichael/viafabricplus/value/ValueHolder.java index c44235ce..431b8a70 100644 --- a/src/main/java/de/florianmichael/viafabricplus/value/ValueHolder.java +++ b/src/main/java/de/florianmichael/viafabricplus/value/ValueHolder.java @@ -21,16 +21,24 @@ package de.florianmichael.viafabricplus.value; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import de.florianmichael.viafabricplus.ViaFabricPlus; import de.florianmichael.viafabricplus.platform.ProtocolRange; import de.florianmichael.viafabricplus.value.impl.BooleanValue; import de.florianmichael.viafabricplus.value.impl.ProtocolSyncBooleanValue; import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import java.io.*; import java.util.ArrayList; import java.util.List; public class ValueHolder { + public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + public final static File CONFIG_FILE = new File(ViaFabricPlus.RUN_DIRECTORY, "settings.json"); + public final static List> values = new ArrayList<>(); // General settings @@ -54,6 +62,26 @@ public class ValueHolder { public static final ProtocolSyncBooleanValue replaceSneaking = new ProtocolSyncBooleanValue("Replace sneaking", ProtocolRange.andOlder(ProtocolVersion.v1_7_6)); public static final ProtocolSyncBooleanValue longSneaking = new ProtocolSyncBooleanValue("Long sneaking", ProtocolRange.andOlder(ProtocolVersion.v1_7_6)); - public static void setup() { + public static void setup() throws FileNotFoundException { + if (CONFIG_FILE.exists()) { + final JsonObject parentNode = GSON.fromJson(new FileReader(CONFIG_FILE), JsonObject.class).getAsJsonObject(); + for (AbstractValue value : values) { + value.read(parentNode); + } + } + } + + public static void save() throws IOException { + CONFIG_FILE.delete(); + CONFIG_FILE.createNewFile(); + + try (final FileWriter fw = new FileWriter(CONFIG_FILE)) { + final JsonObject parentNode = new JsonObject(); + for (AbstractValue value : values) { + value.write(parentNode); + } + fw.write(GSON.toJson(parentNode)); + fw.flush(); + } } } diff --git a/src/main/java/de/florianmichael/viafabricplus/value/impl/BooleanValue.java b/src/main/java/de/florianmichael/viafabricplus/value/impl/BooleanValue.java index d4786e23..3caa4ed1 100644 --- a/src/main/java/de/florianmichael/viafabricplus/value/impl/BooleanValue.java +++ b/src/main/java/de/florianmichael/viafabricplus/value/impl/BooleanValue.java @@ -21,6 +21,7 @@ package de.florianmichael.viafabricplus.value.impl; +import com.google.gson.JsonObject; import de.florianmichael.viafabricplus.value.AbstractValue; public class BooleanValue extends AbstractValue { @@ -28,4 +29,14 @@ public class BooleanValue extends AbstractValue { public BooleanValue(String name, Boolean defaultValue) { super(name, defaultValue); } + + @Override + public void write(JsonObject object) { + object.addProperty(getName(), getValue()); + } + + @Override + public void read(JsonObject object) { + setValue(object.get(getName()).getAsBoolean()); + } } diff --git a/src/main/java/de/florianmichael/viafabricplus/value/impl/ProtocolSyncBooleanValue.java b/src/main/java/de/florianmichael/viafabricplus/value/impl/ProtocolSyncBooleanValue.java index d950cd44..260cb545 100644 --- a/src/main/java/de/florianmichael/viafabricplus/value/impl/ProtocolSyncBooleanValue.java +++ b/src/main/java/de/florianmichael/viafabricplus/value/impl/ProtocolSyncBooleanValue.java @@ -21,6 +21,7 @@ package de.florianmichael.viafabricplus.value.impl; +import com.google.gson.JsonObject; import de.florianmichael.viafabricplus.platform.ProtocolRange; import de.florianmichael.viafabricplus.value.AbstractValue; import de.florianmichael.vialoadingbase.ViaLoadingBase; @@ -36,6 +37,24 @@ public class ProtocolSyncBooleanValue extends AbstractValue { this.protocolRange = protocolRange; } + @Override + public void write(JsonObject object) { + final JsonObject valueNode = new JsonObject(); + + valueNode.addProperty("value", this.getValue()); + valueNode.addProperty("sync-with-protocol", this.isSyncWithProtocol()); + + object.add(getName(), valueNode); + } + + @Override + public void read(JsonObject object) { + final JsonObject valueNode = object.get(getName()).getAsJsonObject(); + + setValue(valueNode.get("value").getAsBoolean()); + setSyncWithProtocol(valueNode.get("sync-with-protocol").getAsBoolean()); + } + @Override public Boolean getValue() { if (this.syncWithProtocol) return protocolRange.contains(ViaLoadingBase.getTargetVersion()); diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index c90bbde2..c6196899 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -17,11 +17,6 @@ "license": "CC0-1.0", "icon": "assets/viafabricplus/icon.png", - "entrypoints": { - "client": [ - "de.florianmichael.viafabricplus.ViaFabricPlus" - ] - }, "environment": "*", "mixins": [ "viafabricplus.mixins.json" diff --git a/src/main/resources/viafabricplus.mixins.json b/src/main/resources/viafabricplus.mixins.json index 9b3ec9bf..5d279bcb 100644 --- a/src/main/resources/viafabricplus.mixins.json +++ b/src/main/resources/viafabricplus.mixins.json @@ -99,6 +99,7 @@ }, "client": [ "base.MixinMain", + "base.MixinMinecraftClient", "base.MixinMultiplayerScreen", "fixes.MixinCamera", "fixes.MixinClientPlayerInteractionManager",