diff --git a/gradle.properties b/gradle.properties index 30ecd7c..5105ad4 100755 --- a/gradle.properties +++ b/gradle.properties @@ -5,10 +5,10 @@ org.gradle.jvmargs=-Xmx1G # check these on https://fabricmc.net/use minecraft_version=1.17.1 yarn_mappings=1.17.1+build.61 - loader_version=0.11.7 + loader_version=0.14.6 # Mod Properties - mod_version = 1.3.0 + mod_version = 1.4.0 maven_group = eu.midnightdust archives_base_name = picturesign diff --git a/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java b/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java index 983bf9a..5b77e34 100755 --- a/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java +++ b/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java @@ -2,13 +2,72 @@ package eu.midnightdust.picturesign; import eu.midnightdust.picturesign.config.PictureSignConfig; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; +import net.minecraft.block.entity.SignBlockEntity; +import net.minecraft.client.gui.screen.ingame.SignEditScreen; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.util.InputUtil; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.BlockPos; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.lwjgl.glfw.GLFW; public class PictureSignClient implements ClientModInitializer { public static Logger LOGGER = LogManager.getLogger("PictureSign"); + public static String[] clipboard = new String[4]; + public static final KeyBinding BINDING_EDIT_SIGN = new KeyBinding("key.picturesign.edit_sign", + InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_C, "key.categories.picturesign"); + public static final KeyBinding BINDING_COPY_SIGN = new KeyBinding("key.picturesign.copy_sign", + InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_U, "key.categories.picturesign"); @Override public void onInitializeClient() { PictureSignConfig.init("picturesign", PictureSignConfig.class); + + KeyBindingHelper.registerKeyBinding(BINDING_COPY_SIGN); + + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (!PictureSignClient.BINDING_COPY_SIGN.isPressed()) return; + PictureSignClient.BINDING_COPY_SIGN.setPressed(false); + if (client.player == null || client.crosshairTarget == null || client.crosshairTarget.getType() != HitResult.Type.BLOCK) return; + if (client.crosshairTarget.getType() == HitResult.Type.BLOCK && client.world.getBlockState(new BlockPos(client.crosshairTarget.getPos())).hasBlockEntity()) { + if (client.world.getBlockEntity(new BlockPos(client.crosshairTarget.getPos())) instanceof SignBlockEntity) { + SignBlockEntity sign = (SignBlockEntity) client.world.getBlockEntity(new BlockPos(client.crosshairTarget.getPos())); + clipboard[0] = sign.getTextOnRow(0, false).asString(); + clipboard[1] = sign.getTextOnRow(1, false).asString(); + clipboard[2] = sign.getTextOnRow(2, false).asString(); + clipboard[3] = sign.getTextOnRow(3, false).asString(); + } + } + }); + if (PictureSignConfig.debug) { + KeyBindingHelper.registerKeyBinding(BINDING_EDIT_SIGN); + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (!PictureSignClient.BINDING_EDIT_SIGN.isPressed()) return; + PictureSignClient.BINDING_EDIT_SIGN.setPressed(false); + if (client.player == null || client.crosshairTarget == null || client.crosshairTarget.getType() != HitResult.Type.BLOCK) return; + if (client.crosshairTarget.getType() == HitResult.Type.BLOCK && client.world.getBlockState(new BlockPos(client.crosshairTarget.getPos())).hasBlockEntity()) { + if (client.world.getBlockEntity(new BlockPos(client.crosshairTarget.getPos())) instanceof SignBlockEntity) { + BlockPos pos = new BlockPos(client.crosshairTarget.getPos()); + SignBlockEntity sign = (SignBlockEntity) client.world.getBlockEntity(pos); + sign.setEditable(true); + sign.setEditor(client.player.getUuid()); + sign.toUpdatePacket(); + sign.markDirty(); + client.world.updateListeners(pos, sign.getCachedState(), sign.getCachedState(), 3); + client.setScreen(new SignEditScreen(sign,false)); +// clipboard[0] = sign.getTextOnRow(0, false).asString(); +// clipboard[1] = sign.getTextOnRow(1, false).asString(); +// clipboard[2] = sign.getTextOnRow(2, false).asString(); +// clipboard[3] = sign.getTextOnRow(3, false).asString(); +// Block signBlock = sign.getCachedState().getBlock(); +// client.interactionManager.breakBlock(pos); +// client.player.setStackInHand(client.player.preferredHand, new ItemStack(signBlock.asItem())); +// client.interactionManager.interactBlock(client.player, client.world, client.player.preferredHand, new BlockHitResult(new Vec3d(pos.getX(), pos.getY(), pos.getZ()), Direction.DOWN, pos,false)); + } + } + }); + } } } diff --git a/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java b/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java index 02c29d8..0cb683c 100755 --- a/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java +++ b/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java @@ -4,6 +4,9 @@ import eu.midnightdust.lib.config.MidnightConfig; public class PictureSignConfig extends MidnightConfig { @Entry public static boolean enabled = true; + @Entry public static boolean translucency = false; + @Entry public static boolean helperUi = true; + @Entry public static boolean exceedVanillaLineLength = false; @Entry public static boolean debug = false; @Entry(min = 1, max = 10) public static int maxThreads = 4; @Entry(min = 0, max = 4096) public static int signRenderDistance = 64; diff --git a/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java b/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java new file mode 100644 index 0000000..f731775 --- /dev/null +++ b/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java @@ -0,0 +1,64 @@ +package eu.midnightdust.picturesign.mixin; + +import eu.midnightdust.lib.util.screen.TexturedOverlayButtonWidget; +import eu.midnightdust.picturesign.PictureSignClient; +import eu.midnightdust.picturesign.config.PictureSignConfig; +import eu.midnightdust.picturesign.screen.PictureSignHelperScreen; +import net.minecraft.block.entity.SignBlockEntity; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.SignEditScreen; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Objects; + +@Mixin(SignEditScreen.class) +public abstract class MixinSignEditScreen extends Screen { + private static final Identifier PICTURESIGN_ICON_TEXTURE = new Identifier("picturesign","textures/gui/picturesign_button.png"); + private static final Identifier CLIPBOARD_ICON_TEXTURE = new Identifier("picturesign","textures/gui/clipboard_button.png"); + private static final Identifier TRASHBIN_ICON_TEXTURE = new Identifier("picturesign","textures/gui/trashbin_button.png"); + @Shadow @Final private SignBlockEntity sign; + + @Shadow @Final private String[] text; + + protected MixinSignEditScreen(Text title) { + super(title); + } + + @Inject(at = @At("TAIL"),method = "init") + private void picturesign$init(CallbackInfo ci) { + if (PictureSignClient.clipboard != null && PictureSignClient.clipboard[0] != null) + this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 84, this.height - 40, 20, 20, 0, 0, 20, CLIPBOARD_ICON_TEXTURE, 32, 64, (buttonWidget) -> { + sign.setTextOnRow(0, Text.of(PictureSignClient.clipboard[0])); + sign.setTextOnRow(1, Text.of(PictureSignClient.clipboard[1])); + sign.setTextOnRow(2, Text.of(PictureSignClient.clipboard[2])); + sign.setTextOnRow(3, Text.of(PictureSignClient.clipboard[3])); + text[0] = PictureSignClient.clipboard[0]; + text[1] = PictureSignClient.clipboard[1]; + text[2] = PictureSignClient.clipboard[2]; + text[3] = PictureSignClient.clipboard[3]; + }, Text.of(""))); + if (PictureSignConfig.helperUi) + this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 62, this.height - 40, 20, 20, 0, 0, 20, TRASHBIN_ICON_TEXTURE, 32, 64, (buttonWidget) -> { + sign.setTextOnRow(0, Text.of("")); + sign.setTextOnRow(1, Text.of("")); + sign.setTextOnRow(2, Text.of("")); + sign.setTextOnRow(3, Text.of("")); + text[0] = ""; + text[1] = ""; + text[2] = ""; + text[3] = ""; + }, Text.of(""))); + if (PictureSignConfig.helperUi) + this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 40, this.height - 40, 20, 20, 0, 0, 20, PICTURESIGN_ICON_TEXTURE, 32, 64, (buttonWidget) -> { + sign.setEditable(true); + Objects.requireNonNull(client).setScreen(new PictureSignHelperScreen(this.sign,false)); + }, Text.of(""))); + } +} diff --git a/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java b/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java index 2aaa6ef..f719a68 100755 --- a/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java +++ b/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java @@ -3,6 +3,7 @@ package eu.midnightdust.picturesign.render; import com.mojang.blaze3d.systems.RenderSystem; import eu.midnightdust.picturesign.PictureDownloader; import eu.midnightdust.picturesign.config.PictureSignConfig; +import eu.midnightdust.picturesign.util.PictureURLUtils; import net.fabricmc.loader.api.FabricLoader; import net.irisshaders.iris.api.v0.IrisApi; import net.minecraft.block.Blocks; @@ -19,21 +20,20 @@ import java.util.List; public class PictureSignRenderer { public void render(SignBlockEntity signBlockEntity, MatrixStack matrixStack, int light, int overlay) { - String text = signBlockEntity.getTextOnRow(0, false).getString() + - signBlockEntity.getTextOnRow(1, false).getString() + - signBlockEntity.getTextOnRow(2, false).getString(); - String url = text.replaceAll("!PS:", "").replaceAll(" ",""); - if (url.contains("imgur:")) url = url.replace("imgur:", "https://i.imgur.com/"); - if (url.contains("imgbb:")) url = url.replace("imgbb:", "https://i.ibb.co/"); - if (!url.contains("https://") && !url.contains("http://")) { + String url = PictureURLUtils.getLink(signBlockEntity); + if (!url.startsWith("https://") && !url.startsWith("http://")) { url = "https://" + url; } if (!url.contains(".png") && !url.contains(".jpg") && !url.contains(".jpeg")) return; - if (PictureSignConfig.safeMode && !url.contains("//i.imgur.com/") && !url.contains("//i.ibb.co/")) return; + if (PictureSignConfig.safeMode && !url.startsWith("https://i.imgur.com/") && !url.startsWith("https://i.ibb.co/") + && !url.startsWith("https://pictshare.net/") && !url.startsWith("https://iili.io/")) + return; World world = signBlockEntity.getWorld(); BlockPos pos = signBlockEntity.getPos(); - if (world != null && (world.getBlockState(pos.down()).getBlock().equals(Blocks.REDSTONE_TORCH) || world.getBlockState(pos.down()).getBlock().equals(Blocks.REDSTONE_WALL_TORCH)) && world.getBlockState(pos.down()).get(Properties.LIT).equals(false)) return; - if (world != null && (world.getBlockState(pos.up()).getBlock().equals(Blocks.REDSTONE_TORCH) || world.getBlockState(pos.up()).getBlock().equals(Blocks.REDSTONE_WALL_TORCH)) && world.getBlockState(pos.up()).get(Properties.LIT).equals(false)) return; + if (world != null && (world.getBlockState(pos.down()).getBlock().equals(Blocks.REDSTONE_TORCH) || world.getBlockState(pos.down()).getBlock().equals(Blocks.REDSTONE_WALL_TORCH)) + && world.getBlockState(pos.down()).get(Properties.LIT).equals(false)) return; + if (world != null && (world.getBlockState(pos.up()).getBlock().equals(Blocks.REDSTONE_TORCH) || world.getBlockState(pos.up()).getBlock().equals(Blocks.REDSTONE_WALL_TORCH)) + && world.getBlockState(pos.up()).get(Properties.LIT).equals(false)) return; String lastLine = signBlockEntity.getTextOnRow(3, false).getString(); @@ -107,7 +107,8 @@ public class PictureSignRenderer { } RenderSystem.setShaderTexture(0, data.identifier); - RenderSystem.enableBlend(); + if (PictureSignConfig.translucency) RenderSystem.enableBlend(); + else RenderSystem.disableBlend(); RenderSystem.enableDepthTest(); RenderSystem.depthMask(true); diff --git a/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java b/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java new file mode 100644 index 0000000..132462b --- /dev/null +++ b/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java @@ -0,0 +1,305 @@ +package eu.midnightdust.picturesign.screen; + +import eu.midnightdust.lib.util.MidnightColorUtil; +import eu.midnightdust.lib.util.screen.TexturedOverlayButtonWidget; +import eu.midnightdust.picturesign.PictureSignClient; +import eu.midnightdust.picturesign.config.PictureSignConfig; +import eu.midnightdust.picturesign.util.PictureURLUtils; +import net.minecraft.block.BlockState; +import net.minecraft.block.SignBlock; +import net.minecraft.block.entity.SignBlockEntity; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ScreenTexts; +import net.minecraft.client.gui.screen.ingame.SignEditScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.client.render.*; +import net.minecraft.client.render.block.entity.SignBlockEntityRenderer; +import net.minecraft.client.util.SpriteIdentifier; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.Matrix4f; + +import java.util.Objects; +import java.util.stream.IntStream; + +public class PictureSignHelperScreen extends Screen { + private static final Identifier TEXTSIGN_ICON_TEXTURE = new Identifier("picturesign","textures/gui/textsign_button.png"); + private static final Identifier CLIPBOARD_ICON_TEXTURE = new Identifier("picturesign","textures/gui/clipboard_button.png"); + private static final Identifier TRASHBIN_ICON_TEXTURE = new Identifier("picturesign","textures/gui/trashbin_button.png"); + private final SignBlockEntity sign; + private SignBlockEntityRenderer.SignModel model; + private String[] text; + + public PictureSignHelperScreen(SignBlockEntity sign, boolean filtered) { + super(new TranslatableText("sign.edit")); + this.text = IntStream.range(0, 4).mapToObj((row) -> + sign.getTextOnRow(row, filtered)).map(Text::getString).toArray(String[]::new); + this.sign = sign; + } + protected void init() { + super.init(); + sign.setEditable(false); + if (!sign.getTextOnRow(3,false).asString().matches("(.*\\d:.*\\d:.*\\d:.*\\d:.*\\d)")) sign.setTextOnRow(3, Text.of("1:1:0:0:0")); + if (!sign.getTextOnRow(0, false).asString().startsWith("!PS:")) sign.setTextOnRow(0, Text.of("!PS:")); + text = IntStream.range(0, 4).mapToObj((row) -> + sign.getTextOnRow(row, false)).map(Text::getString).toArray(String[]::new); + this.addDrawableChild(new ButtonWidget(this.width / 2 - 100, this.height / 4 + 120, 200, 20, ScreenTexts.DONE, (button) -> { + this.finishEditing(); + })); + + if (PictureSignClient.clipboard != null && PictureSignClient.clipboard[0] != null) + this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 84, this.height - 40, 20, 20, 0, 0, 20, CLIPBOARD_ICON_TEXTURE, 32, 64, (buttonWidget) -> { + sign.setTextOnRow(0, Text.of(PictureSignClient.clipboard[0])); + sign.setTextOnRow(1, Text.of(PictureSignClient.clipboard[1])); + sign.setTextOnRow(2, Text.of(PictureSignClient.clipboard[2])); + sign.setTextOnRow(3, Text.of(PictureSignClient.clipboard[3])); + text[0] = PictureSignClient.clipboard[0]; + text[1] = PictureSignClient.clipboard[1]; + text[2] = PictureSignClient.clipboard[2]; + text[3] = PictureSignClient.clipboard[3]; + assert client != null; + client.setScreen(this); + }, Text.of(""))); + if (PictureSignConfig.helperUi) + this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 62, this.height - 40, 20, 20, 0, 0, 20, TRASHBIN_ICON_TEXTURE, 32, 64, (buttonWidget) -> { + sign.setTextOnRow(0, Text.of("")); + sign.setTextOnRow(1, Text.of("")); + sign.setTextOnRow(2, Text.of("")); + sign.setTextOnRow(3, Text.of("")); + text[0] = ""; + text[1] = ""; + text[2] = ""; + text[3] = ""; + assert client != null; + client.setScreen(this); + }, Text.of(""))); + this.addDrawableChild(new TexturedOverlayButtonWidget(this.width - 40, this.height - 40, 20, 20, 0, 0, 20, TEXTSIGN_ICON_TEXTURE, 32, 64, (buttonWidget) -> { + sign.setEditable(true); + Objects.requireNonNull(client).setScreen(new SignEditScreen(this.sign,false)); + }, Text.of(""))); + TextFieldWidget linkWidget = new TextFieldWidget(textRenderer,this.width / 2 - 175,this.height / 5 + 13,210,40, Text.of("url")); + linkWidget.setMaxLength(90); + linkWidget.setText(PictureURLUtils.getLink(sign)); + linkWidget.setChangedListener(s -> { + String[] lines = breakLink(PictureURLUtils.shortenLink(s)); + sign.setTextOnRow(0, Text.of(lines[0])); + sign.setTextOnRow(1, Text.of(lines[1])); + sign.setTextOnRow(2, Text.of(lines[2])); + + text = IntStream.range(0, 4).mapToObj((row) -> + sign.getTextOnRow(row, false)).map(Text::getString).toArray(String[]::new); + }); + this.addDrawableChild(linkWidget); + String[] initialDimensions = sign.getTextOnRow(3, false).asString().split(":"); + TextFieldWidget widthWidget = new TextFieldWidget(textRenderer,this.width / 2 - 175,this.height / 5 + 70,30,20, Text.of("width")); + widthWidget.setText(initialDimensions[0]); + widthWidget.setChangedListener(s -> { + String[] dimensions = new String[5]; + for (int i = 0; i < dimensions.length; ++i){ + if (sign.getTextOnRow(3, false).asString().split(":").length > i) + dimensions[i] = sign.getTextOnRow(3, false).asString().split(":")[i]; + } + dimensions[0] = s; + StringBuilder mergedDimensions = new StringBuilder(); + for (int i = 0; i < 5; ++i) { + if (dimensions[i] == null) dimensions[i] = ""; + mergedDimensions.append(dimensions[i]); + if (i < 4)mergedDimensions.append(":"); + } + sign.setTextOnRow(3, Text.of(String.valueOf(mergedDimensions))); + text = IntStream.range(0, 4).mapToObj((row) -> + sign.getTextOnRow(row, false)).map(Text::getString).toArray(String[]::new); + }); + this.addDrawableChild(widthWidget); + TextFieldWidget heightWidget = new TextFieldWidget(textRenderer,this.width / 2 - 140,this.height / 5 + 70,30,20, Text.of("height")); + heightWidget.setText(initialDimensions[1]); + heightWidget.setChangedListener(s -> { + String[] dimensions = new String[5]; + for (int i = 0; i < dimensions.length; ++i){ + if (sign.getTextOnRow(3, false).asString().split(":").length > i) + dimensions[i] = sign.getTextOnRow(3, false).asString().split(":")[i]; + } + dimensions[1] = s; + StringBuilder mergedDimensions = new StringBuilder(); + for (int i = 0; i < 5; ++i) { + if (dimensions[i] == null) dimensions[i] = ""; + mergedDimensions.append(dimensions[i]); + if (i < 4)mergedDimensions.append(":"); + } + sign.setTextOnRow(3, Text.of(String.valueOf(mergedDimensions))); + text = IntStream.range(0, 4).mapToObj((row) -> + sign.getTextOnRow(row, false)).map(Text::getString).toArray(String[]::new); + }); + this.addDrawableChild(heightWidget); + TextFieldWidget posXWidget = new TextFieldWidget(textRenderer,this.width / 2 - 105,this.height / 5 + 70,30,20, Text.of("posX")); + posXWidget.setText(initialDimensions[2]); + posXWidget.setChangedListener(s -> { + String[] dimensions = new String[5]; + for (int i = 0; i < dimensions.length; ++i){ + if (sign.getTextOnRow(3, false).asString().split(":").length > i) + dimensions[i] = sign.getTextOnRow(3, false).asString().split(":")[i]; + } + dimensions[2] = s; + StringBuilder mergedDimensions = new StringBuilder(); + for (int i = 0; i < 5; ++i) { + if (dimensions[i] == null) dimensions[i] = ""; + mergedDimensions.append(dimensions[i]); + if (i < 4)mergedDimensions.append(":"); + } + sign.setTextOnRow(3, Text.of(String.valueOf(mergedDimensions))); + text = IntStream.range(0, 4).mapToObj((row) -> + sign.getTextOnRow(row, false)).map(Text::getString).toArray(String[]::new); + }); + this.addDrawableChild(posXWidget); + TextFieldWidget posYWidget = new TextFieldWidget(textRenderer,this.width / 2 - 70,this.height / 5 + 70,30,20, Text.of("posY")); + posYWidget.setText(initialDimensions[3]); + posYWidget.setChangedListener(s -> { + String[] dimensions = new String[5]; + for (int i = 0; i < dimensions.length; ++i){ + if (sign.getTextOnRow(3, false).asString().split(":").length > i) + dimensions[i] = sign.getTextOnRow(3, false).asString().split(":")[i]; + } + dimensions[3] = s; + StringBuilder mergedDimensions = new StringBuilder(); + for (int i = 0; i < 5; ++i) { + if (dimensions[i] == null) dimensions[i] = ""; + mergedDimensions.append(dimensions[i]); + if (i < 4)mergedDimensions.append(":"); + } + sign.setTextOnRow(3, Text.of(String.valueOf(mergedDimensions))); + text = IntStream.range(0, 4).mapToObj((row) -> + sign.getTextOnRow(row, false)).map(Text::getString).toArray(String[]::new); + }); + this.addDrawableChild(posYWidget); + TextFieldWidget posZWidget = new TextFieldWidget(textRenderer,this.width / 2 - 35,this.height / 5 + 70,30,20, Text.of("posZ")); + posZWidget.setText(initialDimensions[4]); + posZWidget.setChangedListener(s -> { + String[] dimensions = new String[5]; + for (int i = 0; i < dimensions.length; ++i){ + if (sign.getTextOnRow(3, false).asString().split(":").length > i) + dimensions[i] = sign.getTextOnRow(3, false).asString().split(":")[i]; + } + dimensions[4] = s; + StringBuilder mergedDimensions = new StringBuilder(); + for (int i = 0; i < 5; ++i) { + if (dimensions[i] == null) dimensions[i] = ""; + mergedDimensions.append(dimensions[i]); + if (i < 4)mergedDimensions.append(":"); + } + sign.setTextOnRow(3, Text.of(String.valueOf(mergedDimensions))); + text = IntStream.range(0, 4).mapToObj((row) -> + sign.getTextOnRow(row, false)).map(Text::getString).toArray(String[]::new); + }); + this.addDrawableChild(posZWidget); + this.model = SignBlockEntityRenderer.createSignModel(this.client.getEntityModelLoader(), SignBlockEntityRenderer.getSignType(sign.getCachedState().getBlock())); + } + public void removed() { + ClientPlayNetworkHandler clientPlayNetworkHandler = this.client.getNetworkHandler(); + if (clientPlayNetworkHandler != null) { + clientPlayNetworkHandler.sendPacket(new UpdateSignC2SPacket(this.sign.getPos(), this.text[0], this.text[1], this.text[2], this.text[3])); + } + this.sign.setEditable(true); + } + private String[] breakLink(String link) { + Text linkText = Text.of("!PS:"+link); + String[] brokenLink = new String[3]; + Text line0Text = linkText; + int line0width = line0Text.asString().length(); + assert this.client != null; + while (this.client.textRenderer.getWidth(line0Text) >= 90) { + --line0width; + line0Text = Text.of(line0Text.asString().substring(0,line0width)); + } + brokenLink[0] = line0Text.asString(); + Text line1Text = Text.of(linkText.asString().substring(line0width)); + int line1width = line1Text.asString().length(); + assert this.client != null; + while (this.client.textRenderer.getWidth(line1Text) >= 90) { + --line1width; + line1Text = Text.of(line1Text.asString().substring(0,line1width)); + } + brokenLink[1] = line1Text.asString(); + Text line2Text = Text.of(linkText.asString().substring(line0width + line1width)); + int line2width = line2Text.asString().length(); + assert this.client != null; + if (!PictureSignConfig.exceedVanillaLineLength) + while (this.client.textRenderer.getWidth(line2Text) >= 90) { + --line2width; + line2Text = Text.of(line2Text.asString().substring(0,line2width)); + } + brokenLink[2] = line2Text.asString(); + + return brokenLink; + } + public void tick() { + super.tick(); + if (!this.sign.getType().supports(this.sign.getCachedState())) { + this.finishEditing(); + } + } + private void finishEditing() { + sign.setEditable(true); + sign.markDirty(); + assert this.client != null; + this.client.setScreen(null); + } + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + DiffuseLighting.disableGuiDepthLighting(); + this.renderBackground(matrices); + drawTextWithShadow(matrices,textRenderer, Text.of("Link" + (PictureSignConfig.safeMode ? " (imgur.com/imgbb.com/iili.io/pictshare.net)" : "")),this.width / 2 - 175, this.height / 5 + 3, -8816268); + drawTextWithShadow(matrices,textRenderer, Text.of("Width"),this.width / 2 - 175, this.height / 5 + 60, -8816268); + drawTextWithShadow(matrices,textRenderer, Text.of("Height"),this.width / 2 - 140, this.height / 5 + 60, -8816268); + drawTextWithShadow(matrices,textRenderer, Text.of("PosX"),this.width / 2 - 105, this.height / 5 + 60, -8816268); + drawTextWithShadow(matrices,textRenderer, Text.of("PosY"),this.width / 2 - 75, this.height / 5 + 60, -8816268); + drawTextWithShadow(matrices,textRenderer, Text.of("PosZ"),this.width / 2 - 35, this.height / 5 + 60, -8816268); + drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 40, 16777215); + matrices.push(); + matrices.translate(this.width / 2f + 100, this.height / 5f - 60, 50.0); + matrices.scale(93.75F, -93.75F, 93.75F); + matrices.translate(0.0, -1.3125, 0.0); + BlockState blockState = this.sign.getCachedState(); + boolean bl = blockState.getBlock() instanceof SignBlock; + if (!bl) { + matrices.translate(0.0, -0.3125, 0.0); + } + matrices.push(); + matrices.scale(0.6666667F, -0.6666667F, -0.6666667F); + VertexConsumerProvider.Immediate immediate = this.client.getBufferBuilders().getEntityVertexConsumers(); + SpriteIdentifier spriteIdentifier = TexturedRenderLayers.getSignTextureId(SignBlockEntityRenderer.getSignType(sign.getCachedState().getBlock())); + SignBlockEntityRenderer.SignModel var10002 = this.model; + Objects.requireNonNull(var10002); + VertexConsumer vertexConsumer = spriteIdentifier.getVertexConsumer(immediate, var10002::getLayer); + this.model.stick.visible = bl; + this.model.root.render(matrices, vertexConsumer, 15728880, OverlayTexture.DEFAULT_UV); + matrices.pop(); + matrices.translate(0.0, 0.3333333432674408, 0.046666666865348816); + matrices.scale(0.010416667F, -0.010416667F, 0.010416667F); + int i = this.sign.getTextColor().getSignColor(); + Matrix4f matrix4f = matrices.peek().getModel(); + + int m; + String string; + for(m = 0; m < this.text.length; ++m) { + string = this.text[m]; + if (string != null) { + if (this.textRenderer.isRightToLeft()) { + string = this.textRenderer.mirror(string); + } + + float n = (float)(-this.client.textRenderer.getWidth(string) / 2); + this.client.textRenderer.draw(string, n, (float)(m * 10 - this.text.length * 5), i, false, matrix4f, immediate, false, 0, 15728880, false); + } + } + + immediate.draw(); + + matrices.pop(); + DiffuseLighting.enableGuiDepthLighting(); + super.render(matrices, mouseX, mouseY, delta); + } +} diff --git a/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java b/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java new file mode 100644 index 0000000..7a45e34 --- /dev/null +++ b/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java @@ -0,0 +1,27 @@ +package eu.midnightdust.picturesign.util; + +import net.minecraft.block.entity.SignBlockEntity; + +public class PictureURLUtils { + public static String getLink(SignBlockEntity signBlockEntity) { + String text = signBlockEntity.getTextOnRow(0, false).getString() + + signBlockEntity.getTextOnRow(1, false).getString() + + signBlockEntity.getTextOnRow(2, false).getString(); + String url = text.replaceAll("!PS:", "").replaceAll(" ",""); + if (url.startsWith("ps:")) url = url.replace("ps:", "https://pictshare.net/"); + if (url.startsWith("imgur:")) url = url.replace("imgur:", "https://i.imgur.com/"); + if (url.startsWith("imgbb:")) url = url.replace("imgbb:", "https://i.ibb.co/"); + if (url.startsWith("iili:")) url = url.replace("iili:", "https://iili.io/"); + return url; + } + public static String shortenLink(String url) { + if (url.contains("pictshare.net/")) url = url.replace("pictshare.net/", "ps:"); + if (url.contains("i.imgur.com/")) url = url.replace("i.imgur.com/", "imgur:"); + if (url.contains("i.ibb.co/:")) url = url.replace("i.ibb.co/", "imgbb:"); + if (url.contains("iili.io/")) url = url.replace("iili.io/", "iili:"); + if (url.startsWith("https://")) { + url = url.replace("https://", ""); + } + return url; + } +} diff --git a/src/main/java/eu/midnightdust/picturesign/util/SignEditEvent.java b/src/main/java/eu/midnightdust/picturesign/util/SignEditEvent.java new file mode 100644 index 0000000..ab8319a --- /dev/null +++ b/src/main/java/eu/midnightdust/picturesign/util/SignEditEvent.java @@ -0,0 +1,22 @@ +package eu.midnightdust.picturesign.util; + +import eu.midnightdust.picturesign.PictureSignClient; +import net.minecraft.block.entity.SignBlockEntity; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.ingame.SignEditScreen; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.BlockPos; +import org.jetbrains.annotations.NotNull; + +public class SignEditEvent { + public static void tick(@NotNull MinecraftClient client) { + if (!PictureSignClient.BINDING_EDIT_SIGN.isPressed()) return; + PictureSignClient.BINDING_EDIT_SIGN.setPressed(false); + if (client.player == null || client.crosshairTarget == null || client.crosshairTarget.getType() != HitResult.Type.BLOCK) return; + if (client.crosshairTarget.getType() == HitResult.Type.BLOCK && client.world.getBlockState(new BlockPos(client.crosshairTarget.getPos())).hasBlockEntity()) { + if (client.world.getBlockEntity(new BlockPos(client.crosshairTarget.getPos())) instanceof SignBlockEntity) { + client.setScreen(new SignEditScreen((SignBlockEntity) client.world.getBlockEntity(new BlockPos(client.crosshairTarget.getPos())), false)); + } + } + } +} diff --git a/src/main/resources/assets/picturesign/lang/de_de.json b/src/main/resources/assets/picturesign/lang/de_de.json new file mode 100755 index 0000000..fb1c063 --- /dev/null +++ b/src/main/resources/assets/picturesign/lang/de_de.json @@ -0,0 +1,18 @@ +{ + "picturesign.midnightconfig.title":"PictureSign Konfiguration", + + "picturesign.midnightconfig.enabled":"Aktiviere Bilder", + "picturesign.midnightconfig.translucency":"Aktiviere Lichtdurchlässigkeit", + "picturesign.midnightconfig.translucency.tooltip":"Lichtdurchlässigkeit funktioniert teilweise nicht richtig\nbei Block-Entities (und dementsprechend Schildern)", + "picturesign.midnightconfig.helperUi":"Aktiviere Hilfsoberfäche", + "picturesign.midnightconfig.exceedVanillaLineLength":"Überschreite die Vanilla Zeilenlänge", + "picturesign.midnightconfig.debug":"Debug-Modus", + "picturesign.midnightconfig.maxThreads":"Maximale Download-Threads", + "picturesign.midnightconfig.signRenderDistance":"Schildsichtweite", + "picturesign.midnightconfig.safeMode":"Sicherer Modus", + "picturesign.midnightconfig.safeMode.tooltip":"Lädt nur Bilder von vertrauten Seiten", + "picturesign.midnightconfig.ebeWarning":"§cWenn du die Mod 'Enhanced Block Entities' benutzt, stelle sicher,", + "picturesign.midnightconfig.ebeWarning2":"§cdass du alles in Relation zu Schildern in der EBE Config deaktiviert hast!", + "key.picturesign.copy_sign": "Text eines Schildes kopieren", + "key.picturesign.edit_sign":"Schild bearbeiten" +} \ No newline at end of file diff --git a/src/main/resources/assets/picturesign/lang/en_us.json b/src/main/resources/assets/picturesign/lang/en_us.json index b1ea607..798e91a 100755 --- a/src/main/resources/assets/picturesign/lang/en_us.json +++ b/src/main/resources/assets/picturesign/lang/en_us.json @@ -1,12 +1,19 @@ { "picturesign.midnightconfig.title":"PictureSign Config", - "picturesign.midnightconfig.enabled":"Enabled", - "picturesign.midnightconfig.debug":"Send debug info", + "picturesign.midnightconfig.enabled":"Enable Pictures", + "picturesign.midnightconfig.translucency":"Enable Translucency", + "picturesign.midnightconfig.translucency.tooltip":"Translucency doesn't work too great on block entities\n(and therefore signs)", + "picturesign.midnightconfig.helperUi":"Enable Helper UI", + "picturesign.midnightconfig.exceedVanillaLineLength":"Exceed vanilla line length", + "picturesign.midnightconfig.debug":"Debug mode", "picturesign.midnightconfig.maxThreads":"Max download threads", "picturesign.midnightconfig.signRenderDistance":"Sign render distance", "picturesign.midnightconfig.safeMode":"Safe mode", - "picturesign.midnightconfig.safeMode.tooltip":"Only load images from imgur.com and imgbb.com", + "picturesign.midnightconfig.safeMode.tooltip":"Only load images from trusted providers", "picturesign.midnightconfig.ebeWarning":"§cIf you are using the mod 'Enhanced Block Entities'", - "picturesign.midnightconfig.ebeWarning2":"§cmake sure to disable anything sign-related in it's config!" + "picturesign.midnightconfig.ebeWarning2":"§cmake sure to disable anything sign-related in it's config!", + "key.picturesign.copy_sign":"Copy Text from Sign", + "key.picturesign.edit_sign":"Edit Sign", + "key.categories.picturesign":"PictureSign" } \ No newline at end of file diff --git a/src/main/resources/assets/picturesign/textures/gui/clipboard_button.png b/src/main/resources/assets/picturesign/textures/gui/clipboard_button.png new file mode 100644 index 0000000..d8806e8 Binary files /dev/null and b/src/main/resources/assets/picturesign/textures/gui/clipboard_button.png differ diff --git a/src/main/resources/assets/picturesign/textures/gui/picturesign_button.png b/src/main/resources/assets/picturesign/textures/gui/picturesign_button.png new file mode 100644 index 0000000..f8335ca Binary files /dev/null and b/src/main/resources/assets/picturesign/textures/gui/picturesign_button.png differ diff --git a/src/main/resources/assets/picturesign/textures/gui/textsign_button.png b/src/main/resources/assets/picturesign/textures/gui/textsign_button.png new file mode 100644 index 0000000..948edd5 Binary files /dev/null and b/src/main/resources/assets/picturesign/textures/gui/textsign_button.png differ diff --git a/src/main/resources/assets/picturesign/textures/gui/trashbin_button.png b/src/main/resources/assets/picturesign/textures/gui/trashbin_button.png new file mode 100644 index 0000000..005a4a3 Binary files /dev/null and b/src/main/resources/assets/picturesign/textures/gui/trashbin_button.png differ diff --git a/src/main/resources/picturesign.mixins.json b/src/main/resources/picturesign.mixins.json index 158464b..7de1bba 100755 --- a/src/main/resources/picturesign.mixins.json +++ b/src/main/resources/picturesign.mixins.json @@ -3,7 +3,8 @@ "package": "eu.midnightdust.picturesign.mixin", "compatibilityLevel": "JAVA_16", "client": [ - "MixinSignBlockEntityRenderer" + "MixinSignBlockEntityRenderer", + "MixinSignEditScreen" ], "injectors": { "defaultRequire": 1