diff --git a/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java b/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java index 56c07c9..b42dc57 100755 --- a/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java +++ b/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java @@ -7,6 +7,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import eu.midnightdust.picturesign.PictureDownloader; import eu.midnightdust.picturesign.PictureSignClient; import eu.midnightdust.picturesign.config.PictureSignConfig; +import eu.midnightdust.picturesign.util.PictureInfo; import eu.midnightdust.picturesign.util.PictureSignType; import eu.midnightdust.picturesign.util.PictureURLUtils; import net.fabricmc.loader.api.FabricLoader; @@ -32,7 +33,16 @@ public class PictureSignRenderer { public void render(SignBlockEntity signBlockEntity, MatrixStack matrixStack, int light, int overlay) { String url = PictureURLUtils.getLink(signBlockEntity); - if (!url.startsWith("https://") && !url.startsWith("http://")) { + PictureInfo info = null; + if (!url.contains("://")) { + url = "https://" + url; + } + if (url.endsWith(".json")) { + info = PictureURLUtils.infoFromJson(url); + if (info == null) return; + url = info.url(); + } + if (!url.contains("://")) { url = "https://" + url; } //if (!url.contains(".png") && !url.contains(".jpg") && !url.contains(".jpeg")) return; @@ -49,6 +59,8 @@ public class PictureSignRenderer { if (videoManager != null) videoManager.closePlayer(new Identifier("picturesign", pos.getX() + "." + pos.getY() + "." + pos.getZ())); playedOnce.remove(pos); + videoPlayers.remove(new Identifier("picturesign", pos.getX() + "." + pos.getY() + "." + pos.getZ())); + PictureURLUtils.cachedJsonData.remove(url); return; } @@ -90,13 +102,16 @@ public class PictureSignRenderer { videoPlayer.getControlsInterface().setRepeat(true); } } - else if (!videoPlayer.getMediaInterface().hasMedia() && !playedOnce.contains(pos)) + else if (!videoPlayer.getMediaInterface().hasMedia() && !playedOnce.contains(pos)) { videoPlayer.getMediaInterface().play(url); + } } catch (MalformedURLException e) { PictureSignClient.LOGGER.error(e); return; } + if (info != null && info.start() > 0 && videoPlayer.getControlsInterface().getTime() < info.start()) videoPlayer.getControlsInterface().setTime(info.start()); + if (info != null && info.end() > 0 && videoPlayer.getControlsInterface().getTime() >= info.end() && !playedOnce.contains(pos)) videoPlayer.getControlsInterface().stop(); } else return; if (PictureSignType.isType(signBlockEntity, PictureSignType.VIDEO)) playedOnce.add(pos); diff --git a/src/main/java/eu/midnightdust/picturesign/util/PictureInfo.java b/src/main/java/eu/midnightdust/picturesign/util/PictureInfo.java new file mode 100644 index 0000000..9bd26e4 --- /dev/null +++ b/src/main/java/eu/midnightdust/picturesign/util/PictureInfo.java @@ -0,0 +1,4 @@ +package eu.midnightdust.picturesign.util; + +public record PictureInfo(String url, long start, long end, int volume) { +} diff --git a/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java b/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java index 0e0c9cd..735e121 100644 --- a/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java +++ b/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java @@ -1,8 +1,63 @@ package eu.midnightdust.picturesign.util; +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import eu.midnightdust.picturesign.PictureSignClient; +import eu.midnightdust.picturesign.config.PictureSignConfig; import net.minecraft.block.entity.SignBlockEntity; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.lang.reflect.Type; +import java.net.MalformedURLException; +import java.net.URL; +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + public class PictureURLUtils { + public static final Type STRING_TYPE = new TypeToken>(){}.getType(); + public static final Map cachedJsonData = new HashMap<>(); + private static final Gson GSON = new GsonBuilder().create(); + public static PictureInfo infoFromJson(String pathToJson) { + if (cachedJsonData.containsKey(pathToJson)) return cachedJsonData.get(pathToJson); + PictureInfo result = null; + URL json = toURL(pathToJson); + Map jsonData = null; + + try (Reader reader = new InputStreamReader(json.openStream())) { + jsonData = GSON.fromJson(reader, STRING_TYPE); + } catch (MalformedURLException error) { + PictureSignClient.LOGGER.error("Unable to load url from JSON because of connection problems: " + error.getMessage()); + } catch (IOException error) { + PictureSignClient.LOGGER.error("Unable to load url from JSON because of an I/O Exception: " + error.getMessage()); + } + if (PictureSignConfig.debug) PictureSignClient.LOGGER.info("JsonData: "+jsonData); + if (jsonData != null && !jsonData.isEmpty() && jsonData.containsKey("url")) { + result = new PictureInfo(jsonData.get("url"), getDurationMillis(jsonData.getOrDefault("start_at", "")), getDurationMillis(jsonData.getOrDefault("end_at", "")), Integer.parseInt(jsonData.getOrDefault("volume", "-1"))); + PictureSignClient.LOGGER.info("URL successfully loaded from JSON!"); + } else { + PictureSignClient.LOGGER.warn("Unable to load url from JSON"); + } + if (PictureSignConfig.debug) PictureSignClient.LOGGER.info("Result: "+result); + cachedJsonData.put(pathToJson, result); + return result; + } + private static long getDurationMillis(String duration) { + if (duration.equals("")) return -1; + String[] splitDuration = duration.split(":"); + if (splitDuration.length != 4) return -1; + return TimeUnit.MILLISECONDS.convert(Duration.parse("PT" + splitDuration[0]+"H" + splitDuration[1]+"M" + splitDuration[2]+"S")) + Long.parseLong(splitDuration[3]); + } + public static URL toURL(String string) { + URL result = null; + try { result = new URL(string); } + catch (MalformedURLException e) {PictureSignClient.LOGGER.warn("Malformed URL: " + e);} + return result; + } public static String getLink(SignBlockEntity signBlockEntity) { String text = signBlockEntity.getTextOnRow(0, false).getString() + signBlockEntity.getTextOnRow(1, false).getString() +