Even more improvements

Added SaveFilesCallback to interact with the saving api
Require alpha inventory emulation setting to restart / cleaned code.
Added VFPListEntry#renderTooltip
Added tooltip support to AbstractSetting API
This commit is contained in:
FlorianMichael 2023-11-28 14:56:28 +01:00
parent 1611d96da3
commit bf5c9f9982
No known key found for this signature in database
GPG Key ID: C2FB87E71C425126
16 changed files with 132 additions and 49 deletions

View File

@ -63,15 +63,13 @@ public class ViaFabricPlus {
directory.mkdir();
ClassLoaderPriorityUtil.loadOverridingJars(directory); // Load overriding jars first so other code can access the new classes
settingsManager = new SettingsManager();
saveManager = new SaveManager(settingsManager);
ClientsideFixes.init(); // Init clientside related fixes
loadingFuture = ProtocolHack.init(directory); // Init ViaVersion protocol translator platform
settingsManager = new SettingsManager();
saveManager = new SaveManager(settingsManager);
PostGameLoadCallback.EVENT.register(() -> {
saveManager.init();
loadingFuture.join();
}); // Has to wait for Minecraft because of the translation system usages
PostGameLoadCallback.EVENT.register(() -> loadingFuture.join()); // Block game loading until ViaVersion has loaded
}
public static ViaFabricPlus global() {

View File

@ -19,6 +19,7 @@
package de.florianmichael.viafabricplus.event;
import de.florianmichael.viafabricplus.settings.SettingsManager;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
@ -27,13 +28,13 @@ import net.fabricmc.fabric.api.event.EventFactory;
*/
public interface RegisterSettingsCallback {
Event<RegisterSettingsCallback> EVENT = EventFactory.createArrayBacked(RegisterSettingsCallback.class, listeners -> state -> {
Event<RegisterSettingsCallback> EVENT = EventFactory.createArrayBacked(RegisterSettingsCallback.class, listeners -> (settingsManager, state) -> {
for (RegisterSettingsCallback listener : listeners) {
listener.onInitializeSettings(state);
listener.onRegisterSettings(settingsManager, state);
}
});
void onInitializeSettings(final State state);
void onRegisterSettings(final SettingsManager settingsManager, final State state);
enum State {
PRE, POST

View File

@ -0,0 +1,42 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD
* Copyright (C) 2023 RK_01/RaphiMC and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.event;
import de.florianmichael.viafabricplus.save.SaveManager;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
/**
* This event is fired when ViaFabricPlus has loaded its save files, and before it starts reading the values from the save files.
*/
public interface SaveFilesCallback {
Event<SaveFilesCallback> EVENT = EventFactory.createArrayBacked(SaveFilesCallback.class, listeners -> (saveManager, state) -> {
for (SaveFilesCallback listener : listeners) {
listener.onLoadSaveFiles(saveManager, state);
}
});
void onLoadSaveFiles(final SaveManager saveManager, final State state);
enum State {
PRE, POST
}
}

View File

@ -32,11 +32,11 @@ import de.florianmichael.viafabricplus.protocolhack.provider.viabedrock.ViaFabri
import de.florianmichael.viafabricplus.protocolhack.provider.viabedrock.ViaFabricPlusTransferProvider;
import de.florianmichael.viafabricplus.protocolhack.provider.vialegacy.*;
import de.florianmichael.viafabricplus.protocolhack.provider.viaversion.*;
import de.florianmichael.viafabricplus.settings.impl.GeneralSettings;
import net.raphimc.viabedrock.protocol.providers.BlobCacheProvider;
import net.raphimc.viabedrock.protocol.providers.NettyPipelineProvider;
import net.raphimc.viabedrock.protocol.providers.TransferProvider;
import net.raphimc.vialegacy.protocols.alpha.protocolb1_0_1_1_1toa1_2_3_5_1_2_6.providers.AlphaInventoryProvider;
import net.raphimc.vialegacy.protocols.alpha.protocolb1_0_1_1_1toa1_2_3_5_1_2_6.providers.TrackingAlphaInventoryProvider;
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.providers.ClassicMPPassProvider;
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.providers.ClassicWorldHeightProvider;
import net.raphimc.vialegacy.protocols.release.protocol1_3_1_2to1_2_4_5.providers.OldAuthProvider;
@ -65,11 +65,13 @@ public class ViaFabricPlusVLLoader extends VLLoader {
providers.use(EncryptionProvider.class, new ViaFabricPlusEncryptionProvider());
providers.use(GameProfileFetcher.class, new ViaFabricPlusGameProfileFetcher());
providers.use(ClassicMPPassProvider.class, new ViaFabricPlusClassicMPPassProvider());
providers.use(AlphaInventoryProvider.class, new ViaFabricPlusAlphaInventoryProvider(providers.get(AlphaInventoryProvider.class)));
if (GeneralSettings.global().emulateInventoryActionsInAlphaVersions.getValue()) {
providers.use(AlphaInventoryProvider.class, new ViaFabricPlusAlphaInventoryProvider());
}
providers.use(NettyPipelineProvider.class, new ViaFabricPlusNettyPipelineProvider());
providers.use(BlobCacheProvider.class, new ViaFabricPlusBlobCacheProvider());
providers.use(TransferProvider.class, new ViaFabricPlusTransferProvider());
}
}

View File

@ -34,15 +34,10 @@ import java.util.List;
import static net.raphimc.vialegacy.protocols.alpha.protocolb1_0_1_1_1toa1_2_3_5_1_2_6.Protocolb1_0_1_1_1toa1_2_3_5_1_2_6.copyItems;
public class ViaFabricPlusAlphaInventoryProvider extends AlphaInventoryProvider {
private final AlphaInventoryProvider alphaInventoryProvider;
public ViaFabricPlusAlphaInventoryProvider(final AlphaInventoryProvider alphaInventoryProvider) {
this.alphaInventoryProvider = alphaInventoryProvider;
}
@Override
public boolean usesInventoryTracker() {
return !GeneralSettings.global().emulateInventoryActionsInAlphaVersions.getValue();
return false;
}
protected Item[] getMinecraftContainerItems(final List<ItemStack> trackingItems) {
@ -59,9 +54,7 @@ public class ViaFabricPlusAlphaInventoryProvider extends AlphaInventoryProvider
@Override
public Item[] getMainInventoryItems(UserConnection user) {
if (usesInventoryTracker()) {
return alphaInventoryProvider.getMainInventoryItems(user);
} else if (getPlayer() == null) {
if (getPlayer() == null) {
return new Item[37];
}
@ -70,9 +63,7 @@ public class ViaFabricPlusAlphaInventoryProvider extends AlphaInventoryProvider
@Override
public Item[] getCraftingInventoryItems(UserConnection user) {
if (usesInventoryTracker()) {
return alphaInventoryProvider.getCraftingInventoryItems(user);
} else if (getPlayer() == null) {
if (getPlayer() == null) {
return new Item[4];
}
@ -81,9 +72,7 @@ public class ViaFabricPlusAlphaInventoryProvider extends AlphaInventoryProvider
@Override
public Item[] getArmorInventoryItems(UserConnection user) {
if (usesInventoryTracker()) {
return alphaInventoryProvider.getArmorInventoryItems(user);
} else if (getPlayer() == null) {
if (getPlayer() == null) {
return new Item[4];
}
@ -92,9 +81,7 @@ public class ViaFabricPlusAlphaInventoryProvider extends AlphaInventoryProvider
@Override
public Item[] getContainerItems(UserConnection user) {
if (usesInventoryTracker()) {
return alphaInventoryProvider.getContainerItems(user);
} else if (getPlayer() == null) {
if (getPlayer() == null) {
return new Item[37];
}
@ -103,11 +90,7 @@ public class ViaFabricPlusAlphaInventoryProvider extends AlphaInventoryProvider
@Override
public void addToInventory(UserConnection user, Item item) {
if (usesInventoryTracker()) {
alphaInventoryProvider.addToInventory(user, item);
} else {
getPlayer().getInventory().insertStack(ItemTranslator.viaB1_8toMc(item));
}
getPlayer().getInventory().insertStack(ItemTranslator.viaB1_8toMc(item));
}
protected ClientPlayerEntity getPlayer() {

View File

@ -19,6 +19,7 @@
package de.florianmichael.viafabricplus.save;
import de.florianmichael.viafabricplus.event.SaveFilesCallback;
import de.florianmichael.viafabricplus.save.impl.AccountsSave;
import de.florianmichael.viafabricplus.save.impl.SettingsSave;
import de.florianmichael.viafabricplus.settings.SettingsManager;
@ -34,22 +35,27 @@ public class SaveManager {
private final AccountsSave accountsSave;
public SaveManager(final SettingsManager settingsManager) {
SaveFilesCallback.EVENT.invoker().onLoadSaveFiles(this, SaveFilesCallback.State.PRE);
// Register saves
add(
settingsSave = new SettingsSave(settingsManager),
accountsSave = new AccountsSave()
);
}
public void init() {
// Load save files
for (AbstractSave save : saves) {
save.init();
}
// Save the save files on shutdown
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
for (AbstractSave save : saves) {
save.save();
}
}));
SaveFilesCallback.EVENT.invoker().onLoadSaveFiles(this, SaveFilesCallback.State.POST);
}
public void add(final AbstractSave... saves) {

View File

@ -26,6 +26,8 @@ import net.minecraft.text.Text;
import net.minecraft.util.Util;
import net.minecraft.util.math.MathHelper;
import javax.annotation.Nullable;
/**
* This class is a wrapper for the {@link net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget.Entry} class which provides some global
* functions and features used in all screens which are added by ViaFabricPlus
@ -34,7 +36,14 @@ public abstract class VFPListEntry extends AlwaysSelectedEntryListWidget.Entry<V
protected static final int SCISSORS_OFFSET = 4;
public static final int SLOT_MARGIN = 3;
private DrawContext context;
private int x;
private int y;
private int entryWidth;
private int entryHeight;
public abstract void mappedRender(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta);
public void mappedMouseClicked(double mouseX, double mouseY, int button) {
}
@ -51,15 +60,10 @@ public abstract class VFPListEntry extends AlwaysSelectedEntryListWidget.Entry<V
/**
* Automatically scrolls the text if it is too long to be displayed in the slot. The text will be scrolled from right to left
*
* @param context The {@link DrawContext} of the screen
* @param name The text which should be displayed
* @param x The x position of the slot
* @param y The y position of the slot
* @param entryWidth The width of the slot
* @param entryHeight The height of the slot
* @param name The text which should be displayed
* @param offset The offset of the text from the left side of the slot, this is used to calculate the width of the text, which should be scrolled (Scrolling is enabled when entryWidth - offset < textWidth)
*/
public void renderScrollableText(final DrawContext context, final Text name, final int x, final int y, final int entryWidth, final int entryHeight, final int offset) {
public void renderScrollableText(final Text name, final int offset) {
final var font = MinecraftClient.getInstance().textRenderer;
final var fontWidth = font.getWidth(name);
@ -79,11 +83,31 @@ public abstract class VFPListEntry extends AlwaysSelectedEntryListWidget.Entry<V
}
}
/**
* Draws a tooltip if the mouse is hovering over the slot
*
* @param tooltip The tooltip which should be displayed
* @param mouseX The current mouse X position
* @param mouseY The current mouse Y position
*/
public void renderTooltip(final @Nullable Text tooltip, final int mouseX, final int mouseY) {
if (tooltip != null && mouseX >= x && mouseX <= x + entryWidth && mouseY >= y && mouseY <= y + entryHeight) {
context.drawTooltip(MinecraftClient.getInstance().textRenderer, tooltip, mouseX - x, mouseY - y);
}
}
/**
* Automatically draws a background for the slot with the slot's dimension and calls the {@link #mappedRender(DrawContext, int, int, int, int, int, int, int, boolean, float)} method
*/
@Override
public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
// Allows cross sharing of global variables between util methods
this.context = context;
this.x = x;
this.y = y;
this.entryWidth = entryWidth;
this.entryHeight = entryHeight;
final var matrices = context.getMatrices();
matrices.push();

View File

@ -53,7 +53,10 @@ public class BooleanSettingRenderer extends VFPListEntry {
final Text text = this.value.getValue() ? Text.translatable("base.viafabricplus.on") : Text.translatable("base.viafabricplus.off");
final var offset = textRenderer.getWidth(text) + 6;
renderScrollableText(context, this.value.getName().formatted(Formatting.GRAY), x, y, entryWidth, entryHeight, offset);
renderScrollableText(this.value.getName().formatted(Formatting.GRAY), offset);
context.drawTextWithShadow(textRenderer, text, entryWidth - offset, entryHeight / 2 - textRenderer.fontHeight / 2, this.value.getValue() ? Color.GREEN.getRGB() : Color.RED.getRGB());
renderTooltip(value.getTooltip(), mouseX, mouseY);
}
}

View File

@ -48,5 +48,8 @@ public class ButtonSettingRenderer extends VFPListEntry {
final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
context.drawCenteredTextWithShadow(textRenderer, this.value.displayValue(), entryWidth / 2, entryHeight / 2 - textRenderer.fontHeight / 2, -1);
renderTooltip(value.getTooltip(), mouseX, mouseY);
}
}

View File

@ -52,7 +52,10 @@ public class ModeSettingRenderer extends VFPListEntry {
final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
final var offset = textRenderer.getWidth(this.value.getValue()) + 6;
renderScrollableText(context, this.value.getName().formatted(Formatting.GRAY), x, y, entryWidth, entryHeight, offset);
renderScrollableText(this.value.getName().formatted(Formatting.GRAY), offset);
context.drawTextWithShadow(textRenderer, this.value.getValue(), entryWidth - offset, entryHeight / 2 - textRenderer.fontHeight / 2, -1);
renderTooltip(value.getTooltip(), mouseX, mouseY);
}
}

View File

@ -55,4 +55,5 @@ public class TitleRenderer extends VFPListEntry {
context.drawTextWithShadow(textRenderer, this.name.copy().formatted(Formatting.BOLD), 3, entryHeight / 2 - textRenderer.fontHeight / 2, -1);
}
}

View File

@ -55,7 +55,10 @@ public class VersionedBooleanSettingRenderer extends VFPListEntry {
Color color = this.value.isAuto() ? Color.ORANGE : this.value.isEnabled() ? Color.GREEN : Color.RED;
final var offset = textRenderer.getWidth(text) + 6;
renderScrollableText(context, Text.of(Formatting.GRAY + this.value.getName().getString() + " " + Formatting.RESET + this.value.getProtocolRange().toString()), x, y, entryWidth, entryHeight, offset);
renderScrollableText(Text.of(Formatting.GRAY + this.value.getName().getString() + " " + Formatting.RESET + this.value.getProtocolRange().toString()), offset);
context.drawTextWithShadow(textRenderer, text, entryWidth - offset, entryHeight / 2 - textRenderer.fontHeight / 2, color.getRGB());
renderTooltip(value.getTooltip(), mouseX, mouseY);
}
}

View File

@ -31,7 +31,7 @@ public class SettingsManager {
private final List<SettingGroup> groups = new ArrayList<>();
public SettingsManager() {
RegisterSettingsCallback.EVENT.invoker().onInitializeSettings(RegisterSettingsCallback.State.PRE);
RegisterSettingsCallback.EVENT.invoker().onRegisterSettings(this, RegisterSettingsCallback.State.PRE);
addGroup(
GeneralSettings.global(),
@ -41,7 +41,7 @@ public class SettingsManager {
DebugSettings.global()
);
RegisterSettingsCallback.EVENT.invoker().onInitializeSettings(RegisterSettingsCallback.State.POST);
RegisterSettingsCallback.EVENT.invoker().onRegisterSettings(this, RegisterSettingsCallback.State.POST);
}
public void addGroup(final SettingGroup... groups) {

View File

@ -23,6 +23,7 @@ import com.google.gson.JsonObject;
import de.florianmichael.viafabricplus.screen.base.VFPListEntry;
import de.florianmichael.viafabricplus.util.ChatUtil;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
/**
* This class is the base for all settings. It contains the name, the default value and the current value.
@ -36,6 +37,8 @@ public abstract class AbstractSetting<T> {
private T value;
private Text tooltip;
public AbstractSetting(final SettingGroup parent, final MutableText name, final T defaultValue) {
this.name = name;
this.defaultValue = defaultValue;
@ -87,4 +90,12 @@ public abstract class AbstractSetting<T> {
this.value = value;
}
public Text getTooltip() {
return tooltip;
}
public void setTooltip(Text tooltip) {
this.tooltip = tooltip;
}
}

View File

@ -60,6 +60,7 @@ public class GeneralSettings extends SettingGroup {
public GeneralSettings() {
super(Text.translatable("setting_group_name.viafabricplus.general"));
emulateInventoryActionsInAlphaVersions.setTooltip(Text.translatable("base.viafabricplus.this_will_require_a_restart"));
}
public static GeneralSettings global() {
@ -75,4 +76,5 @@ public class GeneralSettings extends SettingGroup {
default -> builder;
};
}
}

View File

@ -25,6 +25,7 @@
"base.viafabricplus.cancel_and_notify": "Cancel and notify",
"base.viafabricplus.force_version_title": "Please select the version with which the server should be pinged/connected",
"base.viafabricplus.detecting_server_version": "Detecting server version...",
"base.viafabricplus.this_will_require_a_restart": "This will require a restart!",
"setting_group_name.viafabricplus.authentication": "Authentication",
"setting_group_name.viafabricplus.visual": "Visual",