Skip to content

Commit

Permalink
Version 1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
HaHaWTH committed Nov 20, 2024
1 parent 0f2e1c4 commit ae7c9fc
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 37 deletions.
16 changes: 15 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>io.wdsj</groupId>
<artifactId>imagepreviewer</artifactId>
<version>1.1</version>
<version>1.2</version>
<packaging>jar</packaging>

<name>ImagePreviewer</name>
Expand Down Expand Up @@ -101,6 +101,14 @@
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>opencollab-main</id>
<url>https://repo.opencollab.dev/main/</url>
</repository>
<repository>
<id>opencollab-snapshots</id>
<url>https://repo.opencollab.dev/maven-snapshots/</url>
</repository>
<repository>
<id>jitpack</id>
<url>https://jitpack.io</url>
Expand Down Expand Up @@ -174,6 +182,12 @@
<version>2.6.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.geysermc.floodgate</groupId>
<artifactId>api</artifactId>
<version>2.2.2-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.Anon8281</groupId>
<artifactId>UniversalScheduler</artifactId>
Expand Down
4 changes: 1 addition & 3 deletions src/main/java/io/wdsj/imagepreviewer/ImagePreviewer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

import com.github.Anon8281.universalScheduler.UniversalScheduler;
import com.github.Anon8281.universalScheduler.scheduling.schedulers.TaskScheduler;
import com.github.Anon8281.universalScheduler.scheduling.tasks.MyScheduledTask;
import io.wdsj.imagepreviewer.command.ConstructCommandExecutor;
import io.wdsj.imagepreviewer.config.Config;
import io.wdsj.imagepreviewer.image.ImageLoader;
import io.wdsj.imagepreviewer.listener.ChatListener;
import io.wdsj.imagepreviewer.packet.MapManager;
import io.wdsj.imagepreviewer.permission.CachingPermTool;
import io.wdsj.imagepreviewer.task.MapDisplayDirectionTask;
import io.wdsj.imagepreviewer.update.Updater;
import io.wdsj.imagepreviewer.util.Util;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
Expand All @@ -26,7 +24,7 @@

public class ImagePreviewer extends JavaPlugin {
private static ImagePreviewer instance;
public static final String PLUGIN_VERSION = "1.1";
public static final String PLUGIN_VERSION = "1.2";
public static Logger LOGGER;
private static Config config;
private MapManager mapManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@

import io.wdsj.imagepreviewer.ImagePreviewer;
import io.wdsj.imagepreviewer.config.Config;
import io.wdsj.imagepreviewer.hook.floodgate.FloodgateHook;
import io.wdsj.imagepreviewer.image.ImageLoader;
import io.wdsj.imagepreviewer.listener.ChatListener;
import io.wdsj.imagepreviewer.packet.PacketMapDisplay;
import io.wdsj.imagepreviewer.permission.CachingPermTool;
import io.wdsj.imagepreviewer.permission.PermissionsEnum;
import io.wdsj.imagepreviewer.util.MessageUtil;
import io.wdsj.imagepreviewer.util.Util;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
Expand Down Expand Up @@ -37,6 +42,34 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
MessageUtil.sendMessage(sender, config.message_no_permission);
return true;
}
if (args[0].equalsIgnoreCase("history")) {
if (!(sender instanceof Player player)) {
MessageUtil.sendMessage(sender, config.message_command_player_only);
return true;
}
if (!CachingPermTool.hasPermission(PermissionsEnum.HISTORY, player)) {
MessageUtil.sendMessage(sender, config.message_no_permission);
return true;
}
if (ChatListener.getUrlHistory().isEmpty()) {
MessageUtil.sendMessage(sender, config.message_no_history_to_show);
return true;
}
if (config.hook_floodgate && FloodgateHook.isFloodgatePresent() && FloodgateHook.isFloodgatePlayer(player)) {
var fgPlayer = FloodgateHook.getFloodgatePlayer(player);
new FloodgateHook.PreviewHistoryForm().sendForm(fgPlayer);
} else {
MessageUtil.sendMessage(sender, config.message_history_command);
int index = 1;
for (var entry : ChatListener.getUrlHistory()) {
var component = Component.text(index++ + ". " + entry.sender() + ": " + entry.message())
.color(NamedTextColor.GRAY)
.clickEvent(ClickEvent.runCommand("/imagepreviewer preview " + entry.message()));
ImagePreviewer.getInstance().getAudiences().player(player).sendMessage(component);
}
}
return true;
}
if (args[0].equalsIgnoreCase("cancel")) {
if (!(sender instanceof Player player)) {
MessageUtil.sendMessage(sender, config.message_command_player_only);
Expand Down
31 changes: 23 additions & 8 deletions src/main/java/io/wdsj/imagepreviewer/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,18 @@ public class Config {
public final int cache_maximum_size;
public final long cache_expire_time;
public final boolean preload_images_in_chat;
public final boolean listen_for_url_match;
public final boolean broadcast_on_match;
public final Pattern url_match_regex;
public final boolean use_invisible_item_frame, use_glowing_item_frame;
public final String message_reload_success, message_preview_loading,
message_no_permission, message_invalid_url, message_command_player_only,
message_unknown_command, message_already_on_previewing, message_url_matched, message_hover_event
, message_preview_still_loading, message_help_info, message_args_error, message_cancel_success,
message_nothing_to_cancel;
message_nothing_to_cancel, message_history_command, message_no_history_to_show;

public final String form_title, form_history_content;

public final boolean hook_floodgate;

public Config(ImagePreviewer plugin, File dataFolder) throws Exception {
this.plugin = plugin;
Expand Down Expand Up @@ -68,18 +72,25 @@ public Config(ImagePreviewer plugin, File dataFolder) throws Exception {
"The message that will be sent to the player when the URL is matched.");
this.message_hover_event = getString("message.hover-event", "Click to preview image",
"The hover event that will be sent to the player when they hover over the image.");
this.message_help_info = getString("message.help-info", """
this.message_history_command = getString("message.command.history.header", "&eImagePreviewer History &b(Click link to preview)",
"The message that will be sent to the player when they enter the history command.");
this.message_no_history_to_show = getString("message.command.history.no-history", "&cNo history to show.",
"The message that will be sent to the player when they enter the history command and there is no history to show.");
this.message_help_info = getString("message.command.help.help-info", """
&b&l&nImage Previewer
&a/imagepreviewer reload &7- Reload the plugin
&a/imagepreviewer help &7- Show this message
&a/imagepreviewer preview <url> [time-ticks] &7- Preview an image from given url
&a/imagepreviewer cancel &7- Cancel running preview"""
&a/imagepreviewer cancel &7- Cancel running preview
&a/imagepreviewer history &7- Show previous url history"""
);
this.message_cancel_success = getString("message.cancel-success", "&aCancelled image preview.",
this.message_cancel_success = getString("message.command.cancel.cancel-success", "&aCancelled image preview.",
"The message that will be sent to the player when they cancel the image preview.");
this.message_nothing_to_cancel = getString("message.nothing-to-cancel", "&cYou are not on previewing.",
this.message_nothing_to_cancel = getString("message.command.cancel.nothing-to-cancel", "&cYou are not on previewing.",
"The message that will be sent to the player when they are not on previewing.");

this.form_title = getString("message.form.title", "&e&lImage Previewer", "The title of the form.");
this.form_history_content = getString("message.form.history-form.content", "Previous image urls in chat", "The content of the history form.");

this.preview_mode = getInt("plugin.preview-mode", 2,
"""
Expand Down Expand Up @@ -110,12 +121,14 @@ public Config(ImagePreviewer plugin, File dataFolder) throws Exception {
"If set to true, will use adaptive frame delay.");
this.url_match_regex = Pattern.compile(getString("plugin.url-match-regex", "https?://[^\\s]+?\\.(?:png|bmp|jpg|jpeg|gif|webp)\\b",
"The regex that will be used to match the URL."));
this.listen_for_url_match = getBoolean("plugin.listen-for-url-match", true,
"If set to true, will listen for url match and send message to player.");
this.broadcast_on_match = getBoolean("plugin.broadcast-on-match", false,
"If set to true, will broadcast the matched URL component to all players.");
this.use_invisible_item_frame = getBoolean("plugin.use-invisible-item-frame", false,
"If set to true, will use invisible item frame to display image.");
this.use_glowing_item_frame = getBoolean("plugin.use-glowing-item-frame", false,
"If set to true, will use glowing item frame to display image.");

this.hook_floodgate = getBoolean("hook.floodgate", true);
}

public void saveConfig() {
Expand All @@ -129,6 +142,8 @@ public void saveConfig() {
private void structureConfig() {
createTitledSection("Plugin general setting", "plugin");
createTitledSection("Message", "message");
createTitledSection("Floodgate form message", "message.form");
createTitledSection("Plugin hook", "hook");
}

public void createTitledSection(String title, String path) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.wdsj.imagepreviewer.hook.floodgate;

import org.geysermc.floodgate.api.player.FloodgatePlayer;

public abstract class AbstractForm {
public abstract void sendForm(FloodgatePlayer player);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package io.wdsj.imagepreviewer.hook.floodgate;

import io.wdsj.imagepreviewer.ImagePreviewer;
import io.wdsj.imagepreviewer.image.ImageLoader;
import io.wdsj.imagepreviewer.listener.ChatListener;
import io.wdsj.imagepreviewer.packet.PacketMapDisplay;
import io.wdsj.imagepreviewer.permission.CachingPermTool;
import io.wdsj.imagepreviewer.permission.PermissionsEnum;
import io.wdsj.imagepreviewer.util.MessageUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.geysermc.cumulus.form.SimpleForm;
import org.geysermc.cumulus.util.FormImage;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.api.player.FloodgatePlayer;

import java.util.List;

public class FloodgateHook {

public static boolean isFloodgatePresent() {
return Bukkit.getPluginManager().getPlugin("floodgate") != null;
}

public static boolean isFloodgatePlayer(Player player) {
return FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId());
}

public static FloodgatePlayer getFloodgatePlayer(Player player) {
return FloodgateApi.getInstance().getPlayer(player.getUniqueId());
}

public static class PreviewHistoryForm extends AbstractForm {
private final SimpleForm.Builder formBuilder;
private final List<ChatListener.MessageEntry> history;
public PreviewHistoryForm() {
this.formBuilder = SimpleForm.builder();
formBuilder.title(MessageUtil.translateColors(ImagePreviewer.config().form_title));
formBuilder.content(MessageUtil.translateColors(ImagePreviewer.config().form_history_content));
this.history = ChatListener.getUrlHistory();
history.forEach(entry -> {
formBuilder.button(entry.sender() + ": " + entry.message(), FormImage.Type.URL, entry.message());
});
}

@Override
public void sendForm(FloodgatePlayer player) {
formBuilder.validResultHandler(result -> {
int index = result.clickedButtonId();
if (index >= ChatListener.getUrlHistory().size()) return;
var entry = history.get(index);
var plugin = ImagePreviewer.getInstance();
var config = ImagePreviewer.config();
var uuid = player.getCorrectUniqueId();
var javaPlayer = Bukkit.getPlayer(uuid);
if (javaPlayer == null) return;
if (!CachingPermTool.hasPermission(PermissionsEnum.PREVIEW, javaPlayer)) {
MessageUtil.sendMessage(javaPlayer, config.message_no_permission);
return;
}
if (plugin.getMapManager().queuedPlayers.contains(uuid)) {
MessageUtil.sendMessage(javaPlayer, config.message_preview_still_loading);
return;
}
if (plugin.getMapManager().hasRunningPreview(javaPlayer)) {
MessageUtil.sendMessage(javaPlayer, config.message_already_on_previewing);
return;
}
plugin.getMapManager().queuedPlayers.add(uuid);
MessageUtil.sendMessage(javaPlayer, config.message_preview_loading);
ImageLoader.imageAsData(entry.message())
.thenAccept(imageData -> {
new PacketMapDisplay(plugin, javaPlayer, imageData).spawn();
})
.exceptionally(ex -> {
MessageUtil.sendMessage(javaPlayer, config.message_invalid_url);
plugin.getMapManager().queuedPlayers.remove(uuid);
return null;
});
});
player.sendForm(formBuilder.build());
}
}
}
4 changes: 2 additions & 2 deletions src/main/java/io/wdsj/imagepreviewer/image/ImageLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public static CompletableFuture<ImageData> imageAsData(String urlString) {
boolean isAnimated = getFormatName(url).equalsIgnoreCase("gif") && !Config.isReloading && ImagePreviewer.config().process_multi_frame_gif;
if (isAnimated) {
var pairs = readAllFramesGif(url);
BufferedImage[] originalImages = pairs.getLeft();
BufferedImage[] originalImages = pairs.left();
if (originalImages.length == 0) {
throw new IllegalArgumentException("The provided URL is not a valid image: " + urlString);
}
Expand All @@ -72,7 +72,7 @@ public static CompletableFuture<ImageData> imageAsData(String urlString) {
for (BufferedImage resizedImage : resizedImagesList) {
imageDataList.add(MapPalette.imageToBytes(resizedImage));
}
ImageData data = new ImageData(imageDataList, true, pairs.getRight());
ImageData data = new ImageData(imageDataList, true, pairs.right());
if (ImagePreviewer.config().enable_image_cache) {
imageCache.put(urlString, data);
}
Expand Down
24 changes: 18 additions & 6 deletions src/main/java/io/wdsj/imagepreviewer/listener/ChatListener.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.wdsj.imagepreviewer.listener;

import com.google.common.collect.EvictingQueue;
import io.wdsj.imagepreviewer.ImagePreviewer;
import io.wdsj.imagepreviewer.config.Config;
import io.wdsj.imagepreviewer.image.ImageLoader;
Expand All @@ -12,12 +13,14 @@
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;

import java.util.List;
import java.util.regex.Matcher;

public class ChatListener implements Listener {
private static final EvictingQueue<MessageEntry> urlHistory = EvictingQueue.create(10);
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onChat(AsyncPlayerChatEvent event) {
if (Config.isReloading || !ImagePreviewer.config().listen_for_url_match) return;
if (Config.isReloading) return;
String message = event.getMessage();
Matcher matcher = ImagePreviewer.config().url_match_regex.matcher(message);
String url;
Expand All @@ -31,10 +34,19 @@ public void onChat(AsyncPlayerChatEvent event) {
.exceptionally(throwable -> null);
}
String playerName = event.getPlayer().getName();
Component component = Component.text(ImagePreviewer.config().message_url_matched.replace("%player%", playerName))
.color(NamedTextColor.GREEN)
.hoverEvent(HoverEvent.showText(Component.text(ImagePreviewer.config().message_hover_event)))
.clickEvent(ClickEvent.runCommand("/imagepreviewer preview " + url));
ImagePreviewer.getInstance().getAudiences().players().sendMessage(component);
urlHistory.offer(new MessageEntry(url, playerName));
if (ImagePreviewer.config().broadcast_on_match) {
Component component = Component.text(ImagePreviewer.config().message_url_matched.replace("%player%", playerName))
.color(NamedTextColor.GREEN)
.hoverEvent(HoverEvent.showText(Component.text(ImagePreviewer.config().message_hover_event)))
.clickEvent(ClickEvent.runCommand("/imagepreviewer preview " + url));
ImagePreviewer.getInstance().getAudiences().players().sendMessage(component);
}
}

public static List<MessageEntry> getUrlHistory() {
return List.copyOf(urlHistory);
}
public record MessageEntry(String message, String sender) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public enum PermissionsEnum {
PREVIEW_TIME("imagepreviewer.use.time"),
CANCEL_PREVIEW("imagepreviewer.command.cancel"),
RELOAD("imagepreviewer.command.reload"),
HISTORY("imagepreviewer.command.history"),
HELP("imagepreviewer.command.help");

private final String permission;
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/io/wdsj/imagepreviewer/util/MessageUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ public static void sendMessage(CommandSender sender, String message) {
if (message.isBlank()) return;
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', message));
}

public static String translateColors(String message) {
return ChatColor.translateAlternateColorCodes('&', message);
}
}
18 changes: 1 addition & 17 deletions src/main/java/io/wdsj/imagepreviewer/util/Pair.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
package io.wdsj.imagepreviewer.util;

public class Pair <L, R> {
private final L left;
private final R right;

public Pair(L left, R right) {
this.left = left;
this.right = right;
}

public record Pair<L, R>(L left, R right) {
public static <L, R> Pair<L, R> of(L left, R right) {
return new Pair<>(left, right);
}

public L getLeft() {
return left;
}

public R getRight() {
return right;
}
}
Loading

0 comments on commit ae7c9fc

Please sign in to comment.