changing the server

This commit is contained in:
zelophed 2021-04-15 15:44:26 +02:00
parent fdbdf0ec8d
commit 01e5b812c2
19 changed files with 230 additions and 29 deletions

View file

@ -17,7 +17,7 @@ public class ConfigCommand {
ServerPlayerEntity player = ctx.getSource().asPlayer();
AllPackets.channel.send(
PacketDistributor.PLAYER.with(() -> player),
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.configScreen.name(), "")
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.configScreen.name(), "")
);
return Command.SINGLE_SUCCESS;

View file

@ -19,7 +19,7 @@ public class FabulousWarningCommand {
AllPackets.channel.send(
PacketDistributor.PLAYER.with(() -> player),
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.fabulousWarning.name(), "")
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.fabulousWarning.name(), "")
);
return Command.SINGLE_SUCCESS;

View file

@ -17,7 +17,7 @@ public class FixLightingCommand {
.executes(ctx -> {
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource()
.getEntity()),
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.fixLighting.name(), String.valueOf(true)));
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.fixLighting.name(), String.valueOf(true)));
ctx.getSource()
.sendFeedback(

View file

@ -18,12 +18,12 @@ public class OverlayConfigCommand {
.requires(cs -> cs.hasPermissionLevel(0))
.then(Commands.literal("reset")
.executes(ctx -> {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ConfigureConfigPacket.Actions.overlayReset.performAction(""));
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> SConfigureConfigPacket.Actions.overlayReset.performAction(""));
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () ->
AllPackets.channel.send(
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()),
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.overlayReset.name(), "")));
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.overlayReset.name(), "")));
ctx.getSource().sendFeedback(new StringTextComponent("reset overlay offset"), true);
@ -31,12 +31,12 @@ public class OverlayConfigCommand {
})
)
.executes(ctx -> {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ConfigureConfigPacket.Actions.overlayScreen.performAction(""));
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> SConfigureConfigPacket.Actions.overlayScreen.performAction(""));
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () ->
AllPackets.channel.send(
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()),
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.overlayScreen.name(), "")));
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.overlayScreen.name(), "")));
ctx.getSource().sendFeedback(new StringTextComponent("window opened"), true);

View file

@ -48,7 +48,7 @@ public class PonderCommand {
AllPackets.channel.send(
PacketDistributor.PLAYER.with(() -> player),
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.openPonder.name(), sceneId));
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.openPonder.name(), sceneId));
}
return Command.SINGLE_SUCCESS;
}

View file

@ -30,17 +30,17 @@ import org.apache.logging.log4j.LogManager;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class ConfigureConfigPacket extends SimplePacketBase {
public class SConfigureConfigPacket extends SimplePacketBase {
private final String option;
private final String value;
public ConfigureConfigPacket(String option, String value) {
public SConfigureConfigPacket(String option, String value) {
this.option = option;
this.value = value;
}
public ConfigureConfigPacket(PacketBuffer buffer) {
public SConfigureConfigPacket(PacketBuffer buffer) {
this.option = buffer.readString(32767);
this.value = buffer.readString(32767);
}
@ -68,7 +68,7 @@ public class ConfigureConfigPacket extends SimplePacketBase {
.setPacketHandled(true);
}
enum Actions {
public enum Actions {
configScreen(() -> Actions::configScreen),
rainbowDebug(() -> Actions::rainbowDebug),
overlayScreen(() -> Actions::overlayScreen),

View file

@ -14,7 +14,7 @@ public class ToggleDebugCommand extends ConfigureConfigCommand {
protected void sendPacket(ServerPlayerEntity player, String option) {
AllPackets.channel.send(
PacketDistributor.PLAYER.with(() -> player),
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.rainbowDebug.name(), option)
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.rainbowDebug.name(), option)
);
}
}

View file

@ -14,7 +14,7 @@ public class ToggleExperimentalRenderingCommand extends ConfigureConfigCommand {
protected void sendPacket(ServerPlayerEntity player, String option) {
AllPackets.channel.send(
PacketDistributor.PLAYER.with(() -> player),
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.experimentalRendering.name(), option)
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.experimentalRendering.name(), option)
);
}
}

View file

@ -56,7 +56,7 @@ public class BaseConfigScreen extends ConfigScreen {
);
if (Minecraft.getInstance().world != null) {
serverConfigWidget.withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.SERVER.specification)));
serverConfigWidget.withCallback(() -> ScreenOpener.transitionTo(new ServerSubMenuConfigScreen(this, AllConfigs.SERVER.specification)));
} else {
serverConfigWidget.active = false;
serverConfigWidget.updateColorsFromState();

View file

@ -0,0 +1,83 @@
package com.simibubi.create.foundation.config.ui;
import java.util.function.Supplier;
import com.simibubi.create.foundation.command.SConfigureConfigPacket;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.network.PacketDistributor;
public class CConfigureConfigPacket<T> extends SimplePacketBase {
private String path;
private String value;
public CConfigureConfigPacket(String path, T value) {
this.path = path;
this.value = serialize(value);
}
public CConfigureConfigPacket(PacketBuffer buffer) {
this.path = buffer.readString(32767);
this.value = buffer.readString(32767);
}
@Override
public void write(PacketBuffer buffer) {
buffer.writeString(path);
buffer.writeString(value);
}
@Override
public void handle(Supplier<NetworkEvent.Context> context) {
ServerPlayerEntity sender = context.get().getSender();
if (sender == null || !sender.hasPermissionLevel(2))
return;
ForgeConfigSpec.ValueSpec valueSpec = AllConfigs.SERVER.specification.getRaw(path);
ForgeConfigSpec.ConfigValue<T> configValue = AllConfigs.SERVER.specification.getValues().get(path);
T v = (T) deserialize(configValue.get(), value);
if (!valueSpec.test(v))
return;
configValue.set(v);
}
public String serialize(T value) {
if (value instanceof Boolean)
return Boolean.toString((Boolean) value);
if (value instanceof Enum<?>)
return ((Enum<?>) value).name();
if (value instanceof Integer)
return Integer.toString((Integer) value);
if (value instanceof Float)
return Float.toString((Float) value);
if (value instanceof Double)
return Double.toString((Double) value);
throw new IllegalArgumentException("unknown type " + value + ": " + value.getClass().getSimpleName());
}
public Object deserialize(Object type, String sValue) {
if (type instanceof Boolean)
return Boolean.parseBoolean(sValue);
if (type instanceof Enum<?>)
return Enum.valueOf(((Enum<?>) type).getClass(), sValue);
if (type instanceof Integer)
return Integer.parseInt(sValue);
if (type instanceof Float)
return Float.parseFloat(sValue);
if (type instanceof Double)
return Double.parseDouble(sValue);
throw new IllegalArgumentException("unknown type " + type + ": " + type.getClass().getSimpleName());
}
}

View file

@ -25,7 +25,22 @@ import com.simibubi.create.foundation.utility.animation.PhysicalFloat;
public abstract class ConfigScreen extends NavigatableSimiScreen {
private final Screen parent;
/*
* TODO unable to edit feedback message
* TODO overlays for better descriptions
* TODO units at the end of the text box
* TODO match style with ponderUI
* TODO cache changes before setting values and saving to file
* TODO don't exit on ESC
* TODO reset text field focus for any click inside screen
* TODO adjust transition animation of screens
* TODO allow backspace in text fields
*
* TODO some color themes maybe?
*
* */
protected final Screen parent;
protected static final PhysicalFloat cogSpin = PhysicalFloat.create().withDrag(0.3).addForce(new Force.Static(.2f));
protected static final BlockState cogwheelState = AllBlocks.LARGE_COGWHEEL.getDefaultState().with(CogWheelBlock.AXIS, Direction.Axis.Y);

View file

@ -1,7 +1,6 @@
package com.simibubi.create.foundation.config.ui;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.mojang.blaze3d.matrix.MatrixStack;
@ -13,11 +12,16 @@ import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget;
import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.gui.widget.list.ExtendedList;
import net.minecraft.util.text.IFormattableTextComponent;
public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
public TextFieldWidget currentText;
public boolean isForServer = false;
public ConfigScreenList(Minecraft client, int width, int height, int top, int bottom, int elementHeight) {
super(client, width, height, top, bottom, elementHeight);
func_244605_b(false);
@ -87,6 +91,14 @@ public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
public boolean charTyped(char ch, int code) {
return getGuiListeners().stream().anyMatch(l -> l.charTyped(ch, code));
}
protected void setEditable(boolean b) {}
protected boolean isForServer() {
if (list == null)
return false;
return ((ConfigScreenList) list).isForServer;
}
}
public static class LabeledEntry extends Entry {

View file

@ -0,0 +1,52 @@
package com.simibubi.create.foundation.config.ui;
import com.electronwill.nightconfig.core.UnmodifiableConfig;
import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.gui.DelegatedStencilElement;
import com.simibubi.create.foundation.gui.UIRenderHelper;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.ponder.ui.PonderButton;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.common.ForgeConfigSpec;
public class ServerSubMenuConfigScreen extends SubMenuConfigScreen {
protected PonderButton missingPermissions = null;
public ServerSubMenuConfigScreen(Screen parent, ForgeConfigSpec configSpec) {
super(parent, configSpec);
}
public ServerSubMenuConfigScreen(Screen parent, ForgeConfigSpec configSpec, UnmodifiableConfig configGroup) {
super(parent, configSpec, configGroup);
}
@Override
protected void init() {
super.init();
list.isForServer = true;
if (client != null && client.player != null && client.player.hasPermissionLevel(2))
return;
list.children().forEach(e -> e.setEditable(false));
int col1 = 0xff_f78888;
int col2 = 0xff_cc2020;
missingPermissions = new PonderButton(width - 30, height - 50, () -> {})
.showing(new DelegatedStencilElement()
.withStencilRenderer((ms, w, h) -> AllIcons.I_MTD_CLOSE.draw(ms, 0, 0))
.withElementRenderer((ms, w, h) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, col1, col2))
).customColors(col1, col2);
missingPermissions.fade(1);
missingPermissions.getToolTip().add(new StringTextComponent("Locked").formatted(TextFormatting.BOLD));
missingPermissions.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You don't have enough permissions to edit the server config. You can still look at the current values here though.", TextFormatting.GRAY, TextFormatting.GRAY));
widgets.add(missingPermissions);
}
}

View file

@ -42,6 +42,13 @@ public class BooleanEntry extends ValueEntry<Boolean> {
onReset();
}
@Override
protected void setEditable(boolean b) {
super.setEditable(b);
button.active = b;
button.animateGradientFromState();
}
@Override
public void tick() {
super.tick();

View file

@ -41,6 +41,15 @@ public class EnumEntry extends ValueEntry<Enum<?>> {
onValueChange();
}
@Override
protected void setEditable(boolean b) {
super.setEditable(b);
cycleLeft.active = b;
cycleLeft.animateGradientFromState();
cycleRight.active = b;
cycleRight.animateGradientFromState();
}
@Override
public void tick() {
super.tick();

View file

@ -59,8 +59,8 @@ public abstract class NumberEntry<T extends Number> extends ValueEntry<T> {
maxText = new TextStencilElement(font, t).centered(true, false);
maxOffset = font.getWidth(t);
}
} catch (NoSuchFieldException | IllegalAccessException | ClassCastException e) {
e.printStackTrace();
} catch (NoSuchFieldException | IllegalAccessException | ClassCastException | NullPointerException ignored) {
}
textField.setResponder(s -> {
@ -94,6 +94,12 @@ public abstract class NumberEntry<T extends Number> extends ValueEntry<T> {
protected abstract Function<String, T> getParser();
@Override
protected void setEditable(boolean b) {
super.setEditable(b);
textField.setEnabled(b);
}
@Override
protected void onReset() {
super.onReset();

View file

@ -4,6 +4,7 @@ import com.electronwill.nightconfig.core.UnmodifiableConfig;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.config.ui.ConfigButton;
import com.simibubi.create.foundation.config.ui.ConfigScreenList;
import com.simibubi.create.foundation.config.ui.ServerSubMenuConfigScreen;
import com.simibubi.create.foundation.config.ui.SubMenuConfigScreen;
import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.gui.TextStencilElement;
@ -20,7 +21,10 @@ public class SubMenuEntry extends ConfigScreenList.LabeledEntry {
super(label);
TextStencilElement text = new TextStencilElement(Minecraft.getInstance().fontRenderer, "Click to open").centered(true, true);
button = ConfigButton.createFromStencilElement(0, 0, text)
.withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(parent, spec, config)));
.withCallback(() -> ScreenOpener.transitionTo(isForServer() ?
new ServerSubMenuConfigScreen(parent, spec, config) :
new SubMenuConfigScreen(parent, spec, config)
));
listeners.add(button);
}

View file

@ -1,9 +1,11 @@
package com.simibubi.create.foundation.config.ui.entries;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.config.ui.CConfigureConfigPacket;
import com.simibubi.create.foundation.config.ui.ConfigButton;
import com.simibubi.create.foundation.config.ui.ConfigScreenList;
import com.simibubi.create.foundation.gui.TextStencilElement;
import com.simibubi.create.foundation.networking.AllPackets;
import net.minecraft.client.Minecraft;
import net.minecraftforge.common.ForgeConfigSpec;
@ -15,6 +17,7 @@ public class ValueEntry<T> extends ConfigScreenList.LabeledEntry {
protected ForgeConfigSpec.ConfigValue<T> value;
protected ForgeConfigSpec.ValueSpec spec;
protected ConfigButton reset;
protected boolean editable = true;
public ValueEntry(String label, ForgeConfigSpec.ConfigValue<T> value, ForgeConfigSpec.ValueSpec spec) {
super(label);
@ -32,6 +35,13 @@ public class ValueEntry<T> extends ConfigScreenList.LabeledEntry {
listeners.add(reset);
}
@Override
protected void setEditable(boolean b) {
editable = b;
reset.active = editable && !value.get().equals(spec.getDefault());
reset.animateGradientFromState();
}
@Override
public void tick() {
reset.tick();
@ -51,23 +61,24 @@ public class ValueEntry<T> extends ConfigScreenList.LabeledEntry {
return (int) (totalWidth * labelWidthMult);
}
/*@Override
public boolean mouseClicked(double mX, double mY, int button) {
return reset.mouseClicked(mX, mY, button);
}*/
protected void onReset() {
onValueChange();
}
protected void onValueChange() {
reset.active = !value.get().equals(spec.getDefault());
reset.active = editable && !value.get().equals(spec.getDefault());
reset.animateGradientFromState();
if (!isForServer())
return;
String path = String.join(".", value.getPath());
AllPackets.channel.sendToServer(new CConfigureConfigPacket<>(path, value.get()));
}
protected void bumpCog() {bumpCog(10f);}
protected void bumpCog(float force) {
if (list != null && list instanceof ConfigScreenList)
((ConfigScreenList) list).bumpCog(force);
((ConfigScreenList) list).bumpCog(force);
}
}

View file

@ -38,8 +38,9 @@ import com.simibubi.create.content.schematics.packet.InstantSchematicPacket;
import com.simibubi.create.content.schematics.packet.SchematicPlacePacket;
import com.simibubi.create.content.schematics.packet.SchematicSyncPacket;
import com.simibubi.create.content.schematics.packet.SchematicUploadPacket;
import com.simibubi.create.foundation.command.ConfigureConfigPacket;
import com.simibubi.create.foundation.command.SConfigureConfigPacket;
import com.simibubi.create.foundation.command.HighlightPacket;
import com.simibubi.create.foundation.config.ui.CConfigureConfigPacket;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket;
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket;
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
@ -79,12 +80,13 @@ public enum AllPackets {
PLACE_EJECTOR(EjectorPlacementPacket.class, EjectorPlacementPacket::new, PLAY_TO_SERVER),
TRIGGER_EJECTOR(EjectorTriggerPacket.class, EjectorTriggerPacket::new, PLAY_TO_SERVER),
EJECTOR_ELYTRA(EjectorElytraPacket.class, EjectorElytraPacket::new, PLAY_TO_SERVER),
C_CONFIGURE_CONFIG(CConfigureConfigPacket.class, CConfigureConfigPacket::new, PLAY_TO_SERVER),
// Server to Client
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),
SERVER_SPEED(ServerSpeedProvider.Packet.class, ServerSpeedProvider.Packet::new, PLAY_TO_CLIENT),
BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new, PLAY_TO_CLIENT),
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new, PLAY_TO_CLIENT),
S_CONFIGURE_CONFIG(SConfigureConfigPacket.class, SConfigureConfigPacket::new, PLAY_TO_CLIENT),
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new, PLAY_TO_CLIENT),
CONTRAPTION_DISASSEMBLE(ContraptionDisassemblyPacket.class, ContraptionDisassemblyPacket::new, PLAY_TO_CLIENT),
GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new, PLAY_TO_CLIENT),