diff --git a/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinHangingSignBlockEntityRenderer.java b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinHangingSignBlockEntityRenderer.java index 827b367..d54228a 100755 --- a/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinHangingSignBlockEntityRenderer.java +++ b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinHangingSignBlockEntityRenderer.java @@ -4,7 +4,6 @@ import eu.midnightdust.picturesign.config.PictureSignConfig; import eu.midnightdust.picturesign.render.PictureSignRenderer; import eu.midnightdust.picturesign.util.PictureSignType; import net.minecraft.block.entity.SignBlockEntity; -import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.block.entity.BlockEntityRenderer; import net.minecraft.client.render.block.entity.HangingSignBlockEntityRenderer; @@ -15,6 +14,9 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import static eu.midnightdust.picturesign.util.PictureSignType.isCandidate; +import static eu.midnightdust.picturesign.util.PictureSignType.isNotOfType; + @Mixin(HangingSignBlockEntityRenderer.class) public abstract class MixinHangingSignBlockEntityRenderer implements BlockEntityRenderer { @Unique PictureSignRenderer psRenderer = new PictureSignRenderer(); @@ -22,8 +24,8 @@ public abstract class MixinHangingSignBlockEntityRenderer implements BlockEntity @Inject(at = @At("HEAD"), method = "render") public void ps$onRender(SignBlockEntity sign, float f, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, int overlay, CallbackInfo ci) { if (PictureSignConfig.enabled) { - if (PictureSignType.isNotOfType(sign, PictureSignType.NONE, true)) psRenderer.render(sign, matrixStack, light, overlay, true); - if (PictureSignType.isNotOfType(sign, PictureSignType.NONE, false)) psRenderer.render(sign, matrixStack, light, overlay, false); + if (isCandidate(sign, true) && isNotOfType(sign, PictureSignType.NONE, true)) psRenderer.render(sign, matrixStack, vertexConsumerProvider, light, overlay, true); + if (isCandidate(sign, false) && isNotOfType(sign, PictureSignType.NONE, false)) psRenderer.render(sign, matrixStack, vertexConsumerProvider, light, overlay, false); } } @Unique diff --git a/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntityRenderer.java b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntityRenderer.java index 0d66135..c2e33e9 100755 --- a/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntityRenderer.java +++ b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntityRenderer.java @@ -4,7 +4,7 @@ import eu.midnightdust.picturesign.config.PictureSignConfig; import eu.midnightdust.picturesign.render.PictureSignRenderer; import eu.midnightdust.picturesign.util.PictureSignType; import net.minecraft.block.entity.SignBlockEntity; -import net.minecraft.client.render.*; +import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.block.entity.BlockEntityRenderer; import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; import net.minecraft.client.render.block.entity.SignBlockEntityRenderer; @@ -18,6 +18,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import static eu.midnightdust.picturesign.PictureSignClient.client; +import static eu.midnightdust.picturesign.util.PictureSignType.isCandidate; +import static eu.midnightdust.picturesign.util.PictureSignType.isNotOfType; +import static eu.midnightdust.picturesign.util.PictureSignType.hasPicture; @Mixin(SignBlockEntityRenderer.class) public abstract class MixinSignBlockEntityRenderer implements BlockEntityRenderer { @@ -31,13 +34,13 @@ public abstract class MixinSignBlockEntityRenderer implements BlockEntityRendere @Inject(at = @At("HEAD"), method = "render") public void ps$onRender(SignBlockEntity sign, float f, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, int overlay, CallbackInfo ci) { if (PictureSignConfig.enabled && psRenderer != null) { - if (PictureSignType.isNotOfType(sign, PictureSignType.NONE, true)) psRenderer.render(sign, matrixStack, light, overlay, true); - if (PictureSignType.isNotOfType(sign, PictureSignType.NONE, false)) psRenderer.render(sign, matrixStack, light, overlay, false); + if (isCandidate(sign, true) && isNotOfType(sign, PictureSignType.NONE, true)) psRenderer.render(sign, matrixStack, vertexConsumerProvider, light, overlay, true); + if (isCandidate(sign, false) && isNotOfType(sign, PictureSignType.NONE, false)) psRenderer.render(sign, matrixStack, vertexConsumerProvider, light, overlay, false); } } @Inject(at = @At("HEAD"), method = "shouldRender", cancellable = true) private static void shouldRender(BlockPos pos, int signColor, CallbackInfoReturnable cir) { - if (PictureSignConfig.enabled && client.world != null && PictureSignType.hasPicture((SignBlockEntity) client.world.getBlockEntity(pos))) cir.setReturnValue(true); + if (PictureSignConfig.enabled && client.world != null && hasPicture((SignBlockEntity) client.world.getBlockEntity(pos))) cir.setReturnValue(true); } @Unique @Override @@ -47,6 +50,6 @@ public abstract class MixinSignBlockEntityRenderer implements BlockEntityRendere @Unique @Override public boolean rendersOutsideBoundingBox(SignBlockEntity sign) { - return PictureSignConfig.enabled && PictureSignType.hasPicture(sign); + return PictureSignConfig.enabled && hasPicture(sign); } } diff --git a/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java index db5c3fb..31207ec 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java +++ b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java @@ -19,7 +19,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Objects; -import static eu.midnightdust.picturesign.PictureSignClient.MOD_ID; import static eu.midnightdust.picturesign.PictureSignClient.id; @Mixin(AbstractSignEditScreen.class) diff --git a/common/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java b/common/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java index 15b0129..816c99e 100755 --- a/common/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java +++ b/common/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java @@ -2,7 +2,6 @@ package eu.midnightdust.picturesign.render; import com.mojang.blaze3d.systems.RenderSystem; import eu.midnightdust.lib.util.PlatformFunctions; -import eu.midnightdust.picturesign.PictureSignClient; import eu.midnightdust.picturesign.config.PictureSignConfig; import eu.midnightdust.picturesign.util.GIFHandler; import eu.midnightdust.picturesign.util.IrisCompat; @@ -13,32 +12,55 @@ import eu.midnightdust.picturesign.util.PictureSignType; import eu.midnightdust.picturesign.util.PictureURLUtils; import net.minecraft.block.Blocks; import net.minecraft.block.entity.SignBlockEntity; +import net.minecraft.client.font.TextRenderer; import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.BufferRenderer; import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexFormat; import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.texture.TextureManager; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.state.property.Properties; +import net.minecraft.text.OrderedText; +import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RotationAxis; import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; -import java.net.MalformedURLException; +import java.util.Iterator; +import static eu.midnightdust.picturesign.PictureSignClient.client; import static eu.midnightdust.picturesign.PictureSignClient.hasWaterMedia; import static eu.midnightdust.picturesign.PictureSignClient.id; -import static eu.midnightdust.picturesign.util.PictureSignType.*; +import static eu.midnightdust.picturesign.util.PictureSignType.GIF; +import static eu.midnightdust.picturesign.util.PictureSignType.PICTURE; +import static eu.midnightdust.picturesign.util.PictureSignType.getType; public class PictureSignRenderer { private boolean isSafeUrl; private boolean isSafeJsonUrl; - public void render(SignBlockEntity signBlockEntity, MatrixStack matrixStack, int light, int overlay, boolean front) { + @Nullable private Text errorMessage; + public static final Text ERROR = Text.translatable("picturesign.error"); + public static final Text MISSING_VLC = ERROR.copy().append(Text.translatable("picturesign.error.missingVLC")); + public static final Text MISSING_WATERMEDIA = ERROR.copy().append(Text.translatable("picturesign.error.missingWatermedia")); + public static final Text IMAGE_NOT_FOUND = ERROR.copy().append(Text.translatable("picturesign.error.imageNotFound")); + public static final Text UNKNOWN_FILETYPE = ERROR.copy().append(Text.translatable("picturesign.error.unknownFiletype")); + public static final Text UNKNOWN_SIGNTYPE = ERROR.copy().append(Text.translatable("picturesign.error.unknownSigntype")); + public static final Text UNSAFE_JSON_URL = ERROR.copy().append(Text.translatable("picturesign.error.unsafeJsonUrl")); + public static final Text UNSAFE_URL = ERROR.copy().append(Text.translatable("picturesign.error.unsafeUrl")); + + public static final Identifier RAW_TEXTURE = id("internal_raw_texture"); + + public void render(SignBlockEntity signBlockEntity, MatrixStack matrixStack, VertexConsumerProvider vertices, int light, int overlay, boolean front) { + errorMessage = null; PictureSignType type = getType(signBlockEntity, front); String url = PictureURLUtils.getLink(signBlockEntity, front); PictureInfo info = null; @@ -51,21 +73,21 @@ public class PictureSignRenderer { if (!isSafeJsonUrl) isSafeJsonUrl = jsonUrl.startsWith(safe); }); if (url.endsWith(".json") || isSafeJsonUrl) { - if (PictureSignConfig.safeMode) { - if (!isSafeJsonUrl) return; - } + if (PictureSignConfig.safeMode && !isSafeJsonUrl) errorMessage = UNSAFE_JSON_URL; - info = PictureURLUtils.infoFromJson(url); - if (info == null) return; - url = info.url(); + if (errorMessage == null) { + info = PictureURLUtils.infoFromJson(url); + if (info == null) return; + url = info.url(); - if (!url.contains("://")) { - url = "https://" + url; + if (!url.contains("://")) { + url = "https://" + url; + } } } - if (type == PICTURE && !url.contains(".png") && !url.contains(".jpg") && !url.contains(".jpeg") && !url.startsWith("rp:")) return; - if (type == GIF && !url.contains(".gif")) return; + if (type == PICTURE && !url.contains(".png") && !url.contains(".jpg") && !url.contains(".jpeg") && !url.startsWith("rp:")) errorMessage = UNKNOWN_FILETYPE; + if (type == GIF && !url.contains(".gif")) errorMessage = UNKNOWN_FILETYPE; if (PictureSignConfig.safeMode && !url.startsWith("file:") && !url.startsWith("rp:")) { isSafeUrl = false; String finalUrl = url; @@ -84,9 +106,10 @@ public class PictureSignRenderer { if (!isSafeUrl) isSafeUrl = finalUrl.startsWith(safe); }); } - if (!isSafeUrl) return; + if (!isSafeUrl) errorMessage = UNSAFE_URL; } - if ((!PictureSignConfig.enableMultimediaSigns || !MediaHandler.hasValidImplementation()) && type != PICTURE) return; + if ((!PictureSignConfig.enableMultimediaSigns || !MediaHandler.hasValidImplementation()) && type != PICTURE) errorMessage = MISSING_WATERMEDIA; + if (url.startsWith("https://youtube.com/") || url.startsWith("https://www.youtube.com/watch?v=") || url.startsWith("https://youtu.be/")) { url = url.replace("https://www.", "https://"); } @@ -97,7 +120,7 @@ public class PictureSignRenderer { MediaHandler mediaHandler = null; GIFHandler gifHandler = null; - if (MediaHandler.hasValidImplementation()) { + if (errorMessage == null && MediaHandler.hasValidImplementation()) { if (type.isVideo || type.isAudio) mediaHandler = MediaHandler.getOrCreate(videoId, pos); else if (type == GIF && hasWaterMedia) gifHandler = GIFHandler.getOrCreate(videoId); else { @@ -160,12 +183,13 @@ public class PictureSignRenderer { // Download the picture data PictureDownloader.PictureData data = null; - if (type == PICTURE) { + if (errorMessage == null && type == PICTURE) { data = PictureDownloader.getInstance().getPicture(url); - if (data == null || data.identifier == null) return; + if (data == null || data.identifier == null) errorMessage = IMAGE_NOT_FOUND; } else if (mediaHandler != null) { - try { + if (!mediaHandler.isReady()) errorMessage = MISSING_VLC; + else { if (!mediaHandler.hasMedia() && !mediaHandler.playbackStarted) { mediaHandler.play(url, type.isVideo); if (info != null && info.start() > 0) mediaHandler.setTime(info.start()); @@ -173,29 +197,22 @@ public class PictureSignRenderer { mediaHandler.setRepeat(true); } - } catch (Exception e) { - PictureSignClient.LOGGER.error(e); - return; - } - if (info != null && info.volume() >= 0) mediaHandler.setMaxVolume(info.volume()); - mediaHandler.setVolumeBasedOnDistance(); - if (info != null && info.start() > 0 && mediaHandler.getTime() < info.start()) mediaHandler.setTime(info.start()); - if (info != null && info.end() > 0 && mediaHandler.getTime() > info.end()) { - if (type.isLooped) mediaHandler.setTime(info.start() > 0 ? info.start() : 0); - else mediaHandler.stop(); + if (info != null && info.volume() >= 0) mediaHandler.setMaxVolume(info.volume()); + mediaHandler.setVolumeBasedOnDistance(); + if (info != null && info.start() > 0 && mediaHandler.getTime() < info.start()) + mediaHandler.setTime(info.start()); + if (info != null && info.end() > 0 && mediaHandler.getTime() > info.end()) { + if (type.isLooped) mediaHandler.setTime(info.start() > 0 ? info.start() : 0); + else mediaHandler.stop(); + } } } else if (type == GIF && gifHandler != null) { - try { - if (!gifHandler.hasMedia() && !gifHandler.playbackStarted) { - gifHandler.play(url); - } - } catch (MalformedURLException e) { - PictureSignClient.LOGGER.error(e); - return; + if (!gifHandler.hasMedia() && !gifHandler.playbackStarted) { + gifHandler.play(url); } } - else return; + else if (errorMessage == null) errorMessage = UNKNOWN_SIGNTYPE; if (type.isAudio) return; @@ -237,36 +254,29 @@ public class PictureSignRenderer { } else RenderSystem.setShader(GameRenderer::getPositionColorTexLightmapProgram); - Identifier texture = null; - if (type == PICTURE) { - texture = data.identifier; - } - else if (type.isVideo && mediaHandler != null) { - boolean hasVideoTexture = false; - if (mediaHandler.isWorking()) { - int rawTexture = mediaHandler.getTexture(); - if (rawTexture != -1) { - RenderSystem.setShaderTexture(0, rawTexture); - hasVideoTexture = true; + Identifier texture = getMissingTexture(); + if (errorMessage == null) { + if (type == PICTURE) { + assert data != null; + texture = data.identifier; + } else if (type.isVideo && mediaHandler != null) { + if (mediaHandler.isWorking()) { + int rawTexture = mediaHandler.getTexture(); + if (rawTexture != -1) { + RenderSystem.setShaderTexture(0, rawTexture); + texture = RAW_TEXTURE; + } + } + } else if (gifHandler != null) { + if (gifHandler.isWorking()) { + RenderSystem.setShaderTexture(0, gifHandler.getTexture()); + texture = RAW_TEXTURE; } } - if (!hasVideoTexture) { - var id = MediaHandler.getMissingTexture(); - if (id == null) return; - texture = id; - } } - else if (gifHandler != null) { - if (gifHandler.isWorking()) RenderSystem.setShaderTexture(0, gifHandler.getTexture()); - else { - var id = MediaHandler.getMissingTexture(); - if (id == null) return; - texture = id; - } - } - else return; - if (texture != null) RenderSystem.setShaderTexture(0, texture); + if (texture == null) return; + if (texture != RAW_TEXTURE) RenderSystem.setShaderTexture(0, texture); if (PictureSignConfig.translucency) RenderSystem.enableBlend(); else RenderSystem.disableBlend(); @@ -292,9 +302,32 @@ public class PictureSignRenderer { BufferRenderer.drawWithGlobalProgram(buffer.end()); + if (errorMessage != null) renderErrorMessage(client.textRenderer, matrixStack, vertices, width, height); matrixStack.pop(); RenderSystem.disableBlend(); RenderSystem.disableDepthTest(); } + private void renderErrorMessage(TextRenderer textRenderer, MatrixStack matrices, VertexConsumerProvider vertices, float width, float height) { + float scale = Math.min(width, height) / 100; + matrices.translate(0, height, 1.005f); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180)); + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(180)); + matrices.scale(scale,scale,scale); + int wrappedY = 0; + for(Iterator textIterator = textRenderer.wrapLines(errorMessage, MathHelper.floor(width/scale)).iterator(); textIterator.hasNext(); wrappedY += 9) { + renderTextWithShadow(textIterator.next(), wrappedY, textRenderer, matrices.peek().getPositionMatrix(), vertices); + } + } + private void renderTextWithShadow(OrderedText text, int wrappedY, TextRenderer textRenderer, Matrix4f matrix, VertexConsumerProvider vertices) { + textRenderer.draw(text, 0, wrappedY, 0xFFFFFF, false, matrix, vertices, TextRenderer.TextLayerType.POLYGON_OFFSET, 0, 15728880); + matrix.translate(0, 0, 0.025f); + textRenderer.draw(text, 1, wrappedY + 1, 0x555555, false, matrix, vertices, TextRenderer.TextLayerType.POLYGON_OFFSET, 0, 15728880); + matrix.translate(0, 0, -0.025f); + } + public static Identifier getMissingTexture() { + if (PictureSignConfig.missingImageMode.equals(PictureSignConfig.MissingImageMode.TRANSPARENT)) return null; + return PictureSignConfig.missingImageMode.equals(PictureSignConfig.MissingImageMode.BLACK) ? + (id("textures/black.png")) : (TextureManager.MISSING_IDENTIFIER); + } } diff --git a/common/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java b/common/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java index f2c639b..06d7609 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java +++ b/common/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java @@ -5,15 +5,28 @@ import eu.midnightdust.picturesign.config.PictureSignConfig; import eu.midnightdust.picturesign.util.NetworkUtil; import eu.midnightdust.picturesign.util.PictureSignType; import eu.midnightdust.picturesign.util.PictureURLUtils; -import net.minecraft.block.*; +import net.minecraft.block.AbstractSignBlock; +import net.minecraft.block.BlockState; +import net.minecraft.block.HangingSignBlock; +import net.minecraft.block.SignBlock; +import net.minecraft.block.WallHangingSignBlock; +import net.minecraft.block.WoodType; import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HangingSignEditScreen; import net.minecraft.client.gui.screen.ingame.SignEditScreen; -import net.minecraft.client.gui.widget.*; -import net.minecraft.client.render.*; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.client.gui.widget.SliderWidget; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.client.gui.widget.TextIconButtonWidget; +import net.minecraft.client.render.DiffuseLighting; +import net.minecraft.client.render.OverlayTexture; +import net.minecraft.client.render.TexturedRenderLayers; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.block.entity.SignBlockEntityRenderer; import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.client.util.math.MatrixStack; @@ -277,25 +290,25 @@ public class PictureSignHelperScreen extends Screen { DiffuseLighting.disableGuiDepthLighting(); String enabledWebsites = ""; if (PictureSignConfig.safeMode) { - if (type.equals(PictureSignType.PICTURE)) enabledWebsites = " (imgur.com/imgbb.com/iili.io/pictshare.net)"; - else if (type.equals(PictureSignType.GIF)) enabledWebsites = " (imgur.com/tenor.com)"; - else if (type.isVideo) enabledWebsites = " (youtube.com/youtu.be/vimeo.com)"; - else if (type.isAudio) enabledWebsites = " (youtube.com/youtu.be/vimeo.com/freesound.org)"; + if (type.equals(PictureSignType.PICTURE)) enabledWebsites = "(imgur.com/imgbb.com/iili.io/pictshare.net)"; + else if (type.equals(PictureSignType.GIF)) enabledWebsites = "(imgur.com/tenor.com)"; + else if (type.isVideo) enabledWebsites = "(youtube.com/youtu.be/vimeo.com)"; + else if (type.isAudio) enabledWebsites = "(youtube.com/youtu.be/vimeo.com/freesound.org)"; } if (type.isAudio) pictureWidgets.forEach(widget -> widget.active = false); else pictureWidgets.forEach(widget -> widget.active = true); - context.drawTextWithShadow(textRenderer, Text.of("Link" + enabledWebsites), + context.drawTextWithShadow(textRenderer, Text.translatable("picturesign.helper.link", enabledWebsites), this.width / 2 - 175, this.height / 5 + 3, -8816268); - context.drawTextWithShadow(textRenderer, Text.of("Width"),this.width / 2 - 175, this.height / 5 + 60, -8816268); - context.drawTextWithShadow(textRenderer, Text.of("Height"),this.width / 2 - 140, this.height / 5 + 60, -8816268); - context.drawTextWithShadow(textRenderer, Text.of("PosX"),this.width / 2 - 105, this.height / 5 + 60, -8816268); - context.drawTextWithShadow(textRenderer, Text.of("PosY"),this.width / 2 - 70, this.height / 5 + 60, -8816268); - context.drawTextWithShadow(textRenderer, Text.of("PosZ"),this.width / 2 - 35, this.height / 5 + 60, -8816268); - context.drawTextWithShadow(textRenderer, Text.of("Mode"),this.width / 2, this.height / 5 + 60, -8816268); + context.drawTextWithShadow(textRenderer, Text.translatable("picturesign.helper.width"),this.width / 2 - 175, this.height / 5 + 60, -8816268); + context.drawTextWithShadow(textRenderer, Text.translatable("picturesign.helper.height"),this.width / 2 - 140, this.height / 5 + 60, -8816268); + context.drawTextWithShadow(textRenderer, Text.translatable("picturesign.helper.pos_x"),this.width / 2 - 105, this.height / 5 + 60, -8816268); + context.drawTextWithShadow(textRenderer, Text.translatable("picturesign.helper.pos_y"),this.width / 2 - 70, this.height / 5 + 60, -8816268); + context.drawTextWithShadow(textRenderer, Text.translatable("picturesign.helper.pos_z"),this.width / 2 - 35, this.height / 5 + 60, -8816268); + context.drawTextWithShadow(textRenderer, Text.translatable("picturesign.helper.mode"),this.width / 2, this.height / 5 + 60, -8816268); if (text[2].matches("(.*\\d:.*\\d:.*\\d)")) { - context.drawTextWithShadow(textRenderer, Text.of("RotX"),this.width / 2 - 175, this.height / 5 + 92, -8816268); - context.drawTextWithShadow(textRenderer, Text.of("RotY"),this.width / 2 - 103, this.height / 5 + 92, -8816268); - context.drawTextWithShadow(textRenderer, Text.of("RotZ"),this.width / 2 - 30, this.height / 5 + 92, -8816268); + context.drawTextWithShadow(textRenderer, Text.translatable("picturesign.helper.rot_x"),this.width / 2 - 175, this.height / 5 + 92, -8816268); + context.drawTextWithShadow(textRenderer, Text.translatable("picturesign.helper.rot_y"),this.width / 2 - 103, this.height / 5 + 92, -8816268); + context.drawTextWithShadow(textRenderer, Text.translatable("picturesign.helper.rot_z"),this.width / 2 - 30, this.height / 5 + 92, -8816268); } context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 40, 16777215); MatrixStack matrices = context.getMatrices(); diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/GIFHandler.java b/common/src/main/java/eu/midnightdust/picturesign/util/GIFHandler.java index 4e654bf..59381ed 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/util/GIFHandler.java +++ b/common/src/main/java/eu/midnightdust/picturesign/util/GIFHandler.java @@ -3,10 +3,8 @@ package eu.midnightdust.picturesign.util; import me.srrapero720.watermedia.api.image.ImageAPI; import me.srrapero720.watermedia.api.image.ImageCache; import me.srrapero720.watermedia.api.math.MathAPI; -import net.minecraft.client.MinecraftClient; import net.minecraft.util.Identifier; -import java.net.MalformedURLException; import java.util.HashMap; import java.util.Map; @@ -47,8 +45,8 @@ public class GIFHandler { gifPlayers.clear(); } - public void play(String url) throws MalformedURLException { - this.player = ImageAPI.getCache(url, MinecraftClient.getInstance()); + public void play(String url) { + this.player = ImageAPI.getCache(url, client); player.load(); this.playbackStarted = true; } diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/MediaHandler.java b/common/src/main/java/eu/midnightdust/picturesign/util/MediaHandler.java index c3d9bb3..c0ba7e7 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/util/MediaHandler.java +++ b/common/src/main/java/eu/midnightdust/picturesign/util/MediaHandler.java @@ -1,7 +1,6 @@ package eu.midnightdust.picturesign.util; import eu.midnightdust.picturesign.config.PictureSignConfig; -import net.minecraft.client.texture.TextureManager; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -11,8 +10,6 @@ import java.util.Map; import static eu.midnightdust.picturesign.PictureSignClient.client; import static eu.midnightdust.picturesign.PictureSignClient.hasWaterMedia; -import static eu.midnightdust.picturesign.PictureSignClient.id; - public abstract class MediaHandler { public static Map mediaHandlers = new HashMap<>(); @@ -88,12 +85,10 @@ public abstract class MediaHandler { public int getTexture() { return -1; } + public boolean isReady() { + return false; + } public boolean isWorking() { return false; } - public static Identifier getMissingTexture() { - if (PictureSignConfig.missingImageMode.equals(PictureSignConfig.MissingImageMode.TRANSPARENT)) return null; - return PictureSignConfig.missingImageMode.equals(PictureSignConfig.MissingImageMode.BLACK) ? - (id("textures/black.png")) : (TextureManager.MISSING_IDENTIFIER); - } } diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/PictureSignType.java b/common/src/main/java/eu/midnightdust/picturesign/util/PictureSignType.java index 484ef92..dd5ceda 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/util/PictureSignType.java +++ b/common/src/main/java/eu/midnightdust/picturesign/util/PictureSignType.java @@ -4,13 +4,13 @@ import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.text.Text; public enum PictureSignType { - NONE(Text.empty(), "", false, false, false), - PICTURE(Text.of("Image"), "!PS:", false, false, false), - GIF(Text.of("GIF"), "!GS:", true, false, false), - VIDEO(Text.of("Video"), "!VS:", false, true, false), - LOOPED_VIDEO(Text.of("Video Loop"), "!LS:", true, true, false), - AUDIO(Text.of("Audio"), "!AS:", false, false, true), - LOOPED_AUDIO(Text.of("Audio Loop"), "!ALS:", true, false, true); + NONE(Text.empty(), "", false, false, false), + PICTURE(Text.translatable("picturesign.type.image"), "!PS:", false, false, false), + GIF(Text.translatable("picturesign.type.gif"), "!GS:", true, false, false), + VIDEO(Text.translatable("picturesign.type.video"), "!VS:", false, true, false), + LOOPED_VIDEO(Text.translatable("picturesign.type.video_loop"), "!LS:", true, true, false), + AUDIO(Text.translatable("picturesign.type.audio"), "!AS:", false, false, true), + LOOPED_AUDIO(Text.translatable("picturesign.type.audio_loop"), "!ALS:", true, false, true); public final Text name; public final String format; @@ -50,6 +50,9 @@ public enum PictureSignType { }; } + public static boolean isCandidate(SignBlockEntity signBlockEntity, boolean front) { + return signBlockEntity.getText(front).getMessage(0,false).getString().startsWith("!"); + } public static boolean isNotOfType(SignBlockEntity signBlockEntity, PictureSignType type, boolean front) { return getType(signBlockEntity, front) != type; } diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/WaterMediaHandler.java b/common/src/main/java/eu/midnightdust/picturesign/util/WaterMediaHandler.java index b169e42..b939ad4 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/util/WaterMediaHandler.java +++ b/common/src/main/java/eu/midnightdust/picturesign/util/WaterMediaHandler.java @@ -1,5 +1,6 @@ package eu.midnightdust.picturesign.util; +import me.srrapero720.watermedia.api.player.PlayerAPI; import me.srrapero720.watermedia.api.player.SyncBasePlayer; import me.srrapero720.watermedia.api.player.SyncMusicPlayer; import me.srrapero720.watermedia.api.player.SyncVideoPlayer; @@ -9,6 +10,8 @@ import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import org.lwjgl.opengl.GL11; +import static eu.midnightdust.picturesign.PictureSignClient.client; + public class WaterMediaHandler extends MediaHandler { private SyncBasePlayer player; @@ -54,7 +57,7 @@ public class WaterMediaHandler extends MediaHandler { @Override public void play(String url, boolean isVideo) { - this.player = isVideo ? new SyncVideoPlayer(MinecraftClient.getInstance()) : new SyncMusicPlayer(); + this.player = isVideo ? new SyncVideoPlayer(client) : new SyncMusicPlayer(); mediaHandlers.put(id, this); if (player.isBroken()) return; player.start(url); @@ -85,6 +88,10 @@ public class WaterMediaHandler extends MediaHandler { return -1; } @Override + public boolean isReady() { + return PlayerAPI.isReady(); + } + @Override public boolean isWorking() { return mediaHandlers.containsKey(id) && mediaHandlers.get(id) instanceof WaterMediaHandler waterMediaHandler && waterMediaHandler.player != null && !waterMediaHandler.player.isBroken(); diff --git a/common/src/main/resources/assets/picturesign/lang/de_de.json b/common/src/main/resources/assets/picturesign/lang/de_de.json index 67776c4..1b37e26 100755 --- a/common/src/main/resources/assets/picturesign/lang/de_de.json +++ b/common/src/main/resources/assets/picturesign/lang/de_de.json @@ -2,6 +2,8 @@ "picturesign.midnightconfig.title":"PictureSign Konfiguration", "picturesign.midnightconfig.enabled":"Aktiviere Bilder", + "picturesign.midnightconfig.enableMultimediaSigns":"Aktiviere Multimedia", + "picturesign.midnightconfig.audioDistanceMultiplier":"Audio-Distanz Multiplikator", "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", @@ -12,21 +14,37 @@ "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, dass du alles in Relation zu Schildern in der EBE Config deaktiviert hast!", - "picturesign.midnightconfig.safeProviders":"Sichere Anbieter", + "picturesign.midnightconfig.safeProviders":"Sichere Bildanbieter", + "picturesign.midnightconfig.safeGifProviders":"Sichere GIF-Anbieter", + "picturesign.midnightconfig.safeMultimediaProviders":"Sichere Multimedia-Anbieter", + "picturesign.midnightconfig.safeJsonProviders":"Sichere JSON-Anbieter", "picturesign.midnightconfig.missingImageMode":"Darstellung fehlender Texturen", "picturesign.midnightconfig.enum.MissingImageMode.BLACK":"Schwarz", "picturesign.midnightconfig.enum.MissingImageMode.MISSING_TEXTURE":"Schwarz & Lila", "picturesign.midnightconfig.enum.MissingImageMode.TRANSPARENT":"Transparent", + "key.picturesign.copy_sign": "Text eines Schildes kopieren", "key.picturesign.edit_sign":"Schild bearbeiten", "picturesign.midnightconfig.category.1general": "Generell", "picturesign.midnightconfig.category.advanced": "Fortgeschritten", - "picturesign.midnightconfig.enableVideoSigns": "Aktiviere Videos", "picturesign.midnightconfig.fullBrightPicture": "Höchste Helligkeit", "picturesign.midnightconfig.fullBrightPicture.tooltip": "Sorgt dafür, dass Bilder immer vollkommen beleuchtet dargestellt werden", - "picturesign.midnightconfig.invidiousInstance": "Invidious-Instanz", - "picturesign.midnightconfig.invidiousInstance.tooltip": "Wähle die Invidious-Instanz aus, die zur Wiedergabe von YouTube-Videos verwendet wird. \nEine Liste dieser ist zu finden unter\ndocs.invidious.io/instances/", "picturesign.midnightconfig.pictureShader": "Render-Programm", - "picturesign.midnightconfig.pictureShader.tooltip": "Wähle das Shader-Programm, mit dem die Bilder dargestellt werden, was nützlich ist, wenn diese mit Shaderpacks nicht richtig dargestellt werden" + "picturesign.midnightconfig.pictureShader.tooltip": "Wähle das Shader-Programm, mit dem die Bilder dargestellt werden, was nützlich ist, wenn diese mit Shaderpacks nicht richtig dargestellt werden", + + "picturesign.type.image": "Bild", + + "picturesign.helper.width": "Breite", + "picturesign.helper.height": "Höhe", + "picturesign.helper.mode": "Modus", + + "picturesign.error": "FEHLER: ", + "picturesign.error.imageNotFound": "Das angegebene Bild konnte nicht gefunden werden.\nBist du offline oder ist die Website down?", + "picturesign.error.missingVLC": "VLC ist nicht installiert oder konnte nicht gefunden werden.", + "picturesign.error.missingWatermedia": "Installiere WATERMeDIA, um GIFs, Videos und Audios zu genießen.", + "picturesign.error.unknownFiletype": "Der Dateityp des Bildes wird nicht von PictureSign unterstützt.", + "picturesign.error.unknownSigntype": "Diese Version von PictureSign unterstützt keine Schilder des angegebenen Typen.", + "picturesign.error.unsafeJsonUrl": "Die angegebene JSON URL ist nicht als sicher bekannt.\nNutze einen anderen Anbieter oder ändere die PictureSign Konfiguration.", + "picturesign.error.unsafeUrl": "Die angegebene URL ist nicht als sicher bekannt.\nNutze einen anderen Anbieter oder ändere die PictureSign Konfiguration." } \ No newline at end of file diff --git a/common/src/main/resources/assets/picturesign/lang/en_us.json b/common/src/main/resources/assets/picturesign/lang/en_us.json index b733daf..71ddee7 100755 --- a/common/src/main/resources/assets/picturesign/lang/en_us.json +++ b/common/src/main/resources/assets/picturesign/lang/en_us.json @@ -22,8 +22,6 @@ "picturesign.midnightconfig.safeGifProviders":"Safe GIF Providers", "picturesign.midnightconfig.safeMultimediaProviders":"Safe Multimedia Providers", "picturesign.midnightconfig.safeJsonProviders":"Safe JSON Providers", - "picturesign.midnightconfig.invidiousInstance":"Invidious Instance", - "picturesign.midnightconfig.invidiousInstance.tooltip":"Select the Invidious instance that is being used to play YouTube videos. \nYou can find a list of them at\ndocs.invidious.io/instances/", "picturesign.midnightconfig.missingImageMode":"Missing image mode", "picturesign.midnightconfig.enum.MissingImageMode.BLACK":"Black", "picturesign.midnightconfig.enum.MissingImageMode.MISSING_TEXTURE":"Black & Purple", @@ -37,5 +35,32 @@ "picturesign.midnightconfig.enum.PictureShader.PosTexCol":"PosTexCol", "key.picturesign.copy_sign":"Copy Text from Sign", "key.picturesign.edit_sign":"Edit Sign", - "key.categories.picturesign":"PictureSign" + "key.categories.picturesign":"PictureSign", + + "picturesign.type.image": "Image", + "picturesign.type.gif": "GIF", + "picturesign.type.video": "Video", + "picturesign.type.video_loop": "Video Loop", + "picturesign.type.audio": "Audio", + "picturesign.type.audio_loop": "Audio Loop", + + "picturesign.helper.link": "Link %s", + "picturesign.helper.width": "Width", + "picturesign.helper.height": "Height", + "picturesign.helper.pos_x": "PosX", + "picturesign.helper.pos_y": "PosY", + "picturesign.helper.pos_z": "PosZ", + "picturesign.helper.rot_x": "RotX", + "picturesign.helper.rot_y": "RotY", + "picturesign.helper.rot_z": "RotZ", + "picturesign.helper.mode": "Mode", + + "picturesign.error": "ERROR: ", + "picturesign.error.imageNotFound": "The specified image could not be found.\nAre you offline or is the website down?", + "picturesign.error.missingVLC": "VLC is not installed or could not be found.", + "picturesign.error.missingWatermedia": "Install WATERMeDIA to enjoy GIFs, videos and audios.", + "picturesign.error.unknownFiletype": "The filetype of the specified image is not supported by PictureSign.", + "picturesign.error.unknownSigntype": "This version of PictureSign does not support signs of the specified type.", + "picturesign.error.unsafeJsonUrl": "The provided JSON URL is not known to be safe.\nUpload to a different provider or change the PictureSign config.", + "picturesign.error.unsafeUrl": "The provided URL is not known to be safe.\nUpload to a different provider or change the PictureSign config." } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 4ffdef5..6841548 100755 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ curseforge_id=432008 modrinth_id=YQnwl5Vv midnightlib_version=1.5.7 -watermedia_version=2.0.63 +watermedia_version=2.0.64 iris_version=1.6.17+1.20.4 # The latest Iris version causes the build to fail, but we don't need that anyway