From 83cc2d91117366ddd40a6165834e6988e3a1a395 Mon Sep 17 00:00:00 2001 From: ayunami2000 Date: Sat, 30 Apr 2022 09:59:11 -0400 Subject: [PATCH] images --- .../me/ayunami2000/ayunEagVidMap/Main.java | 53 ++++++-- .../ayunEagVidMap/VideoMapPacketCodec.java | 56 +++++++- .../VideoMapPacketCodecBukkit.java | 122 ------------------ src/main/resources/config.yml | 6 +- src/main/resources/messages.yml | 6 +- target/ayunEagVidMap-1.0-SNAPSHOT.jar | Bin 15700 -> 14354 bytes 6 files changed, 101 insertions(+), 142 deletions(-) delete mode 100644 src/main/java/me/ayunami2000/ayunEagVidMap/VideoMapPacketCodecBukkit.java diff --git a/src/main/java/me/ayunami2000/ayunEagVidMap/Main.java b/src/main/java/me/ayunami2000/ayunEagVidMap/Main.java index f75e47e..adc921e 100644 --- a/src/main/java/me/ayunami2000/ayunEagVidMap/Main.java +++ b/src/main/java/me/ayunami2000/ayunEagVidMap/Main.java @@ -1,9 +1,12 @@ package me.ayunami2000.ayunEagVidMap; +import net.minecraft.server.v1_5_R3.Packet; +import net.minecraft.server.v1_5_R3.Packet131ItemData; import org.bukkit.command.BlockCommandSender; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.v1_5_R3.entity.CraftPlayer; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -18,7 +21,7 @@ public class Main extends JavaPlugin implements CommandExecutor, Listener { public static Main plugin; - private VideoMapPacketCodecBukkit videoMapCodec = null; + private VideoMapPacketCodec videoMapCodec = null; private Vector audioLoc = new Vector(0, 100, 0); private String url = ""; private boolean urlChanged = true; @@ -27,6 +30,7 @@ public class Main extends JavaPlugin implements CommandExecutor, Listener { private int mapOffset = 0; private int interval = 10; private int syncTask = -1; + private boolean imageMode = false; @Override public void onLoad(){ @@ -43,7 +47,7 @@ public class Main extends JavaPlugin implements CommandExecutor, Listener { @Override public void onDisable(){ - sendToAllPlayers(videoMapCodec.disableVideoBukkit()); + if (videoMapCodec.mapIds != null) sendToAllPlayers(videoMapCodec.disableVideo()); } private void stopSyncTask() { @@ -67,20 +71,21 @@ public class Main extends JavaPlugin implements CommandExecutor, Listener { setSize(this.getConfig().getInt("size.width"), this.getConfig().getInt("size.height")); url = this.getConfig().getString("url"); interval = this.getConfig().getInt("interval"); + imageMode = this.getConfig().getBoolean("image"); stopSyncTask(); createSyncTask(); } private void syncToPlayer(Player player) { - videoMapCodec.syncPlaybackWithPlayersBukkit().send(player); + freePacketSender(player, videoMapCodec.syncPlaybackWithPlayers()); } private void syncToAllPlayers() { - videoMapCodec.syncPlaybackWithPlayersBukkit().send(this.getServer().getOnlinePlayers()); + sendToAllPlayers(videoMapCodec.syncPlaybackWithPlayers()); } - private void sendToAllPlayers(VideoMapPacketCodecBukkit.VideoMapPacket p) { - p.send(this.getServer().getOnlinePlayers()); + private void sendToAllPlayers(byte[] p) { + for (Player player : this.getServer().getOnlinePlayers()) freePacketSender(player, p); } private void setSize(int width, int height) { @@ -97,14 +102,14 @@ public class Main extends JavaPlugin implements CommandExecutor, Listener { mapIds[y][x] = offset++; } } - videoMapCodec = new VideoMapPacketCodecBukkit(mapIds, audioLoc.getX(), audioLoc.getY(), audioLoc.getZ(), 0.5f); + videoMapCodec = new VideoMapPacketCodec(mapIds, audioLoc.getX(), audioLoc.getY(), audioLoc.getZ(), 0.5f); } @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { if (videoMapCodec != null && videoMapCodec.getURL() != null) { Player player = event.getPlayer(); - videoMapCodec.beginPlaybackBukkit(videoMapCodec.getURL(), videoMapCodec.isLoopEnable(), videoMapCodec.getDuration()).send(player); + freePacketSender(player, videoMapCodec.beginPlayback(videoMapCodec.getURL() == null ? "" : videoMapCodec.getURL(), videoMapCodec.isLoopEnable(), videoMapCodec.getDuration())); syncToPlayer(player); } } @@ -116,6 +121,15 @@ public class Main extends JavaPlugin implements CommandExecutor, Listener { return true; } switch (args[0].toLowerCase()) { + case "m": + case "mode": + sendToAllPlayers(videoMapCodec.disableVideo()); + imageMode = !imageMode; + sendToAllPlayers(videoMapCodec.beginPlayback(videoMapCodec.getURL() == null ? "" : videoMapCodec.getURL(), videoMapCodec.isLoopEnable(), videoMapCodec.getDuration())); + this.getConfig().set("image", imageMode); + this.saveConfig(); + MessageHandler.sendPrefixedMessage(sender, "mode", imageMode ? MessageHandler.getMessage("image") : MessageHandler.getMessage("video")); + break; case "rl": case "reload": this.reloadConfig(); @@ -174,8 +188,8 @@ public class Main extends JavaPlugin implements CommandExecutor, Listener { this.getConfig().set("audio.z", audioLoc.getZ()); this.saveConfig(); float ct = videoMapCodec.getPlaybackTime(); - sendToAllPlayers(videoMapCodec.moveAudioSourceBukkit(audioLoc.getX(), audioLoc.getY(), audioLoc.getZ(), 0.5f)); - sendToAllPlayers(videoMapCodec.setPlaybackTimeBukkit(ct)); + sendToAllPlayers(videoMapCodec.moveAudioSource(audioLoc.getX(), audioLoc.getY(), audioLoc.getZ(), 0.5f)); + sendToAllPlayers(videoMapCodec.setPlaybackTime(ct)); MessageHandler.sendPrefixedMessage(sender, "locSet", audioLoc); break; case "p": @@ -186,14 +200,14 @@ public class Main extends JavaPlugin implements CommandExecutor, Listener { if (urlChanged) { urlChanged = false; MessageHandler.sendPrefixedMessage(sender, "playing"); - sendToAllPlayers(videoMapCodec.beginPlaybackBukkit(url, true, Integer.MAX_VALUE / 1000.0f)); + sendToAllPlayers(videoMapCodec.beginPlayback(url, true, Integer.MAX_VALUE / 1000.0f)); } else { MessageHandler.sendPrefixedMessage(sender, "resuming"); } - sendToAllPlayers(videoMapCodec.setPausedBukkit(false)); + sendToAllPlayers(videoMapCodec.setPaused(false)); } else { MessageHandler.sendPrefixedMessage(sender, "pausing"); - sendToAllPlayers(videoMapCodec.setPausedBukkit(true)); + sendToAllPlayers(videoMapCodec.setPaused(true)); } break; case "s": @@ -213,7 +227,7 @@ public class Main extends JavaPlugin implements CommandExecutor, Listener { MessageHandler.sendPrefixedMessage(sender, "notANumber", args[offendingIndex], MessageHandler.getMessage("integer")); break; } - sendToAllPlayers(videoMapCodec.disableVideoBukkit()); + sendToAllPlayers(videoMapCodec.disableVideo()); setSize(width, height); syncToAllPlayers(); this.getConfig().set("size.width", mapSize[0]); @@ -242,4 +256,15 @@ public class Main extends JavaPlugin implements CommandExecutor, Listener { } return true; } + + private void freePacketSender(Player player, byte[] packet) { + nativeSendPacketToPlayer(player, new Packet131ItemData((short)(104 + (imageMode ? 1 : 0)), (short)0, packet)); + } + + private static void nativeSendPacketToPlayer(Player player, Object obj) { + if(obj == null) { + return; + } + ((CraftPlayer)player).getHandle().playerConnection.sendPacket((Packet)obj); + } } diff --git a/src/main/java/me/ayunami2000/ayunEagVidMap/VideoMapPacketCodec.java b/src/main/java/me/ayunami2000/ayunEagVidMap/VideoMapPacketCodec.java index 11798ba..055378e 100644 --- a/src/main/java/me/ayunami2000/ayunEagVidMap/VideoMapPacketCodec.java +++ b/src/main/java/me/ayunami2000/ayunEagVidMap/VideoMapPacketCodec.java @@ -40,7 +40,7 @@ public class VideoMapPacketCodec { this.requiresFullResetPacket = true; this.isDisabled = true; } - + /** * @param mapIds 2D grid of map IDs that make up the screen (mapIds[y][x]) * @param posX audio playback X coord @@ -48,7 +48,14 @@ public class VideoMapPacketCodec { * @param posZ audio playback Z coord */ public VideoMapPacketCodec(int[][] mapIds, double posX, double posY, double posZ) { - this(mapIds, posX, posY, posZ, 1.0f); + this(mapIds, posX, posY, posZ, 0.5f); + } + + /** + * @param mapIds 2D grid of map IDs that make up the screen (mapIds[y][x]) + */ + public VideoMapPacketCodec(int[][] mapIds) { + this(mapIds, 0, 100, 0, 0.5f); } /** @@ -119,7 +126,7 @@ public class VideoMapPacketCodec { } str.write(frameRate); str.writeInt(duration); - str.writeUTF(url); + str.writeUTF(url == null ? "" : url); } if(requiresFullResetPacket || requiresPositionPacket) { @@ -163,7 +170,7 @@ public class VideoMapPacketCodec { } return t; } - + /** * @param url URL to an MP4 or other HTML5 supported video file * @param loop If the video file should loop @@ -180,6 +187,40 @@ public class VideoMapPacketCodec { this.isDisabled = false; return syncPlaybackWithPlayers(); } + + /** + * @param url URL to an MP4 or other HTML5 supported video file + * @return packet to send to players + */ + public byte[] beginPlayback(String url) { + this.url = url; + this.loop = false; + this.duration = 0; + this.pauseTimestamp = 0l; + this.timestamp = 0l; + this.requiresFullResetPacket = true; + this.isDisabled = false; + return syncPlaybackWithPlayers(); + } + + /** + * Tells the browser to pre-load a URL to a video to be played in the future + * @param url the URL of the video + * @param ttl the amount of time the video should stay loaded + * @return packet to send to players + */ + public static byte[] bufferVideo(String url, int ttl) { + try { + ByteArrayOutputStream bao = new ByteArrayOutputStream(); + DataOutputStream str = new DataOutputStream(bao); + str.write(8); + str.writeInt(ttl); + str.writeUTF(url); + return bao.toByteArray(); + }catch(IOException e) { + throw new RuntimeException("serialization error", e); + } + } /** * @return the duration of the current clip @@ -254,4 +295,11 @@ public class VideoMapPacketCodec { return pauseTimestamp > 0l; } + /** + * @return current server-side volume + */ + public float getVolume() { + return volume; + } + } diff --git a/src/main/java/me/ayunami2000/ayunEagVidMap/VideoMapPacketCodecBukkit.java b/src/main/java/me/ayunami2000/ayunEagVidMap/VideoMapPacketCodecBukkit.java deleted file mode 100644 index 14bd6c9..0000000 --- a/src/main/java/me/ayunami2000/ayunEagVidMap/VideoMapPacketCodecBukkit.java +++ /dev/null @@ -1,122 +0,0 @@ -package me.ayunami2000.ayunEagVidMap; - -import java.util.List; - -import org.bukkit.craftbukkit.v1_5_R3.entity.CraftPlayer; -import org.bukkit.entity.Player; - -import net.minecraft.server.v1_5_R3.Packet; -import net.minecraft.server.v1_5_R3.Packet131ItemData; - -public class VideoMapPacketCodecBukkit extends VideoMapPacketCodec { - - /** - * @param mapIds 2D grid of map IDs that make up the screen (mapIds[y][x]) - * @param posX audio playback X coord - * @param posY audio playback Y coord - * @param posZ audio playback Z coord - * @param volume the volume of the clip - */ - public VideoMapPacketCodecBukkit(int[][] mapIds, double posX, double posY, double posZ, float volume) { - super(mapIds, posX, posY, posZ, volume); - } - - /** - * @param mapIds 2D grid of map IDs that make up the screen (mapIds[y][x]) - * @param posX audio playback X coord - * @param posY audio playback Y coord - * @param posZ audio playback Z coord - */ - public VideoMapPacketCodecBukkit(int[][] mapIds, double posX, double posY, double posZ) { - super(mapIds, posX, posY, posZ, 1.0f); - } - - public class VideoMapPacket { - protected final Object packet; - protected VideoMapPacket(byte[] packet) { - this.packet = new Packet131ItemData((short)104, (short)0, packet); - } - public Object getNativePacket() { - return packet; - } - public void send(Player p) { - nativeSendPacketToPlayer(p, packet); - } - public void send(Player... p) { - for(Player pp : p) { - nativeSendPacketToPlayer(pp, packet); - } - } - public void send(List p) { - for(Player pp : p) { - nativeSendPacketToPlayer(pp, packet); - } - } - } - - /** - * @param posX audio playback X coord - * @param posY audio playback Y coord - * @param posZ audio playback Z coord - * @param volume the volume of the clip - * @return packet to send to players - */ - public VideoMapPacket moveAudioSourceBukkit(double posX, double posY, double posZ, float volume) { - return new VideoMapPacket(moveAudioSource(posX, posY, posZ, volume)); - } - - /** - * unloads video and resets all map object to vanilla renderer - * @return packet to send to players - */ - public VideoMapPacket disableVideoBukkit() { - return new VideoMapPacket(disableVideo()); - } - - /** - * syncs the server side video timestamp with players - * @return packet to send to players - */ - public VideoMapPacket syncPlaybackWithPlayersBukkit() { - return new VideoMapPacket(syncPlaybackWithPlayers()); - } - - /** - * @param url URL to an MP4 or other HTML5 supported video file - * @param loop If the video file should loop - * @param duration duration of the video in seconds - * @return packet to send to players - */ - public VideoMapPacket beginPlaybackBukkit(String url, boolean loop, float duration) { - return new VideoMapPacket(beginPlayback(url, loop, duration)); - } - - /** - * @param time time in seconds to seek the video to - */ - public VideoMapPacket setPlaybackTimeBukkit(float time) { - return new VideoMapPacket(setPlaybackTime(time)); - } - - /** - * @param loop video should loop - */ - public VideoMapPacket setLoopEnableBukkit(boolean loop) { - return new VideoMapPacket(setLoopEnable(loop)); - } - - /** - * @param pause set if video should pause - * @return packet to send to players - */ - public VideoMapPacket setPausedBukkit(boolean pause) { - return new VideoMapPacket(setPaused(pause)); - } - - public static void nativeSendPacketToPlayer(Player player, Object obj) { - if(obj == null) { - return; - } - ((CraftPlayer)player).getHandle().playerConnection.sendPacket((Packet)obj); - } -} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 6e325b8..4a769ac 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -14,4 +14,8 @@ interval: 10 audio: x: 0 y: 100 - z: 0 \ No newline at end of file + z: 0 +# image mode +image: false +# autoplay +autoplay: false \ No newline at end of file diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index b6e217d..a55d63c 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -8,6 +8,7 @@ usage: - "&7&o/ayunvid [ ] &3- Sets or gets the size of video, in maps. E.g., a width of 2 and a height of 3 would result in a video using 6 maps." - "&7&o/ayunvid &3- Reloads the configuration file." - "&7&o/ayunvid &3- Set the sync interval, in seconds, or 0 to disable." + - "&7&o/ayunvid &3- Switch between image mode and video mode." currentUrl: "&3Current URL: {0}" setUrl: "&3Successfully set URL." locFromConsole: "&cError: You must specify the coordinates when running this command from the console!" @@ -24,4 +25,7 @@ setSize: "&3Set size to {0} maps wide by {1} maps tall ({2} maps total)" invalidUsage: "&cError: That is not a valid subcommand! Try &n/ayunvid&c help for usage." reloaded: "&3Successfully reloaded configuration!" currentInterval: "&3Current sync interval: {0} seconds" -setInterval: "&3Successfully set or disabled sync interval." \ No newline at end of file +setInterval: "&3Successfully set or disabled sync interval." +mode: "&3Now using {0}." +image: "an image" +video: "video" \ No newline at end of file diff --git a/target/ayunEagVidMap-1.0-SNAPSHOT.jar b/target/ayunEagVidMap-1.0-SNAPSHOT.jar index acb122a6360a003c72d714945eafebbd662a80d0..2a0421fb696ab6832433a703e55ed422d9f050d0 100644 GIT binary patch delta 12996 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±|qq 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