diff --git a/common/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java b/common/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java index 0cd6226..7543a1d 100755 --- a/common/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java +++ b/common/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java @@ -13,7 +13,7 @@ public class PictureSignConfig extends MidnightConfig { private static final String advanced = "advanced"; @Entry(category = general) public static boolean enabled = true; - @Entry(category = general) public static boolean enableVideoSigns = true; + @Entry(category = general) public static boolean enableMultimediaSigns = true; @Entry(min = 0, max = 1000, isSlider = true, category = general) public static int audioDistanceMultiplier = 30; @Entry(category = general) public static boolean translucency = false; @Entry(category = general) public static boolean fullBrightPicture = false; 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 6749d13..0f5981e 100755 --- a/common/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java +++ b/common/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java @@ -2,29 +2,44 @@ package eu.midnightdust.picturesign.render; import com.mojang.blaze3d.systems.RenderSystem; import eu.midnightdust.lib.util.PlatformFunctions; -import eu.midnightdust.picturesign.util.*; import eu.midnightdust.picturesign.PictureSignClient; import eu.midnightdust.picturesign.config.PictureSignConfig; +import eu.midnightdust.picturesign.util.GIFHandler; +import eu.midnightdust.picturesign.util.IrisCompat; +import eu.midnightdust.picturesign.util.MediaHandler; +import eu.midnightdust.picturesign.util.PictureDownloader; +import eu.midnightdust.picturesign.util.PictureInfo; +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.render.*; +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.VertexFormat; +import net.minecraft.client.render.VertexFormats; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.state.property.Properties; import net.minecraft.util.Identifier; -import net.minecraft.util.math.*; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.RotationAxis; import net.minecraft.world.World; -import org.joml.*; +import org.joml.Matrix4f; import java.net.MalformedURLException; +import static eu.midnightdust.picturesign.PictureSignClient.hasWaterMedia; import static eu.midnightdust.picturesign.PictureSignClient.id; +import static eu.midnightdust.picturesign.util.PictureSignType.*; public class PictureSignRenderer { private boolean isSafeUrl; private boolean isSafeJsonUrl; public void render(SignBlockEntity signBlockEntity, MatrixStack matrixStack, int light, int overlay, boolean front) { - PictureSignType type = PictureSignType.getType(signBlockEntity, front); + PictureSignType type = getType(signBlockEntity, front); String url = PictureURLUtils.getLink(signBlockEntity, front); PictureInfo info = null; if (!url.contains("://") && !url.startsWith("file:") && !url.startsWith("rp:")) { @@ -49,17 +64,17 @@ public class PictureSignRenderer { } } - if (type == PictureSignType.PICTURE && !url.contains(".png") && !url.contains(".jpg") && !url.contains(".jpeg") && !url.startsWith("rp:")) return; - if (type == PictureSignType.GIF && !url.contains(".gif")) return; + if (type == PICTURE && !url.contains(".png") && !url.contains(".jpg") && !url.contains(".jpeg") && !url.startsWith("rp:")) return; + if (type == GIF && !url.contains(".gif")) return; if (PictureSignConfig.safeMode && !url.startsWith("file:") && !url.startsWith("rp:")) { isSafeUrl = false; String finalUrl = url; - if (type == PictureSignType.PICTURE) { + if (type == PICTURE) { PictureSignConfig.safeProviders.forEach(safe -> { if (!isSafeUrl) isSafeUrl = finalUrl.startsWith(safe); }); } - if (type == PictureSignType.GIF) { + if (type == GIF) { PictureSignConfig.safeGifProviders.forEach(safe -> { if (!isSafeUrl) isSafeUrl = finalUrl.startsWith(safe); }); @@ -71,7 +86,7 @@ public class PictureSignRenderer { } if (!isSafeUrl) return; } - if ((!PictureSignConfig.enableVideoSigns || !PictureSignClient.hasWaterMedia) && type != PictureSignType.PICTURE) return; + if ((!PictureSignConfig.enableMultimediaSigns || !MediaHandler.hasValidImplementation()) && type != PICTURE) return; 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://"); } @@ -82,9 +97,9 @@ public class PictureSignRenderer { MediaHandler mediaHandler = null; GIFHandler gifHandler = null; - if (PictureSignClient.hasWaterMedia) { + if (MediaHandler.hasValidImplementation()) { if (type.isVideo || type.isAudio) mediaHandler = MediaHandler.getOrCreate(videoId, pos); - else if (type == PictureSignType.GIF) gifHandler = GIFHandler.getOrCreate(videoId); + else if (type == GIF && hasWaterMedia) gifHandler = GIFHandler.getOrCreate(videoId); else { MediaHandler.closePlayer(videoId); GIFHandler.closePlayer(videoId); @@ -145,7 +160,7 @@ public class PictureSignRenderer { // Download the picture data PictureDownloader.PictureData data = null; - if (type == PictureSignType.PICTURE) { + if (type == PICTURE) { data = PictureDownloader.getInstance().getPicture(url); if (data == null || data.identifier == null) return; } @@ -157,7 +172,7 @@ public class PictureSignRenderer { mediaHandler.setRepeat(true); } - } catch (MalformedURLException e) { + } catch (Exception e) { PictureSignClient.LOGGER.error(e); return; } @@ -166,7 +181,7 @@ public class PictureSignRenderer { if (info != null && info.start() > 0 && mediaHandler.getTime() < info.start()) mediaHandler.setTime(info.start()); if (info != null && info.end() > 0 && mediaHandler.getTime() >= info.end() && !mediaHandler.playbackStarted) mediaHandler.stop(); } - else if (type == PictureSignType.GIF && gifHandler != null) { + else if (type == GIF && gifHandler != null) { try { if (!gifHandler.hasMedia() && !gifHandler.playbackStarted) { gifHandler.play(url); @@ -219,7 +234,7 @@ public class PictureSignRenderer { else RenderSystem.setShader(GameRenderer::getPositionColorTexLightmapProgram); Identifier texture = null; - if (type == PictureSignType.PICTURE) { + if (type == PICTURE) { texture = data.identifier; } else if (type.isVideo && mediaHandler != null) { 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 f591114..f2c639b 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java +++ b/common/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java @@ -13,7 +13,6 @@ 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.network.ClientPlayNetworkHandler; import net.minecraft.client.render.*; import net.minecraft.client.render.block.entity.SignBlockEntityRenderer; import net.minecraft.client.util.SpriteIdentifier; @@ -45,7 +44,7 @@ public class PictureSignHelperScreen extends Screen { private final boolean isHanging; protected final WoodType signType; private static boolean switchScreen = false; - private List pictureWidgets = new ArrayList<>(); + private final List pictureWidgets = new ArrayList<>(); private PictureSignType type = PictureSignType.PICTURE; public PictureSignHelperScreen(SignBlockEntity sign, boolean front, boolean filtered) { @@ -110,11 +109,6 @@ public class PictureSignHelperScreen extends Screen { text[0] = text[0].replace(type.format, ""); type = type.next(); text[0] = type.format + text[0]; -// if (text[0].startsWith("!PS:")) text[0] = "!VS:" + text[0].replace("!PS:","").replace("!VS:", "").replace("!LS:", ""); -// else if (text[0].startsWith("!VS:")) text[0] = "!LS:" + text[0].replace("!PS:","").replace("!VS:", "").replace("!LS:", ""); -// else if (text[0].startsWith("!LS:")) text[0] = "!PS:" + text[0].replace("!PS:","").replace("!VS:", "").replace("!LS:", ""); -// else text[0] = "!PS:" + text[0].replace("!PS:","").replace("!VS:", "").replace("!LS:", ""); -// type = PictureSignType.getType(text[0]); buttonWidget.setMessage(type.name); sign.changeText(changer -> changer.withMessage(0, Text.of(text[0])), front); 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 9f35625..4e654bf 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/util/GIFHandler.java +++ b/common/src/main/java/eu/midnightdust/picturesign/util/GIFHandler.java @@ -3,7 +3,6 @@ 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 me.srrapero720.watermedia.api.url.UrlAPI; import net.minecraft.client.MinecraftClient; import net.minecraft.util.Identifier; 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 2cf693c..6e46c6b 100644 --- a/common/src/main/java/eu/midnightdust/picturesign/util/MediaHandler.java +++ b/common/src/main/java/eu/midnightdust/picturesign/util/MediaHandler.java @@ -1,43 +1,37 @@ package eu.midnightdust.picturesign.util; import eu.midnightdust.picturesign.config.PictureSignConfig; -import me.srrapero720.watermedia.api.player.SyncBasePlayer; -import me.srrapero720.watermedia.api.player.SyncMusicPlayer; -import me.srrapero720.watermedia.api.player.SyncVideoPlayer; -import net.minecraft.client.MinecraftClient; import net.minecraft.client.texture.TextureManager; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import java.net.MalformedURLException; import java.util.HashMap; import java.util.Map; -import static eu.midnightdust.picturesign.PictureSignClient.client; -import static eu.midnightdust.picturesign.PictureSignClient.id; +import static eu.midnightdust.picturesign.PictureSignClient.*; -public class MediaHandler { - public static Map mediaPlayers = new HashMap<>(); +public abstract class MediaHandler { + public static Map mediaHandlers = new HashMap<>(); public final Identifier id; public final BlockPos pos; public boolean playbackStarted = false; public boolean isDeactivated; - private SyncBasePlayer player; - private int maxVolume = 100; + int maxVolume = 100; - private MediaHandler(Identifier id, BlockPos pos) { + MediaHandler(Identifier id, BlockPos pos) { this.id = id; this.pos = pos; - mediaPlayers.put(id, this); } public static MediaHandler getOrCreate(Identifier id, BlockPos pos) { - if (mediaPlayers.containsKey(id)) return mediaPlayers.get(id); - else return new MediaHandler(id, pos); + if (mediaHandlers.containsKey(id)) return mediaHandlers.get(id); + else if (hasWaterMedia) return new WaterMediaHandler(id, pos); + // Add new implementations here via Mixin + else return null; } public void setVolumeBasedOnDistance() { - if (player == null || client.player == null) return; + if (!isWorking() || client.player == null) return; Vec3d playerPos = client.player.getPos(); if (PictureSignConfig.audioDistanceMultiplier == 0) { @@ -47,74 +41,56 @@ public class MediaHandler { double distance = this.pos.getSquaredDistance(playerPos) / PictureSignConfig.audioDistanceMultiplier; setVolume((int) Math.clamp(maxVolume-distance, 0, 100)); } - private void setVolume(int volume) { - player.setVolume(volume); - } + void setVolume(int volume) {} public void setMaxVolume(int volume) { maxVolume = volume; } - public void closePlayer() { - if (player != null) { - player.stop(); - player.release(); - } - //mediaPlayers.remove(id); - player = null; - } + public void closePlayer() {} + public static void closePlayer(Identifier videoId) { - if (mediaPlayers.containsKey(videoId)) mediaPlayers.get(videoId).closePlayer(); + if (mediaHandlers.containsKey(videoId)) mediaHandlers.get(videoId).closePlayer(); } public static void closeAll() { - mediaPlayers.forEach(((id, player) -> player.closePlayer())); - mediaPlayers.clear(); + mediaHandlers.forEach(((id, player) -> player.closePlayer())); + mediaHandlers.clear(); } public void stop() { - player.stop(); isDeactivated = true; } public boolean isStopped() { - return player.isStopped(); + return false; } public boolean isPaused() { - return player.isPaused(); - } - public void pause() { - player.pause(); - } - public void restart() { - player.play(); + return false; } + public void pause() {} + public void restart() {} - public void play(String url, boolean isVideo) throws MalformedURLException { - this.player = isVideo ? new SyncVideoPlayer(MinecraftClient.getInstance()) : new SyncMusicPlayer(); - mediaPlayers.put(id, this); - if (player.isBroken()) return; - player.start(url); - this.playbackStarted = true; + public void play(String url, boolean isVideo) { } public boolean hasMedia() { - return player != null && player.isPlaying(); - } - public void setRepeat(boolean value) { - player.setRepeatMode(true); + return true; } + public void setRepeat(boolean value) {} public long getTime() { - return player.getTime(); + return -1; } public void setTime(long value) { - player.seekTo(value); } public int getTexture() { - if (player instanceof SyncVideoPlayer videoPlayer) return videoPlayer.getGlTexture(); return -1; } public boolean isWorking() { - return mediaPlayers.containsKey(id) && mediaPlayers.get(id).player != null && !mediaPlayers.get(id).player.isBroken(); + 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); } + public static boolean hasValidImplementation() { // Mixin here to add new Multimedia implementations + if (hasWaterMedia) return true; + else return false; + } } diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/WaterMediaHandler.java b/common/src/main/java/eu/midnightdust/picturesign/util/WaterMediaHandler.java new file mode 100644 index 0000000..5a560e6 --- /dev/null +++ b/common/src/main/java/eu/midnightdust/picturesign/util/WaterMediaHandler.java @@ -0,0 +1,87 @@ +package eu.midnightdust.picturesign.util; + +import me.srrapero720.watermedia.api.player.SyncBasePlayer; +import me.srrapero720.watermedia.api.player.SyncMusicPlayer; +import me.srrapero720.watermedia.api.player.SyncVideoPlayer; +import net.minecraft.client.MinecraftClient; +import net.minecraft.sound.SoundCategory; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; + +public class WaterMediaHandler extends MediaHandler { + private SyncBasePlayer player; + + WaterMediaHandler(Identifier id, BlockPos pos) { + super(id, pos); + mediaHandlers.put(id, this); + } + @Override + void setVolume(int volume) { + player.setVolume((int) (volume * MinecraftClient.getInstance().options.getSoundVolume(SoundCategory.MASTER))); + } + + @Override + public void closePlayer() { + if (player != null) { + player.stop(); + player.release(); + } + //mediaPlayers.remove(id); + player = null; + } + @Override + public void stop() { + player.stop(); + isDeactivated = true; + } + @Override + public boolean isStopped() { + return player.isStopped(); + } + @Override + public boolean isPaused() { + return player.isPaused(); + } + @Override + public void pause() { + player.pause(); + } + @Override + public void restart() { + player.play(); + } + + @Override + public void play(String url, boolean isVideo) { + this.player = isVideo ? new SyncVideoPlayer(MinecraftClient.getInstance()) : new SyncMusicPlayer(); + mediaHandlers.put(id, this); + if (player.isBroken()) return; + player.start(url); + this.playbackStarted = true; + } + @Override + public boolean hasMedia() { + return player != null && player.isPlaying(); + } + @Override + public void setRepeat(boolean value) { + player.setRepeatMode(true); + } + @Override + public long getTime() { + return player.getTime(); + } + @Override + public void setTime(long value) { + player.seekTo(value); + } + @Override + public int getTexture() { + if (player instanceof SyncVideoPlayer videoPlayer) return videoPlayer.getGlTexture(); + return -1; + } + 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/en_us.json b/common/src/main/resources/assets/picturesign/lang/en_us.json index fd82a69..b733daf 100755 --- a/common/src/main/resources/assets/picturesign/lang/en_us.json +++ b/common/src/main/resources/assets/picturesign/lang/en_us.json @@ -4,7 +4,7 @@ "picturesign.midnightconfig.category.advanced":"Advanced", "picturesign.midnightconfig.enabled":"Enable Pictures", - "picturesign.midnightconfig.enableVideoSigns":"Enable Videos", + "picturesign.midnightconfig.enableMultimediaSigns":"Enable Multimedia", "picturesign.midnightconfig.audioDistanceMultiplier":"Audio Distance Multiplier", "picturesign.midnightconfig.translucency":"Enable Translucency", "picturesign.midnightconfig.translucency.tooltip":"Translucency doesn't work too great on block entities\n(and therefore signs)", diff --git a/fabric/src/main/java/eu/midnightdust/picturesign/fabric/PictureSignClientFabric.java b/fabric/src/main/java/eu/midnightdust/picturesign/fabric/PictureSignClientFabric.java index 7233a9a..7de7315 100755 --- a/fabric/src/main/java/eu/midnightdust/picturesign/fabric/PictureSignClientFabric.java +++ b/fabric/src/main/java/eu/midnightdust/picturesign/fabric/PictureSignClientFabric.java @@ -13,7 +13,9 @@ import net.minecraft.util.Identifier; import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; -import static eu.midnightdust.picturesign.PictureSignClient.*; +import static eu.midnightdust.picturesign.PictureSignClient.BINDING_COPY_SIGN; +import static eu.midnightdust.picturesign.PictureSignClient.id; +import static eu.midnightdust.picturesign.PictureSignClient.clipboard; public class PictureSignClientFabric implements ClientModInitializer { @Override @@ -22,10 +24,10 @@ public class PictureSignClientFabric implements ClientModInitializer { KeyBindingHelper.registerKeyBinding(BINDING_COPY_SIGN); ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> { - if (hasWaterMedia) MediaHandler.closeAll(); + if (MediaHandler.hasValidImplementation()) MediaHandler.closeAll(); }); ClientBlockEntityEvents.BLOCK_ENTITY_UNLOAD.register((blockEntity, world) -> { - if (hasWaterMedia) { + if (MediaHandler.hasValidImplementation()) { BlockPos pos = blockEntity.getPos(); Identifier videoId = id(pos.getX() + "_" + pos.getY() + "_" + pos.getZ()+"_f"); MediaHandler.closePlayer(videoId); diff --git a/neoforge/src/main/java/eu/midnightdust/picturesign/neoforge/PictureSignClientGameEvents.java b/neoforge/src/main/java/eu/midnightdust/picturesign/neoforge/PictureSignClientGameEvents.java index 9bf48bd..623b0a9 100644 --- a/neoforge/src/main/java/eu/midnightdust/picturesign/neoforge/PictureSignClientGameEvents.java +++ b/neoforge/src/main/java/eu/midnightdust/picturesign/neoforge/PictureSignClientGameEvents.java @@ -16,7 +16,6 @@ import net.neoforged.neoforge.event.level.ChunkEvent; import static eu.midnightdust.picturesign.PictureSignClient.id; import static eu.midnightdust.picturesign.PictureSignClient.client; import static eu.midnightdust.picturesign.PictureSignClient.clipboard; -import static eu.midnightdust.picturesign.PictureSignClient.hasWaterMedia; import static eu.midnightdust.picturesign.PictureSignClient.MOD_ID; import static eu.midnightdust.picturesign.PictureSignClient.BINDING_COPY_SIGN; @@ -24,12 +23,12 @@ import static eu.midnightdust.picturesign.PictureSignClient.BINDING_COPY_SIGN; public class PictureSignClientGameEvents { @SubscribeEvent() public static void sendPacketOnLogin(ClientPlayerNetworkEvent.LoggingIn event) { - if (hasWaterMedia) MediaHandler.closeAll(); + if (MediaHandler.hasValidImplementation()) MediaHandler.closeAll(); } @SubscribeEvent public static void onBlockEntityUnload(ChunkEvent.Unload event) { - for (BlockPos pos : event.getChunk().getBlockEntityPositions()) { - if (hasWaterMedia) { + if (MediaHandler.hasValidImplementation()) { + for (BlockPos pos : event.getChunk().getBlockEntityPositions()) { Identifier videoId = id(pos.getX() + "_" + pos.getY() + "_" + pos.getZ() + "_f"); MediaHandler.closePlayer(videoId); Identifier videoId2 = id(pos.getX() + "_" + pos.getY() + "_" + pos.getZ() + "_b");