diff --git a/build.gradle b/build.gradle index ae4e48c..00ffda0 100755 --- a/build.gradle +++ b/build.gradle @@ -1,93 +1,82 @@ plugins { - id 'fabric-loom' version '1.2-SNAPSHOT' - id 'maven-publish' + id "architectury-plugin" version "3.4-SNAPSHOT" + id "dev.architectury.loom" version "1.6-SNAPSHOT" apply false + id "me.shedaniel.unified-publishing" version "0.1.+" apply false + id 'com.github.johnrengelman.shadow' version '8.1.1' apply false } -sourceCompatibility = JavaVersion.VERSION_17 -targetCompatibility = JavaVersion.VERSION_17 - -archivesBaseName = project.archives_base_name -version = project.mod_version -group = project.maven_group - -loom { +architectury { + minecraft = rootProject.minecraft_version } repositories { maven { url = "https://api.modrinth.com/maven" } - flatDir { - dirs("localMaven") + maven { url 'https://jitpack.io' } +} + +subprojects { + apply plugin: "dev.architectury.loom" + repositories { + maven { + url = "https://api.modrinth.com/maven" + } + maven { url 'https://jitpack.io' } + } + + dependencies { + minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" + implementation "com.github.SrRapero720.watermedia:build:${rootProject.watermedia_version}" + // The following line declares the mojmap mappings, you may use other mappings as well + //mappings loom.officialMojangMappings() + // The following line declares the yarn mappings you may select this one as well. + mappings loom.layered { + it.mappings("net.fabricmc:yarn:$rootProject.yarn_mappings:v2") + it.mappings("dev.architectury:yarn-mappings-patch-neoforge:$rootProject.yarn_mappings_patch_neoforge_version") + } } } -dependencies { - //to change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - modCompileOnly "maven.modrinth:iris:${project.iris_version}" - modImplementation "maven.modrinth:midnightlib:${project.midnightlib_version}" - include "maven.modrinth:midnightlib:${project.midnightlib_version}" - modImplementation "maven.modrinth:videolib:${project.videolib_version}" - include "maven.modrinth:videolib:${project.videolib_version}" - implementation("uk.co.caprica:vlcj:${project.vlcj_version}") -} +allprojects { + apply plugin: "java" + apply plugin: "architectury-plugin" + apply plugin: "maven-publish" -processResources { - inputs.property "version", project.version + archivesBaseName = rootProject.archives_base_name + version = rootProject.mod_version + group = rootProject.maven_group - filesMatching("fabric.mod.json") { - expand "version": project.version + repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. } -} -tasks.withType(JavaCompile).configureEach { - // ensure that the encoding is set to UTF-8, no matter what the system default is - // this fixes some edge cases with special characters not displaying correctly - // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html - // If Javadoc is generated, this must be specified in that task too. - it.options.encoding = "UTF-8" - - // Minecraft 1.17 (21w19a) upwards uses Java 16. - it.options.release = 17 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() -} - -jar { - from("LICENSE") { - rename { "${it}_${project.archivesBaseName}"} + tasks.withType(JavaCompile) { + options.encoding = "UTF-8" + options.release = 21 } -} - -// configure the maven publication -publishing { - publications { - mavenJava(MavenPublication) { - // add all the jars that should be included when publishing to maven - artifact(remapJar) { - builtBy remapJar - } - artifact(sourcesJar) { - builtBy remapSourcesJar + ext { + releaseChangelog = { + def changes = new StringBuilder() + changes << "## PictureSign v$project.version for $project.minecraft_version\n[View the changelog](https://www.github.com/TeamMidnightDust/PictureSign/commits/)" + def proc = "git log --max-count=1 --pretty=format:%s".execute() + proc.in.eachLine { line -> + def processedLine = line.toString() + if (!processedLine.contains("New translations") && !processedLine.contains("Merge") && !processedLine.contains("branch")) { + changes << "\n- ${processedLine.capitalize()}" + } } + proc.waitFor() + return changes.toString() } } - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. + java { + withSourcesJar() } } diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 0000000..ff55c16 --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,25 @@ +architectury { + common(rootProject.enabled_platforms.split(",")) +} + +dependencies { + // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies + // Do NOT use other classes from fabric loader + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + modCompileOnlyApi "maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric" + //modCompileOnly "maven.modrinth:iris:${project.iris_version}" +} + +publishing { + publications { + mavenCommon(MavenPublication) { + artifactId = rootProject.archives_base_name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} diff --git a/common/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java b/common/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java new file mode 100755 index 0000000..0fc3dcf --- /dev/null +++ b/common/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java @@ -0,0 +1,26 @@ +package eu.midnightdust.picturesign; + +import eu.midnightdust.lib.util.PlatformFunctions; +import eu.midnightdust.picturesign.config.PictureSignConfig; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.util.InputUtil; +import net.minecraft.util.Identifier; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.lwjgl.glfw.GLFW; + +public class PictureSignClient { + public static Logger LOGGER = LogManager.getLogger("PictureSign"); + public static String MOD_ID = "picturesign"; + public static final boolean hasWaterMedia = PlatformFunctions.isModLoaded("watermedia"); + public static String[] clipboard = new String[4]; + public static final KeyBinding BINDING_COPY_SIGN = new KeyBinding("key."+MOD_ID+".copy_sign", + InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_U, "key.categories."+MOD_ID); + + public static void init() { + PictureSignConfig.init(MOD_ID, PictureSignConfig.class); + } + public static Identifier id(String path) { + return Identifier.of(MOD_ID, path); + } +} diff --git a/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java b/common/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java similarity index 93% rename from src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java rename to common/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java index c58d527..44816b2 100755 --- a/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java +++ b/common/src/main/java/eu/midnightdust/picturesign/config/PictureSignConfig.java @@ -9,8 +9,8 @@ import java.util.List; import java.util.function.Supplier; public class PictureSignConfig extends MidnightConfig { - public static final String general = "1general"; - private final static String advanced = "advanced"; + private static final String general = "1general"; + private static final String advanced = "advanced"; @Entry(category = general) public static boolean enabled = true; @Entry(category = general) public static boolean enableVideoSigns = true; @@ -35,7 +35,6 @@ public class PictureSignConfig extends MidnightConfig { PosColTexLight(GameRenderer::getPositionColorTexLightmapProgram), RenderTypeCutout(GameRenderer::getRenderTypeCutoutProgram), PosTex(GameRenderer::getPositionTexProgram), - PosColTex(GameRenderer::getPositionColorTexProgram), PosTexCol(GameRenderer::getPositionTexColorProgram); PictureShader(Supplier program) { diff --git a/src/main/java/eu/midnightdust/picturesign/mixin/MixinHangingSignBlockEntityRenderer.java b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinHangingSignBlockEntityRenderer.java similarity index 74% rename from src/main/java/eu/midnightdust/picturesign/mixin/MixinHangingSignBlockEntityRenderer.java rename to common/src/main/java/eu/midnightdust/picturesign/mixin/MixinHangingSignBlockEntityRenderer.java index f9b07a7..1f24351 100755 --- a/src/main/java/eu/midnightdust/picturesign/mixin/MixinHangingSignBlockEntityRenderer.java +++ b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinHangingSignBlockEntityRenderer.java @@ -17,14 +17,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(HangingSignBlockEntityRenderer.class) public abstract class MixinHangingSignBlockEntityRenderer implements BlockEntityRenderer { - private static final MinecraftClient client = MinecraftClient.getInstance(); - PictureSignRenderer psRenderer = new PictureSignRenderer(); + @Unique private static final MinecraftClient client = MinecraftClient.getInstance(); + @Unique PictureSignRenderer psRenderer = new PictureSignRenderer(); @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.isType(sign, PictureSignType.NONE, true)) psRenderer.render(sign, matrixStack, light, overlay, true); - if (!PictureSignType.isType(sign, PictureSignType.NONE, false)) psRenderer.render(sign, matrixStack, light, overlay, false); + 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); } } @Unique @@ -35,6 +35,6 @@ public abstract class MixinHangingSignBlockEntityRenderer implements BlockEntity @Unique @Override public boolean rendersOutsideBoundingBox(SignBlockEntity sign) { - return PictureSignConfig.enabled && !PictureSignType.hasNoPicture(sign); + return PictureSignConfig.enabled && PictureSignType.hasPicture(sign); } } diff --git a/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntity.java b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntity.java similarity index 79% rename from src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntity.java rename to common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntity.java index 5a406c4..5920cfa 100644 --- a/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntity.java +++ b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntity.java @@ -11,6 +11,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import static eu.midnightdust.picturesign.PictureSignClient.MOD_ID; +import static eu.midnightdust.picturesign.PictureSignClient.id; @Mixin(value = SignBlockEntity.class, priority = 1100) public abstract class MixinSignBlockEntity extends BlockEntity { @@ -21,8 +22,8 @@ public abstract class MixinSignBlockEntity extends BlockEntity { @Override @Unique public void markRemoved() { - Identifier videoId = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ() + "_f"); - Identifier videoId2 = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ() + "_b"); + Identifier videoId = id(pos.getX() + "_" + pos.getY() + "_" + pos.getZ() + "_f"); + Identifier videoId2 = id(pos.getX() + "_" + pos.getY() + "_" + pos.getZ() + "_b"); VideoHandler.closePlayer(videoId); VideoHandler.closePlayer(videoId2); super.markRemoved(); diff --git a/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntityRenderer.java b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntityRenderer.java similarity index 74% rename from src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntityRenderer.java rename to common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntityRenderer.java index 9666239..003f08f 100755 --- a/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntityRenderer.java +++ b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignBlockEntityRenderer.java @@ -19,19 +19,19 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(SignBlockEntityRenderer.class) public abstract class MixinSignBlockEntityRenderer implements BlockEntityRenderer { - private static final MinecraftClient client = MinecraftClient.getInstance(); - PictureSignRenderer psRenderer = new PictureSignRenderer(); + @Unique private static final MinecraftClient client = MinecraftClient.getInstance(); + @Unique PictureSignRenderer psRenderer = new PictureSignRenderer(); @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.isType(sign, PictureSignType.NONE, true)) psRenderer.render(sign, matrixStack, light, overlay, true); - if (!PictureSignType.isType(sign, PictureSignType.NONE, false)) psRenderer.render(sign, matrixStack, light, overlay, false); + 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); } } @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.hasNoPicture((SignBlockEntity) client.world.getBlockEntity(pos))) cir.setReturnValue(true); + if (PictureSignConfig.enabled && client.world != null && PictureSignType.hasPicture((SignBlockEntity) client.world.getBlockEntity(pos))) cir.setReturnValue(true); } @Unique @Override @@ -41,6 +41,6 @@ public abstract class MixinSignBlockEntityRenderer implements BlockEntityRendere @Unique @Override public boolean rendersOutsideBoundingBox(SignBlockEntity sign) { - return PictureSignConfig.enabled && !PictureSignType.hasNoPicture(sign); + return PictureSignConfig.enabled && PictureSignType.hasPicture(sign); } } diff --git a/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java similarity index 88% rename from src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java rename to common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java index 56f0a4f..db5c3fb 100644 --- a/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java +++ b/common/src/main/java/eu/midnightdust/picturesign/mixin/MixinSignEditScreen.java @@ -12,6 +12,7 @@ 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.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -19,18 +20,18 @@ 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) public abstract class MixinSignEditScreen extends Screen { - private static final Identifier PICTURESIGN_ICON_TEXTURE = new Identifier(MOD_ID,"icon/picturesign"); - private static final Identifier CLIPBOARD_ICON_TEXTURE = new Identifier(MOD_ID,"icon/clipboard"); - private static final Identifier TRASHBIN_ICON_TEXTURE = new Identifier(MOD_ID,"icon/trashbin"); @Shadow @Final private SignBlockEntity blockEntity; - @Shadow @Final private String[] messages; - @Shadow @Final private boolean front; - private static boolean switchScreen = false; + + @Unique private static final Identifier PICTURESIGN_ICON_TEXTURE = id("icon/picturesign"); + @Unique private static final Identifier CLIPBOARD_ICON_TEXTURE = id("icon/clipboard"); + @Unique private static final Identifier TRASHBIN_ICON_TEXTURE = id("icon/trashbin"); + @Unique private static boolean switchScreen = false; protected MixinSignEditScreen(Text title) { super(title); diff --git a/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java b/common/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java similarity index 61% rename from src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java rename to common/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java index 0915da0..ca979a1 100755 --- a/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java +++ b/common/src/main/java/eu/midnightdust/picturesign/render/PictureSignRenderer.java @@ -5,14 +5,9 @@ import eu.midnightdust.lib.util.PlatformFunctions; import eu.midnightdust.picturesign.util.*; import eu.midnightdust.picturesign.PictureSignClient; import eu.midnightdust.picturesign.config.PictureSignConfig; -import net.fabricmc.loader.api.FabricLoader; -import net.irisshaders.iris.api.v0.IrisApi; import net.minecraft.block.Blocks; import net.minecraft.block.entity.SignBlockEntity; -import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.*; -import net.minecraft.client.texture.NativeImageBackedTexture; -import net.minecraft.client.texture.TextureManager; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.state.property.Properties; import net.minecraft.util.Identifier; @@ -22,12 +17,17 @@ import org.joml.*; import java.net.MalformedURLException; -import static eu.midnightdust.picturesign.PictureSignClient.MOD_ID; +import static eu.midnightdust.picturesign.PictureSignClient.id; public class PictureSignRenderer { private boolean isSafeUrl; - private boolean hasRotation = false; + private boolean isDeactivated = false; + private boolean playbackStarted = false; + private Identifier videoId; + private VideoHandler videoHandler; + public void render(SignBlockEntity signBlockEntity, MatrixStack matrixStack, int light, int overlay, boolean front) { + PictureSignType type = PictureSignType.getType(signBlockEntity, front); String url = PictureURLUtils.getLink(signBlockEntity, front); PictureInfo info = null; if (!url.contains("://")) { @@ -41,7 +41,7 @@ public class PictureSignRenderer { if (!url.contains("://")) { url = "https://" + url; } - if (PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE, front) && !url.contains(".png") && !url.contains(".jpg") && !url.contains(".jpeg")) return; + if (type == PictureSignType.PICTURE && !url.contains(".png") && !url.contains(".jpg") && !url.contains(".jpeg")) return; if (PictureSignConfig.safeMode) { isSafeUrl = false; String finalUrl = url; @@ -50,25 +50,35 @@ public class PictureSignRenderer { }); if (!isSafeUrl && !url.startsWith("https://youtu.be/") && !url.startsWith("https://youtube.com/") && !url.startsWith("https://www.youtube.com/")) return; } - if ((!PictureSignConfig.enableVideoSigns || !PictureSignClient.hasVideoLib) && !PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE, front)) return; + if ((!PictureSignConfig.enableVideoSigns || !PictureSignClient.hasWaterMedia) && type != PictureSignType.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://"); - url = url.replace("youtube.com/watch?v=", PictureSignConfig.invidiousInstance.replace("https://", "").replace("/", "")+"/latest_version?id="); - url = url.replace("youtu.be/", PictureSignConfig.invidiousInstance.replace("https://", "").replace("/", "")+"/latest_version?id="); + //url = url.replace("youtube.com/watch?v=", PictureSignConfig.invidiousInstance.replace("https://", "").replace("/", "")+"/latest_version?id="); + //url = url.replace("youtu.be/", PictureSignConfig.invidiousInstance.replace("https://", "").replace("/", "")+"/latest_version?id="); } World world = signBlockEntity.getWorld(); BlockPos pos = signBlockEntity.getPos(); String videoSuffix = front ? "_f" : "_b"; - Identifier videoId = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ()+videoSuffix); + if (videoId == null) videoId = id(pos.getX() + "_" + pos.getY() + "_" + pos.getZ()+videoSuffix); + if (videoHandler == null) videoHandler = new VideoHandler(videoId); + 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) || (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))) { - if (PictureSignClient.hasVideoLib) VideoHandler.closePlayer(videoId); + if (PictureSignClient.hasWaterMedia && videoHandler.isWorking() && !videoHandler.isStopped()) { + videoHandler.stop(); + } + isDeactivated = true; PictureURLUtils.cachedJsonData.remove(url); return; } + else if (isDeactivated) { + if (PictureSignClient.hasWaterMedia && videoHandler.isWorking() && videoHandler.isStopped()) + videoHandler.restart(); + isDeactivated = false; + } String lastLine = signBlockEntity.getText(front).getMessage(3, false).getString(); @@ -90,7 +100,7 @@ public class PictureSignRenderer { catch (NumberFormatException ignored) {} String thirdLine = signBlockEntity.getText(front).getMessage(2, false).getString(); - hasRotation = thirdLine.matches("(.*\\d:.*\\d:.*\\d)"); + boolean hasRotation = thirdLine.matches("(.*\\d:.*\\d:.*\\d)"); float xRot = 0; float yRot = 0; float zRot = 0; @@ -107,31 +117,30 @@ public class PictureSignRenderer { // Download the picture data PictureDownloader.PictureData data = null; - if (PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE, front)) { + if (type == PictureSignType.PICTURE) { data = PictureDownloader.getInstance().getPicture(url); if (data == null || data.identifier == null) return; } - else if (PictureSignType.isType(signBlockEntity, PictureSignType.VIDEO, front) || PictureSignType.isType(signBlockEntity, PictureSignType.LOOPED_VIDEO, front)) { - VideoHandler.videoPlayers.add(videoId); + else if (type.isVideo) { try { - if (PictureSignType.isType(signBlockEntity, PictureSignType.LOOPED_VIDEO, front) && !VideoHandler.hasMedia(videoId)) { - VideoHandler.play(videoId, url); - VideoHandler.setRepeat(videoId, true); + if (type.isLooped && !videoHandler.hasMedia() && !playbackStarted) { + videoHandler.play(url); + videoHandler.setRepeat(true); } - else if (!VideoHandler.hasMedia(videoId) && !VideoHandler.playedOnce.contains(videoId)) { - VideoHandler.play(videoId, url); + else if (!videoHandler.hasMedia() && !playbackStarted) { + videoHandler.play(url); } } catch (MalformedURLException e) { PictureSignClient.LOGGER.error(e); return; } - if (info != null && info.start() > 0 && VideoHandler.getTime(videoId) < info.start()) VideoHandler.setTime(videoId, info.start()); - if (info != null && info.end() > 0 && VideoHandler.getTime(videoId) >= info.end() && !VideoHandler.playedOnce.contains(videoId)) VideoHandler.stop(videoId); + if (info != null && info.start() > 0 && videoHandler.getTime() < info.start()) videoHandler.setTime(info.start()); + if (info != null && info.end() > 0 && videoHandler.getTime() >= info.end() && !playbackStarted) videoHandler.stop(); } else return; - if (PictureSignType.isType(signBlockEntity, PictureSignType.VIDEO, front)) VideoHandler.playedOnce.add(videoId); + if (videoId != null && !playbackStarted) playbackStarted = true; float xOffset = 0.0F; float zOffset = 0.0F; @@ -164,30 +173,26 @@ public class PictureSignRenderer { if (!front) yRotation -= 180f; Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder buffer = tessellator.getBuffer(); int l = PictureSignConfig.fullBrightPicture ? 15728880 : light; - if (FabricLoader.getInstance().isModLoaded("iris") && IrisApi.getInstance().isShaderPackInUse()) { + if (PlatformFunctions.isModLoaded("iris") && IrisCompat.isShaderPackInUse()) { RenderSystem.setShader(PictureSignConfig.pictureShader.program); } else RenderSystem.setShader(GameRenderer::getPositionColorTexLightmapProgram); - Identifier texture; - if (PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE, front)) { - assert data != null; + Identifier texture = null; + if (type == PictureSignType.PICTURE) { texture = data.identifier; } - else if (PictureSignType.isType(signBlockEntity, PictureSignType.VIDEO, front) || PictureSignType.isType(signBlockEntity, PictureSignType.LOOPED_VIDEO, front)) - texture = VideoHandler.getTexture(videoId); + else if (type.isVideo) + if (videoHandler.isWorking()) RenderSystem.setShaderTexture(0, videoHandler.getTexture()); + else { + var id = VideoHandler.getMissingTexture(); + if (id == null) return; + texture = id; + } else return; - TextureManager textureManager = MinecraftClient.getInstance().getTextureManager(); - if (textureManager.getTexture(texture) == null || (textureManager.getTexture(texture) instanceof NativeImageBackedTexture nativeTexture && nativeTexture.getImage() == null) || - (!PictureSignType.isType(signBlockEntity, PictureSignType.PICTURE, front) && VideoHandler.getFramerate(videoId) < 1)) { - if (PictureSignConfig.missingImageMode.equals(PictureSignConfig.MissingImageMode.TRANSPARENT)) return; - texture = PictureSignConfig.missingImageMode.equals(PictureSignConfig.MissingImageMode.BLACK) ? - (new Identifier(MOD_ID, "textures/black.png")) : (TextureManager.MISSING_IDENTIFIER); - } - RenderSystem.setShaderTexture(0, texture); + if (texture != null) RenderSystem.setShaderTexture(0, texture); if (PictureSignConfig.translucency) RenderSystem.enableBlend(); else RenderSystem.disableBlend(); @@ -199,26 +204,20 @@ public class PictureSignRenderer { matrixStack.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yRotation + yRot)); matrixStack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(xRot)); matrixStack.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(zRot)); - //System.out.println(hasRotation +" "+ xRot + " " + yRot + " " + zRot); - - //matrixStack.multiply(new Quaternionf(new AxisAngle4d(Math.toRadians(yRotation + yRot), 0, 1, 0))); Matrix4f matrix4f = matrixStack.peek().getPositionMatrix(); - buffer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE_LIGHT); + BufferBuilder buffer = tessellator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE_LIGHT); - buffer.vertex(matrix4f, width, 0.0F, 1.0F).color(255, 255, 255, 255).texture(1.0F, 1.0F).light(l).overlay(overlay) - .next(); + buffer.vertex(matrix4f, width, 0.0F, 1.0F).color(255, 255, 255, 255).texture(1.0F, 1.0F).light(l).overlay(overlay); - buffer.vertex(matrix4f, width, height, 1.0F).color(255, 255, 255, 255).texture(1.0F, 0.0F).light(l).overlay(overlay) - .next(); + buffer.vertex(matrix4f, width, height, 1.0F).color(255, 255, 255, 255).texture(1.0F, 0.0F).light(l).overlay(overlay); - buffer.vertex(matrix4f, 0.0F, height, 1.0F).color(255, 255, 255, 255).texture(0.0F, 0.0F).light(l).overlay(overlay) - .next(); + buffer.vertex(matrix4f, 0.0F, height, 1.0F).color(255, 255, 255, 255).texture(0.0F, 0.0F).light(l).overlay(overlay); - buffer.vertex(matrix4f, 0.0F, 0.0F, 1.0F).color(255, 255, 255, 255).texture(0.0F, 1.0F).light(l).overlay(overlay) - .next(); + buffer.vertex(matrix4f, 0.0F, 0.0F, 1.0F).color(255, 255, 255, 255).texture(0.0F, 1.0F).light(l).overlay(overlay); + + BufferRenderer.drawWithGlobalProgram(buffer.end()); - tessellator.draw(); matrixStack.pop(); RenderSystem.disableBlend(); diff --git a/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java b/common/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java similarity index 88% rename from src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java rename to common/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java index f19a2e0..f85baeb 100644 --- a/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java +++ b/common/src/main/java/eu/midnightdust/picturesign/screen/PictureSignHelperScreen.java @@ -33,12 +33,12 @@ import java.util.Objects; import java.util.function.Consumer; import java.util.stream.IntStream; -import static eu.midnightdust.picturesign.PictureSignClient.MOD_ID; +import static eu.midnightdust.picturesign.PictureSignClient.id; public class PictureSignHelperScreen extends Screen { - private static final Identifier TEXTSIGN_ICON_TEXTURE = new Identifier(MOD_ID,"icon/textsign"); - private static final Identifier CLIPBOARD_ICON_TEXTURE = new Identifier(MOD_ID,"icon/clipboard"); - private static final Identifier TRASHBIN_ICON_TEXTURE = new Identifier(MOD_ID,"icon/trashbin"); + private static final Identifier TEXTSIGN_ICON_TEXTURE = id("icon/textsign"); + private static final Identifier CLIPBOARD_ICON_TEXTURE = id("icon/clipboard"); + private static final Identifier TRASHBIN_ICON_TEXTURE = id("icon/trashbin"); private final SignBlockEntity sign; private SignBlockEntityRenderer.SignModel model; protected String[] text; @@ -46,7 +46,7 @@ public class PictureSignHelperScreen extends Screen { private final boolean isHanging; protected final WoodType signType; private static boolean switchScreen = false; - private PictureSignType pictureSignType = PictureSignType.PICTURE; + private PictureSignType type = PictureSignType.PICTURE; public PictureSignHelperScreen(SignBlockEntity sign, boolean front, boolean filtered) { super((sign.getCachedState().getBlock() instanceof HangingSignBlock || sign.getCachedState().getBlock() instanceof WallHangingSignBlock) ? Text.translatable("hanging_sign.edit") : Text.translatable("sign.edit")); @@ -64,7 +64,7 @@ public class PictureSignHelperScreen extends Screen { text = IntStream.range(0, 4).mapToObj((row) -> sign.getText(front).getMessage(row, false)).map(Text::getString).toArray(String[]::new); if (!text[3].matches("(.*\\d:.*\\d:.*\\d:.*\\d:.*\\d)")) text[3] = "1:1:0:0:0"; - if (!text[0].startsWith("!PS:") && !text[0].startsWith("!VS:") && !text[0].startsWith("!LS:")) text[0] = "!PS:"+text[0]; + if (!text[0].startsWith("!")) text[0] = PictureSignType.PICTURE.format+text[0]; if (text[2].isBlank() && PictureSignConfig.exceedVanillaLineLength) text[2] = "0:0:0"; for (int i = 0; i < 4; i++) { int finalI = i; @@ -105,15 +105,17 @@ public class PictureSignHelperScreen extends Screen { textsignBuilder.setPosition(this.width - 40, this.height - 40); this.addDrawableChild(textsignBuilder); } - if (text[0].startsWith("!VS:")) pictureSignType = PictureSignType.VIDEO; - if (text[0].startsWith("!LS:")) pictureSignType = PictureSignType.LOOPED_VIDEO; - this.addDrawableChild(ButtonWidget.builder(Text.of(text[0].startsWith("!PS:") ? "Image" : (text[0].startsWith("!VS:") ? "Video" : "Loop")), (buttonWidget) -> { - 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:", ""); - buttonWidget.setMessage(Text.of(text[0].startsWith("!PS:") ? "Image" : (text[0].startsWith("!VS:") ? "Video" : "Loop"))); - pictureSignType = text[0].startsWith("!PS:") ? PictureSignType.PICTURE : (text[0].startsWith("!VS:") ? PictureSignType.VIDEO : PictureSignType.LOOPED_VIDEO); + type = PictureSignType.getType(text[0]); + this.addDrawableChild(ButtonWidget.builder(type.name, (buttonWidget) -> { + 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); }).dimensions(this.width / 2,this.height / 5 + 70,40,20).build()); @@ -121,11 +123,7 @@ public class PictureSignHelperScreen extends Screen { linkWidget.setMaxLength(900); linkWidget.setText(PictureURLUtils.getLink(sign, front)); linkWidget.setChangedListener(s -> { - String prefix = ""; - if (text[0].startsWith("!PS:")) prefix = "!PS:"; - else if (text[0].startsWith("!VS:")) prefix = "!VS:"; - else if (text[0].startsWith("!LS:")) prefix = "!LS:"; - String[] lines = breakLink(prefix, PictureURLUtils.shortenLink(s)); + String[] lines = breakLink(type.format, PictureURLUtils.shortenLink(s)); for (int i = 0; i < (PictureSignConfig.exceedVanillaLineLength ? 2 : 3); i++) { text[i] = lines[i]; int finalI = i; @@ -273,10 +271,11 @@ public class PictureSignHelperScreen extends Screen { } } public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); if (this.client == null) return; DiffuseLighting.disableGuiDepthLighting(); context.drawTextWithShadow(textRenderer, Text.of("Link" + - (PictureSignConfig.safeMode ? (pictureSignType.equals(PictureSignType.PICTURE) ? " (imgur.com/imgbb.com/iili.io/pictshare.net)" : " (youtube.com/youtu.be/vimeo.com)") : "")), + (PictureSignConfig.safeMode ? (type.equals(PictureSignType.PICTURE) ? " (imgur.com/imgbb.com/iili.io/pictshare.net)" : " (youtube.com/youtu.be/vimeo.com)") : "")), 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); @@ -325,8 +324,6 @@ public class PictureSignHelperScreen extends Screen { matrices.pop(); DiffuseLighting.enableGuiDepthLighting(); - - super.render(context, mouseX, mouseY, delta); } protected void translateForRender(DrawContext context, BlockState state) { MatrixStack matrices = context.getMatrices(); @@ -367,7 +364,7 @@ public class PictureSignHelperScreen extends Screen { else { MatrixStack matrices = context.getMatrices(); matrices.scale(4.5F, 4.5F, 1.0F); - context.drawTexture(new Identifier("textures/gui/hanging_signs/" + this.signType.name() + ".png"), -8, -8, 0.0F, 0.0F, 16, 16, 16, 16); + context.drawTexture(Identifier.ofVanilla("textures/gui/hanging_signs/" + this.signType.name() + ".png"), -8, -8, 0.0F, 0.0F, 16, 16, 16, 16); } } diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/IrisCompat.java b/common/src/main/java/eu/midnightdust/picturesign/util/IrisCompat.java new file mode 100644 index 0000000..06b28fe --- /dev/null +++ b/common/src/main/java/eu/midnightdust/picturesign/util/IrisCompat.java @@ -0,0 +1,9 @@ +package eu.midnightdust.picturesign.util; + +//import net.irisshaders.iris.api.v0.IrisApi; + +public class IrisCompat { + public static boolean isShaderPackInUse() { + return false;//IrisApi.getInstance().isShaderPackInUse(); + } +} diff --git a/src/main/java/eu/midnightdust/picturesign/util/PictureDownloader.java b/common/src/main/java/eu/midnightdust/picturesign/util/PictureDownloader.java similarity index 100% rename from src/main/java/eu/midnightdust/picturesign/util/PictureDownloader.java rename to common/src/main/java/eu/midnightdust/picturesign/util/PictureDownloader.java diff --git a/src/main/java/eu/midnightdust/picturesign/util/PictureInfo.java b/common/src/main/java/eu/midnightdust/picturesign/util/PictureInfo.java similarity index 100% rename from src/main/java/eu/midnightdust/picturesign/util/PictureInfo.java rename to common/src/main/java/eu/midnightdust/picturesign/util/PictureInfo.java diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/PictureSignType.java b/common/src/main/java/eu/midnightdust/picturesign/util/PictureSignType.java new file mode 100644 index 0000000..4b5f94f --- /dev/null +++ b/common/src/main/java/eu/midnightdust/picturesign/util/PictureSignType.java @@ -0,0 +1,59 @@ +package eu.midnightdust.picturesign.util; + +import net.minecraft.block.entity.SignBlockEntity; +import net.minecraft.text.Text; + +public enum PictureSignType { + NONE(Text.empty(), ""), + PICTURE(Text.of("Image"), "!PS:"), + 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"), "!LAS:", true, false, true); + + public final Text name; + public final String format; + public final boolean isLooped; + public final boolean isVideo; + public final boolean isAudio; + PictureSignType(Text name, String format) { + this(name, format, false, false, false); + } + + PictureSignType(Text name, String format, boolean isLooped, boolean isVideo, boolean isAudio) { + this.name = name; + this.format = format; + this.isLooped = isLooped; + this.isVideo = isVideo; + this.isAudio = isAudio; + } + + public static PictureSignType getType(SignBlockEntity signBlockEntity, boolean front) { + return getType(signBlockEntity.getText(front).getMessage(0,false).getString()); + } + public static PictureSignType getType(String lineOne) { + if (lineOne.startsWith("!PS:")) return PICTURE; + else if (lineOne.startsWith("!VS:")) return VIDEO; + else if (lineOne.startsWith("!LS:")) return LOOPED_VIDEO; + else if (lineOne.startsWith("!AS:")) return AUDIO; + else if (lineOne.startsWith("!LAS:")) return LOOPED_AUDIO; + else return NONE; + } + public PictureSignType next() { + return switch (this) { + case PICTURE -> VIDEO; + case VIDEO -> LOOPED_VIDEO; + case LOOPED_VIDEO -> AUDIO; + case AUDIO -> LOOPED_AUDIO; + case LOOPED_AUDIO -> PICTURE; + default -> NONE; + }; + } + + public static boolean isNotOfType(SignBlockEntity signBlockEntity, PictureSignType type, boolean front) { + return getType(signBlockEntity, front) != type; + } + public static boolean hasPicture(SignBlockEntity signBlockEntity) { + return isNotOfType(signBlockEntity, NONE, true) || isNotOfType(signBlockEntity, NONE, false); + } +} diff --git a/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java b/common/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java similarity index 97% rename from src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java rename to common/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java index 9d0f1ba..723576d 100644 --- a/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java +++ b/common/src/main/java/eu/midnightdust/picturesign/util/PictureURLUtils.java @@ -12,6 +12,7 @@ import java.io.InputStreamReader; import java.io.Reader; import java.lang.reflect.Type; import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; import java.time.Duration; import java.util.HashMap; @@ -22,6 +23,7 @@ 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; @@ -48,14 +50,14 @@ public class PictureURLUtils { return result; } private static long getDurationMillis(String duration) { - if (duration.equals("")) return -1; + if (duration.isEmpty()) 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); } + try { result = URI.create(string).toURL(); } catch (MalformedURLException e) {PictureSignClient.LOGGER.warn("Malformed URL: " + e);} return result; } diff --git a/common/src/main/java/eu/midnightdust/picturesign/util/VideoHandler.java b/common/src/main/java/eu/midnightdust/picturesign/util/VideoHandler.java new file mode 100644 index 0000000..e3a89c5 --- /dev/null +++ b/common/src/main/java/eu/midnightdust/picturesign/util/VideoHandler.java @@ -0,0 +1,87 @@ +package eu.midnightdust.picturesign.util; + +import eu.midnightdust.picturesign.config.PictureSignConfig; +import me.srrapero720.watermedia.api.player.SyncVideoPlayer; +import me.srrapero720.watermedia.api.url.UrlAPI; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.texture.TextureManager; +import net.minecraft.util.Identifier; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import static eu.midnightdust.picturesign.PictureSignClient.id; + +public class VideoHandler { + public static Map videoPlayers = new HashMap<>(); + + private final Identifier id; + private SyncVideoPlayer player; + + public VideoHandler(Identifier id) { + this.id = id; + } + + public void closePlayer() { + if (videoPlayers.containsKey(id)) videoPlayers.get(id).release(); + videoPlayers.remove(id); + player = null; + } + public static void closePlayer(Identifier videoId) { + if (videoPlayers.containsKey(videoId)) videoPlayers.get(videoId).release(); + videoPlayers.remove(videoId); + } + public static void closeAll() { + videoPlayers.forEach(((id, player) -> player.release())); + videoPlayers.clear(); + } + public void stop() { + player.stop(); + } + public boolean isStopped() { + return player.isStopped(); + } + public boolean isPaused() { + return player.isPaused(); + } + public void pause() { + player.pause(); + } + public void restart() { + player.play(); + } + + public void play(String url) throws MalformedURLException { + URL fixedUrl = UrlAPI.fixURL(url).url; + System.out.println("Fixed URL: " + fixedUrl); + this.player = new SyncVideoPlayer(MinecraftClient.getInstance()); + videoPlayers.put(id, player); + if (player.isBroken()) return; + player.start(fixedUrl.toString()); + } + public boolean hasMedia() { + return player != null && player.isPlaying(); + } + public void setRepeat(boolean value) { + player.setRepeatMode(true); + } + public long getTime() { + return player.getTime(); + } + public void setTime(long value) { + player.seekTo(value); + } + public int getTexture() { + return player.getGlTexture(); + } + public boolean isWorking() { + return videoPlayers.containsKey(id) && !videoPlayers.get(id).isBroken(); + } + 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/src/main/resources/assets/picturesign/icon.png b/common/src/main/resources/assets/picturesign/icon.png similarity index 100% rename from src/main/resources/assets/picturesign/icon.png rename to common/src/main/resources/assets/picturesign/icon.png diff --git a/src/main/resources/assets/picturesign/lang/de_de.json b/common/src/main/resources/assets/picturesign/lang/de_de.json similarity index 100% rename from src/main/resources/assets/picturesign/lang/de_de.json rename to common/src/main/resources/assets/picturesign/lang/de_de.json diff --git a/src/main/resources/assets/picturesign/lang/en_us.json b/common/src/main/resources/assets/picturesign/lang/en_us.json similarity index 100% rename from src/main/resources/assets/picturesign/lang/en_us.json rename to common/src/main/resources/assets/picturesign/lang/en_us.json diff --git a/src/main/resources/assets/picturesign/textures/black.png b/common/src/main/resources/assets/picturesign/textures/black.png similarity index 100% rename from src/main/resources/assets/picturesign/textures/black.png rename to common/src/main/resources/assets/picturesign/textures/black.png diff --git a/src/main/resources/assets/picturesign/textures/gui/sprites/icon/clipboard.png b/common/src/main/resources/assets/picturesign/textures/gui/sprites/icon/clipboard.png similarity index 100% rename from src/main/resources/assets/picturesign/textures/gui/sprites/icon/clipboard.png rename to common/src/main/resources/assets/picturesign/textures/gui/sprites/icon/clipboard.png diff --git a/src/main/resources/assets/picturesign/textures/gui/sprites/icon/picturesign.png b/common/src/main/resources/assets/picturesign/textures/gui/sprites/icon/picturesign.png similarity index 100% rename from src/main/resources/assets/picturesign/textures/gui/sprites/icon/picturesign.png rename to common/src/main/resources/assets/picturesign/textures/gui/sprites/icon/picturesign.png diff --git a/src/main/resources/assets/picturesign/textures/gui/sprites/icon/textsign.png b/common/src/main/resources/assets/picturesign/textures/gui/sprites/icon/textsign.png similarity index 100% rename from src/main/resources/assets/picturesign/textures/gui/sprites/icon/textsign.png rename to common/src/main/resources/assets/picturesign/textures/gui/sprites/icon/textsign.png diff --git a/src/main/resources/assets/picturesign/textures/gui/sprites/icon/trashbin.png b/common/src/main/resources/assets/picturesign/textures/gui/sprites/icon/trashbin.png similarity index 100% rename from src/main/resources/assets/picturesign/textures/gui/sprites/icon/trashbin.png rename to common/src/main/resources/assets/picturesign/textures/gui/sprites/icon/trashbin.png diff --git a/src/main/resources/picturesign.mixins.json b/common/src/main/resources/picturesign.mixins.json similarity index 100% rename from src/main/resources/picturesign.mixins.json rename to common/src/main/resources/picturesign.mixins.json diff --git a/fabric/build.gradle b/fabric/build.gradle new file mode 100644 index 0000000..d59a2dc --- /dev/null +++ b/fabric/build.gradle @@ -0,0 +1,106 @@ +plugins { + id 'com.github.johnrengelman.shadow' + id "me.shedaniel.unified-publishing" +} + +architectury { + platformSetupLoomIde() + fabric() +} + +loom { +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin since it *excludes* files. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentFabric.extendsFrom common + archivesBaseName = rootProject.archives_base_name + "-fabric" +} + +dependencies { + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" + modImplementation include ("maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric") + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +shadowJar { + exclude "architectury.common.json" + + configurations = [project.configurations.shadowCommon] + archiveClassifier = "dev-shadow" +} + +remapJar { + input.set shadowJar.archiveFile + dependsOn shadowJar +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +unifiedPublishing { + project { + displayName = "PictureSign $project.version - Fabric $project.minecraft_version" + releaseType = "$project.release_type" + changelog = releaseChangelog() + gameVersions = [] + gameLoaders = ["fabric","quilt"] + mainPublication remapJar + relations { + depends { + curseforge = "fabric-api" + modrinth = "fabric-api" + } + depends { + curseforge = "watermedia" + modrinth = "watermedia" + } + includes { + curseforge = "midnightlib" + modrinth = "midnightlib" + } + } + + var CURSEFORGE_TOKEN = project.findProperty("CURSEFORGE_TOKEN") ?: System.getenv("CURSEFORGE_TOKEN") + if (CURSEFORGE_TOKEN != null) { + curseforge { + token = CURSEFORGE_TOKEN + id = rootProject.curseforge_id + gameVersions.addAll "Java 21", project.minecraft_version + } + } + + var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN") + if (MODRINTH_TOKEN != null) { + modrinth { + token = MODRINTH_TOKEN + id = rootProject.modrinth_id + version = "$project.version-$project.name" + gameVersions.addAll project.minecraft_version + } + } + } +} \ No newline at end of file diff --git a/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java b/fabric/src/main/java/eu/midnightdust/picturesign/fabric/PictureSignClientFabric.java similarity index 57% rename from src/main/java/eu/midnightdust/picturesign/PictureSignClient.java rename to fabric/src/main/java/eu/midnightdust/picturesign/fabric/PictureSignClientFabric.java index 8a69351..fdf1834 100755 --- a/src/main/java/eu/midnightdust/picturesign/PictureSignClient.java +++ b/fabric/src/main/java/eu/midnightdust/picturesign/fabric/PictureSignClientFabric.java @@ -1,7 +1,6 @@ -package eu.midnightdust.picturesign; +package eu.midnightdust.picturesign.fabric; -import eu.midnightdust.lib.util.PlatformFunctions; -import eu.midnightdust.picturesign.config.PictureSignConfig; +import eu.midnightdust.picturesign.PictureSignClient; import eu.midnightdust.picturesign.util.VideoHandler; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents; @@ -9,42 +8,33 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.minecraft.block.entity.SignBlockEntity; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; import net.minecraft.util.Identifier; 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 MOD_ID = "picturesign"; - public static final boolean hasVideoLib = PlatformFunctions.isModLoaded("videolib"); - public static String[] clipboard = new String[4]; - public static final KeyBinding BINDING_COPY_SIGN = new KeyBinding("key."+MOD_ID+".copy_sign", - InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_U, "key.categories."+MOD_ID); +import static eu.midnightdust.picturesign.PictureSignClient.*; + +public class PictureSignClientFabric implements ClientModInitializer { @Override public void onInitializeClient() { - PictureSignConfig.init(MOD_ID, PictureSignConfig.class); + PictureSignClient.init(); KeyBindingHelper.registerKeyBinding(BINDING_COPY_SIGN); ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> { - if (hasVideoLib) VideoHandler.closeAll(); + if (hasWaterMedia) VideoHandler.closeAll(); }); ClientBlockEntityEvents.BLOCK_ENTITY_UNLOAD.register((blockEntity, world) -> { - if (hasVideoLib) { + if (hasWaterMedia) { BlockPos pos = blockEntity.getPos(); - Identifier videoId = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ()+"_f"); + Identifier videoId = id(pos.getX() + "_" + pos.getY() + "_" + pos.getZ()+"_f"); VideoHandler.closePlayer(videoId); - Identifier videoId2 = new Identifier(MOD_ID, pos.getX() + "_" + pos.getY() + "_" + pos.getZ()+"_b"); + Identifier videoId2 = id(pos.getX() + "_" + pos.getY() + "_" + pos.getZ()+"_b"); VideoHandler.closePlayer(videoId2); } }); ClientTickEvents.END_CLIENT_TICK.register(client -> { - if (!PictureSignClient.BINDING_COPY_SIGN.isPressed()) return; - PictureSignClient.BINDING_COPY_SIGN.setPressed(false); + if (!BINDING_COPY_SIGN.isPressed()) return; + BINDING_COPY_SIGN.setPressed(false); if (client.player == null || client.world == null || client.crosshairTarget == null || client.crosshairTarget.getType() != HitResult.Type.BLOCK) return; if (client.crosshairTarget.getType() == HitResult.Type.BLOCK && client.world.getBlockState(BlockPos.ofFloored(client.crosshairTarget.getPos())).hasBlockEntity()) { if (client.world.getBlockEntity(BlockPos.ofFloored(client.crosshairTarget.getPos())) instanceof SignBlockEntity sign) { diff --git a/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json similarity index 73% rename from src/main/resources/fabric.mod.json rename to fabric/src/main/resources/fabric.mod.json index 9f887c7..248bb92 100755 --- a/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -4,7 +4,7 @@ "version": "${version}", "name": "PictureSign", - "description": "Use signs to display custom images completely client-side!", + "description": "Use signs to display custom images and videos completely client-side!", "authors": [ "Motschen", "TeamMidnightDust" @@ -21,12 +21,13 @@ "environment": "client", "entrypoints": { "client": [ - "eu.midnightdust.picturesign.PictureSignClient" + "eu.midnightdust.picturesign.fabric.PictureSignClientFabric" ] }, "depends": { - "midnightlib": "*" + "midnightlib": "*", + "watermedia": "*" }, "mixins": [ "picturesign.mixins.json" diff --git a/gradle.properties b/gradle.properties index f57b4e6..c9a7fed 100755 --- a/gradle.properties +++ b/gradle.properties @@ -1,22 +1,25 @@ -# Done to increase the memory available to gradle. -org.gradle.jvmargs=-Xmx1G +org.gradle.jvmargs=-Xmx2048M -# Fabric Properties - # check these on https://fabricmc.net/use - minecraft_version=1.20.2 - yarn_mappings=1.20.2+build.4 - loader_version=0.14.24 +minecraft_version=1.21 +yarn_mappings=1.21+build.2 +enabled_platforms=fabric,neoforge -# Mod Properties - mod_version = 2.0.0-beta.2 - maven_group = eu.midnightdust - archives_base_name = picturesign +archives_base_name=picturesign +mod_version=2.0.0-beta.2 +maven_group=eu.midnightdust +release_type=release +curseforge_id=432008 +modrinth_id=YQnwl5Vv -# Dependencies - # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api - fabric_version=0.90.7+1.20.2 - midnightlib_version=1.5.0-fabric - videolib_version=0.2.2-mnd - vlcj_version=4.8.2 +midnightlib_version=1.5.7 +watermedia_version=2.0.63 +iris_version=1.7.1+1.21 - iris_version=1.6.4+1.20 +fabric_loader_version=0.15.11 +fabric_api_version=0.100.1+1.21 + +neoforge_version=21.0.14-beta +yarn_mappings_patch_neoforge_version = 1.21+build.4 + +quilt_loader_version=0.19.0-beta.18 +quilt_fabric_api_version=7.0.1+0.83.0-1.20 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180..e644113 100755 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 59bc51a..a441313 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c787..b740cf1 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +80,11 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -205,6 +214,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd3..7101f8e 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,89 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/localMaven/videolib-0.2.2-mnd.jar b/localMaven/videolib-0.2.2-mnd.jar deleted file mode 100644 index ba9f807..0000000 Binary files a/localMaven/videolib-0.2.2-mnd.jar and /dev/null differ diff --git a/neoforge/build.gradle b/neoforge/build.gradle new file mode 100644 index 0000000..3097019 --- /dev/null +++ b/neoforge/build.gradle @@ -0,0 +1,116 @@ +plugins { + id 'com.github.johnrengelman.shadow' + id "me.shedaniel.unified-publishing" +} + +repositories { + maven { + name = 'NeoForged' + url = 'https://maven.neoforged.net/releases' + } +} + + +architectury { + platformSetupLoomIde() + neoForge() +} + +loom { + accessWidenerPath = project(":common").loom.accessWidenerPath +} + +configurations { + common { + canBeResolved = true + canBeConsumed = false + } + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentNeoForge.extendsFrom common + + // Files in this configuration will be bundled into your mod using the Shadow plugin. + // Don't use the `shadow` configuration from the plugin itself as it's meant for excluding files. + shadowBundle { + canBeResolved = true + canBeConsumed = false + } + archivesBaseName = rootProject.archives_base_name + "-neoforge" +} + +dependencies { + neoForge "net.neoforged:neoforge:$rootProject.neoforge_version" + modImplementation include ("maven.modrinth:midnightlib:${rootProject.midnightlib_version}-neoforge") + + common(project(path: ':common', configuration: 'namedElements')) { transitive false } + shadowBundle project(path: ':common', configuration: 'transformProductionNeoForge') +} + +processResources { + inputs.property 'version', project.version + + filesMatching('META-INF/neoforge.mods.toml') { + expand version: project.version + } +} + +shadowJar { + configurations = [project.configurations.shadowBundle] + archiveClassifier = 'dev-shadow' +} + +remapJar { + input.set shadowJar.archiveFile +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +unifiedPublishing { + project { + displayName = "PictureSign $project.version - NeoForge $project.minecraft_version" + releaseType = "$project.release_type" + changelog = releaseChangelog() + gameVersions = [] + gameLoaders = ["neoforge"] + mainPublication remapJar + relations { + depends { + curseforge = "watermedia" + modrinth = "watermedia" + } + includes { + curseforge = "midnightlib" + modrinth = "midnightlib" + } + } + + var CURSEFORGE_TOKEN = project.findProperty("CURSEFORGE_TOKEN") ?: System.getenv("CURSEFORGE_TOKEN") + if (CURSEFORGE_TOKEN != null) { + curseforge { + token = CURSEFORGE_TOKEN + id = rootProject.curseforge_id + gameVersions.addAll "Java 21", project.minecraft_version + } + } + + var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN") + if (MODRINTH_TOKEN != null) { + modrinth { + token = MODRINTH_TOKEN + id = rootProject.modrinth_id + version = "$project.version-$project.name" + gameVersions.addAll project.minecraft_version + } + } + } +} diff --git a/neoforge/gradle.properties b/neoforge/gradle.properties new file mode 100644 index 0000000..2914393 --- /dev/null +++ b/neoforge/gradle.properties @@ -0,0 +1 @@ +loom.platform=neoforge \ No newline at end of file diff --git a/neoforge/resources/META-INF/neoforge.mods.toml b/neoforge/resources/META-INF/neoforge.mods.toml new file mode 100644 index 0000000..4d1c3b1 --- /dev/null +++ b/neoforge/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,38 @@ +modLoader = "javafml" +loaderVersion = "[2,)" +#issueTrackerURL = "" +license = "MIT License" + +[[mods]] +modId = "picturesign" +version = "${version}" +displayName = "PictureSign" +logoFile = "icon.png" +authors = "Motschen, TeamMidnightDust" +description = ''' +Use signs to display custom images and videos completely client-side! +''' + +[[mixins]] +config = "picturesign.mixins.json" + +[[dependencies.visualoverhaul]] +modId = "neoforge" +mandatory = true +versionRange = "[21.0,)" +ordering = "NONE" +side = "BOTH" + +[[dependencies.visualoverhaul]] +modId = "minecraft" +mandatory = true +versionRange = "[1.21,)" +ordering = "NONE" +side = "BOTH" + +[[dependencies.visualoverhaul]] +modId = "midnightlib" +mandatory = true +versionRange = "[1.0,)" +ordering = "AFTER" +side = "BOTH" diff --git a/neoforge/resources/icon.png b/neoforge/resources/icon.png new file mode 100755 index 0000000..2a0d83a Binary files /dev/null and b/neoforge/resources/icon.png differ diff --git a/settings.gradle b/settings.gradle index 5b60df3..5011340 100755 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,15 @@ pluginManagement { repositories { - jcenter() - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } + maven { url "https://maven.fabricmc.net/" } + maven { url "https://maven.architectury.dev/" } + maven { url "https://maven.neoforged.net/releases" } gradlePluginPortal() } } + +include("common") +include("fabric") +//include("quilt") +include("neoforge") + +rootProject.name = "picturesign" diff --git a/src/main/java/eu/midnightdust/picturesign/util/PictureSignType.java b/src/main/java/eu/midnightdust/picturesign/util/PictureSignType.java deleted file mode 100644 index 776f702..0000000 --- a/src/main/java/eu/midnightdust/picturesign/util/PictureSignType.java +++ /dev/null @@ -1,20 +0,0 @@ -package eu.midnightdust.picturesign.util; - -import net.minecraft.block.entity.SignBlockEntity; - -public enum PictureSignType { - NONE, PICTURE, VIDEO, LOOPED_VIDEO; - public static PictureSignType getType(SignBlockEntity signBlockEntity, boolean front) { - String rowOne = signBlockEntity.getText(front).getMessage(0,false).getString(); - if (rowOne.startsWith("!PS:")) return PICTURE; - if (rowOne.startsWith("!VS:")) return VIDEO; - if (rowOne.startsWith("!LS:")) return LOOPED_VIDEO; - else return NONE; - } - public static boolean isType(SignBlockEntity signBlockEntity, PictureSignType type, boolean front) { - return getType(signBlockEntity, front) == type; - } - public static boolean hasNoPicture(SignBlockEntity signBlockEntity) { - return isType(signBlockEntity, NONE, true) && isType(signBlockEntity, NONE, false); - } -} diff --git a/src/main/java/eu/midnightdust/picturesign/util/VideoHandler.java b/src/main/java/eu/midnightdust/picturesign/util/VideoHandler.java deleted file mode 100644 index 3054773..0000000 --- a/src/main/java/eu/midnightdust/picturesign/util/VideoHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -package eu.midnightdust.picturesign.util; - -import com.igrium.videolib.VideoLib; -import com.igrium.videolib.api.VideoManager; -import net.minecraft.util.Identifier; - -import java.net.MalformedURLException; -import java.util.ArrayList; -import java.util.List; - -public class VideoHandler { - public static List videoPlayers = new ArrayList<>(); - public static List playedOnce = new ArrayList<>(); - static VideoManager videoManager = VideoLib.getInstance().getVideoManager(); - public static void closePlayer(Identifier id) { - videoManager.closePlayer(id); - videoPlayers.remove(id); - playedOnce.remove(id); - } - public static void closeAll() { - try {videoManager.close();} catch (Exception ignored) {} - videoPlayers.clear(); - playedOnce.clear(); - } - public static void stop(Identifier id) { - videoManager.getOrCreate(id).getControlsInterface().stop(); - } - public static void play(Identifier id, String url) throws MalformedURLException { - videoManager.getOrCreate(id).getMediaInterface().play(url); - } - public static boolean hasMedia(Identifier id) { - return videoManager.getOrCreate(id).getMediaInterface().hasMedia(); - } - public static void setRepeat(Identifier id, boolean value) { - videoManager.getOrCreate(id).getControlsInterface().setRepeat(value); - } - public static long getTime(Identifier id) { - return videoManager.getOrCreate(id).getControlsInterface().getTime(); - } - public static void setTime(Identifier id, long value) { - videoManager.getOrCreate(id).getControlsInterface().setTime(value); - } - public static Identifier getTexture(Identifier id) { - return videoManager.getOrCreate(id).getTexture(); - } - public static float getFramerate(Identifier id) { - return videoManager.getOrCreate(id).getCodecInterface().getFrameRate(); - } -}