diff --git a/bukkit/build.gradle.kts b/bukkit/build.gradle.kts index c0fe8d6..a7caafa 100644 --- a/bukkit/build.gradle.kts +++ b/bukkit/build.gradle.kts @@ -1,7 +1,18 @@ taboolib { subproject = true } +repositories { + maven("https://repo.codemc.io/repository/maven-public/") + maven("https://repo.glaremasters.me/repository/bloodshot") +} + dependencies { compileOnly(project(":common")) + compileOnly("fr.xephi:authme:5.6.0-SNAPSHOT") + compileOnly("org.maxgamer:QuickShop:5.1.1.2") + compileOnly("com.ghostchu:quickshop-bukkit:4.2.2.11") + compileOnly("com.griefdefender:api:2.1.0-SNAPSHOT") +// compileOnly("com.bekvon.bukkit.residence:Residence:5.1.0.1") + compileOnly(fileTree("lib")) } gradle.buildFinished { buildDir.deleteRecursively() diff --git a/bukkit/lib/Residence5.1.0.1.jar b/bukkit/lib/Residence5.1.0.1.jar new file mode 100644 index 0000000..d147cc8 Binary files /dev/null and b/bukkit/lib/Residence5.1.0.1.jar differ diff --git a/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/AuthMeHook.java b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/AuthMeHook.java new file mode 100644 index 0000000..568b8f5 --- /dev/null +++ b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/AuthMeHook.java @@ -0,0 +1,29 @@ +package me.regadpole.plumbot.bukkit.hook; + +import fr.xephi.authme.api.v3.AuthMeApi; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import taboolib.common.platform.function.IOKt; + +public class AuthMeHook { + + public static Boolean hasAuthMe; + public static AuthMeApi authMeApi; + + public static void hookAuthme() { + + Plugin authMe = Bukkit.getPluginManager().getPlugin("AuthMe"); + try { + if (authMe != null) { + hasAuthMe = true; + authMeApi = AuthMeApi.getInstance(); + IOKt.info("AuthMe 关联成功"); + }else{ + hasAuthMe = false; + IOKt.info("AuthMe 关联失败"); + } + } catch (Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/GriefDefenderHook.java b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/GriefDefenderHook.java new file mode 100644 index 0000000..65d86f0 --- /dev/null +++ b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/GriefDefenderHook.java @@ -0,0 +1,27 @@ +package me.regadpole.plumbot.bukkit.hook; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import taboolib.common.platform.function.IOKt; + +public class GriefDefenderHook { + + + public static Boolean hasGriefDefender; + + public static void hookGriefDefender() { + + Plugin authMe = Bukkit.getPluginManager().getPlugin("GriefDefender"); + try { + if (authMe != null) { + hasGriefDefender = true; + IOKt.info("GriefDefender 关联成功"); + }else{ + hasGriefDefender = false; + IOKt.info("GriefDefender 关联失败"); + } + } catch (Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/QuickShopHook.java b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/QuickShopHook.java new file mode 100644 index 0000000..ac4e766 --- /dev/null +++ b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/QuickShopHook.java @@ -0,0 +1,40 @@ +package me.regadpole.plumbot.bukkit.hook; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import taboolib.common.platform.function.IOKt; + +public class QuickShopHook { + + public static Boolean hasQs; + + public static Boolean hasQsHikari; + + public static void hookQuickShop() { + + Plugin quickShop = Bukkit.getPluginManager().getPlugin("QuickShop"); + try { + if (quickShop != null) { + hasQs = true; + hasQsHikari = false; + IOKt.info("QuickShop-Reremake 关联成功"); + }else{ + hasQs = false; + Plugin quickShopHikari = Bukkit.getPluginManager().getPlugin("QuickShop-Hikari"); + try { + if (quickShopHikari != null) { + hasQsHikari = true; + IOKt.info("QuickShop-Hikari 关联成功"); + }else{ + hasQsHikari = false; + IOKt.info("QuickShop 关联失败"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } catch (Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/ResidenceHook.java b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/ResidenceHook.java new file mode 100644 index 0000000..4489751 --- /dev/null +++ b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/hook/ResidenceHook.java @@ -0,0 +1,32 @@ +package me.regadpole.plumbot.bukkit.hook; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.chat.ChatManager; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import taboolib.common.platform.function.IOKt; + +public class ResidenceHook { + + public static Boolean hasRes; + + public static ChatManager resChatApi; + + public static void hookRes() { + + Plugin residence = Bukkit.getPluginManager().getPlugin("Residence"); + try { + if (residence != null) { + hasRes = true; + resChatApi = Residence.getInstance().getChatManager(); + IOKt.info("Residence 关联成功"); + }else{ + hasRes = false; + IOKt.info("Residence 关联失败"); + } + } catch (Throwable e) { + e.printStackTrace(); + } + } +} + diff --git a/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/ConsoleSender.java b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/ConsoleSender.java new file mode 100644 index 0000000..90b10fa --- /dev/null +++ b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/ConsoleSender.java @@ -0,0 +1,136 @@ +package me.regadpole.plumbot.bukkit.listener; + +import me.regadpole.plumbot.bukkit.util.ServerManager; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.conversations.Conversation; +import org.bukkit.conversations.ConversationAbandonedEvent; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Set; +import java.util.UUID; + +public class ConsoleSender implements ConsoleCommandSender { + + private final Server server = Bukkit.getServer(); + + public Server getServer() { + return this.server; + } + + public String getName() { + return "CONSOLE"; + } + + public void sendMessage(String message) { + ServerManager.msgList.add(message); + } + + public void sendMessage(String[] messages) { + for (String msg : messages) + sendMessage(msg); + } + + public void sendMessage(@Nullable UUID sender, @NotNull String message) { + ServerManager.msgList.add(message); + } + + public void sendMessage(@Nullable UUID sender, @NotNull String[] messages) { + for (String msg : messages) + sendMessage(null, msg); + } + + public boolean isPermissionSet(String s) { + return false; + } + + public boolean isPermissionSet(Permission permission) { + return false; + } + + public boolean hasPermission(String s) { + return true; + } + + public boolean hasPermission(Permission permission) { + return true; + } + + public boolean isOp() { + return true; + } + + public void setOp(boolean b) { + throw new UnsupportedOperationException(); + } + + public Spigot spigot() { + throw new UnsupportedOperationException(); + } + + public boolean isConversing() { + throw new UnsupportedOperationException(); + } + + public void acceptConversationInput(String s) { + ServerManager.msgList.add(s); + throw new UnsupportedOperationException(); + } + + public boolean beginConversation(Conversation conversation) { + throw new UnsupportedOperationException(); + } + + public void abandonConversation(Conversation conversation) { + throw new UnsupportedOperationException(); + } + + public void abandonConversation(Conversation conversation, ConversationAbandonedEvent conversationAbandonedEvent) { + throw new UnsupportedOperationException(); + } + + public void sendRawMessage(String s) { + ServerManager.msgList.add(s); + } + + public void sendRawMessage(@Nullable UUID sender, @NotNull String message) { + ServerManager.msgList.add(message); + } + + public PermissionAttachment addAttachment(Plugin plugin, String s, boolean b) { + ServerManager.msgList.add(s); + throw new UnsupportedOperationException(); + } + + public PermissionAttachment addAttachment(Plugin plugin) { + throw new UnsupportedOperationException(); + } + + public PermissionAttachment addAttachment(Plugin plugin, String s, boolean b, int i) { + ServerManager.msgList.add(s); + throw new UnsupportedOperationException(); + } + + public PermissionAttachment addAttachment(Plugin plugin, int i) { + throw new UnsupportedOperationException(); + } + + public void removeAttachment(PermissionAttachment permissionAttachment) { + throw new UnsupportedOperationException(); + } + + public void recalculatePermissions() { + throw new UnsupportedOperationException(); + } + + public Set getEffectivePermissions() { + throw new UnsupportedOperationException(); + } + +} diff --git a/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/GDClaimEvent.java b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/GDClaimEvent.java new file mode 100644 index 0000000..27286f0 --- /dev/null +++ b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/GDClaimEvent.java @@ -0,0 +1,20 @@ +package me.regadpole.plumbot.bukkit.listener; + +import com.griefdefender.api.event.ClaimEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +public class GDClaimEvent implements Listener { + + + private static String gdMessage; + + @EventHandler(priority = EventPriority.HIGH) + public void onGDClaim (ClaimEvent e){ + setGDMessage(e.getMessage().toString()); + } + + public static String getGDMessage() {return gdMessage;} + private static void setGDMessage(String s) {gdMessage = s;} +} diff --git a/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/QsChatEvent.java b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/QsChatEvent.java new file mode 100644 index 0000000..8ce2ef8 --- /dev/null +++ b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/QsChatEvent.java @@ -0,0 +1,23 @@ +package me.regadpole.plumbot.bukkit.listener; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +public class QsChatEvent implements Listener { + + private static String qsMessage; + private static Player qsSender; + + @EventHandler(priority = EventPriority.HIGH) + public void onQSChat (org.maxgamer.quickshop.api.event.QSHandleChatEvent e){ + setQsMessage(e.getMessage()); + setQsSender(e.getSender()); + } + + public static String getQsMessage() {return qsMessage;} + public static Player getQsSender() {return qsSender;} + private static void setQsMessage(String s) {qsMessage = s;} + private static void setQsSender(Player p) {qsSender = p;} +} diff --git a/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/QsHikariChatEvent.java b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/QsHikariChatEvent.java new file mode 100644 index 0000000..ccd0d31 --- /dev/null +++ b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/QsHikariChatEvent.java @@ -0,0 +1,23 @@ +package me.regadpole.plumbot.bukkit.listener; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +public class QsHikariChatEvent implements Listener { + + private static String qsMessage; + private static Player qsSender; + + @EventHandler(priority = EventPriority.HIGH) + public void onQSChat (com.ghostchu.quickshop.api.event.QSHandleChatEvent e){ + setQsMessage(e.getMessage()); + setQsSender(e.getSender()); + } + + + public static String getQsMessage() {return qsMessage;} + public static Player getQsSender() {return qsSender;} + private static void setQsMessage(String s) {qsMessage = s;} + private static void setQsSender(Player p) {qsSender = p;} +} diff --git a/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/ServerTps.java b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/ServerTps.java new file mode 100644 index 0000000..750a8d1 --- /dev/null +++ b/bukkit/src/main/java/me/regadpole/plumbot/bukkit/listener/ServerTps.java @@ -0,0 +1,67 @@ +package me.regadpole.plumbot.bukkit.listener; + +import org.bukkit.Bukkit; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.text.NumberFormat; +import java.util.Locale; +import java.util.function.Supplier; + +public class ServerTps { + + /** Number formatter for 2 decimal places */ + private final NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.CHINA); + + /** NMS server to get TPS from on spigot */ + private Object server; + + /** TPS field*/ + private Field recentTps; + + /** Detection for presence of Paper's TPS getter */ + private Method paperTps; + + /** Detection for presence of Paper's MSPT getter */ + private Method paperMspt; + + private Supplier TPS; + + private String MSPT = "none"; + + public ServerTps() { + try { + server = Bukkit.getServer().getClass().getMethod("getServer").invoke(Bukkit.getServer()); + recentTps = server.getClass().getField("recentTps"); + } catch (ReflectiveOperationException e) { + //not spigot + } + try { paperTps = Bukkit.class.getMethod("getTPS"); } catch (NoSuchMethodException ignored) {} + try { paperMspt = Bukkit.class.getMethod("getAverageTickTime"); } catch (NoSuchMethodException ignored) {} + TPS = () -> { + if (paperTps != null) { + return formatTPS(Bukkit.getTPS()[0]); + } else if (recentTps != null) { + try { + return formatTPS(((double[]) recentTps.get(server))[0]); + } catch (IllegalAccessException e) { + return String.valueOf(-1); + } + } else { + return String.valueOf(-1); + } + }; + if (paperMspt != null) { + MSPT = numberFormat.format(Bukkit.getAverageTickTime()); + } + } + + private String formatTPS(double tps) { + return numberFormat.format(Math.min(20, tps)); + } + + public Object getTps() {return TPS.get();} + + public String getMSPT() {return MSPT;} + +} diff --git a/bukkit/src/main/java/me/regadpole/plumbot/event/BukkitListener.kt b/bukkit/src/main/java/me/regadpole/plumbot/event/BukkitListener.kt deleted file mode 100644 index 2c2b4fb..0000000 --- a/bukkit/src/main/java/me/regadpole/plumbot/event/BukkitListener.kt +++ /dev/null @@ -1,32 +0,0 @@ -package me.regadpole.plumbot.event - -import me.regadpole.plumbot.event.impl.BukkitJoinEvent -import me.regadpole.plumbot.listener.game.GameListener -import me.regadpole.plumbot.util.impl.BukkitPlayer -import org.bukkit.event.entity.PlayerDeathEvent -import org.bukkit.event.player.AsyncPlayerChatEvent -import org.bukkit.event.player.PlayerJoinEvent -import org.bukkit.event.player.PlayerQuitEvent -import taboolib.common.platform.event.SubscribeEvent - -class BukkitListener { - @SubscribeEvent - fun onJoin(event: PlayerJoinEvent) { - GameListener.onJoin(BukkitJoinEvent(event.player)) - } - - @SubscribeEvent - fun onQuit(event: PlayerQuitEvent) { - GameListener.onQuit(GQuitEvent(BukkitPlayer(event.player))) - } - - @SubscribeEvent - fun onChat(event: AsyncPlayerChatEvent) { - GameListener.onChat(GPlayerChatEvent(event.message, BukkitPlayer(event.player))) - } - - @SubscribeEvent - fun onDeath(event: PlayerDeathEvent) { - GameListener.onDie(GDeathEvent(BukkitPlayer(event.entity))) - } -} \ No newline at end of file diff --git a/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/BukkitImpl.kt b/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/BukkitImpl.kt new file mode 100644 index 0000000..1997479 --- /dev/null +++ b/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/BukkitImpl.kt @@ -0,0 +1,37 @@ +package me.regadpole.plumbot.bukkit + +import me.regadpole.plumbot.PlatformImpl +import me.regadpole.plumbot.bukkit.hook.AuthMeHook +import me.regadpole.plumbot.bukkit.hook.GriefDefenderHook +import me.regadpole.plumbot.bukkit.hook.QuickShopHook +import me.regadpole.plumbot.bukkit.hook.ResidenceHook +import me.regadpole.plumbot.bukkit.listener.GDClaimEvent +import me.regadpole.plumbot.bukkit.listener.QsChatEvent +import me.regadpole.plumbot.bukkit.listener.QsHikariChatEvent +import org.bukkit.Bukkit +import taboolib.common.platform.function.info + +class BukkitImpl: PlatformImpl() { + override fun load() { + AuthMeHook.hookAuthme() + ResidenceHook.hookRes() + QuickShopHook.hookQuickShop() + GriefDefenderHook.hookGriefDefender() + info("关联插件连接完毕") + if (QuickShopHook.hasQs) Bukkit.getPluginManager().registerEvents(QsChatEvent(), Bukkit.getPluginManager().getPlugin("PlumBot")!!) + if (QuickShopHook.hasQsHikari) Bukkit.getPluginManager().registerEvents(QsHikariChatEvent(), Bukkit.getPluginManager().getPlugin("PlumBot")!!) + if (GriefDefenderHook.hasGriefDefender) Bukkit.getPluginManager().registerEvents(GDClaimEvent(), Bukkit.getPluginManager().getPlugin("PlumBot")!!) + } + + override fun getPlayerList(): List { + TODO("Not yet implemented") + } + + override fun getTPS(): List { + TODO("Not yet implemented") + } + + override fun dispatchCommand(cmd: String): StringBuilder { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/event/BukkitListener.kt b/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/event/BukkitListener.kt new file mode 100644 index 0000000..b2104e3 --- /dev/null +++ b/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/event/BukkitListener.kt @@ -0,0 +1,70 @@ +package me.regadpole.plumbot.bukkit.event + +import me.regadpole.plumbot.bukkit.event.impl.BukkitJoinEvent +import me.regadpole.plumbot.bukkit.hook.AuthMeHook +import me.regadpole.plumbot.bukkit.hook.GriefDefenderHook +import me.regadpole.plumbot.bukkit.hook.QuickShopHook +import me.regadpole.plumbot.bukkit.hook.ResidenceHook +import me.regadpole.plumbot.bukkit.listener.GDClaimEvent +import me.regadpole.plumbot.bukkit.listener.QsChatEvent +import me.regadpole.plumbot.bukkit.listener.QsHikariChatEvent +import me.regadpole.plumbot.bukkit.util.impl.BukkitPlayer +import me.regadpole.plumbot.event.GDeathEvent +import me.regadpole.plumbot.event.GPlayerChatEvent +import me.regadpole.plumbot.event.GQuitEvent +import me.regadpole.plumbot.listener.game.GameListener +import me.regadpole.plumbot.tool.StringTool +import org.bukkit.event.entity.PlayerDeathEvent +import org.bukkit.event.player.AsyncPlayerChatEvent +import org.bukkit.event.player.PlayerJoinEvent +import org.bukkit.event.player.PlayerQuitEvent +import taboolib.common.platform.event.SubscribeEvent + +class BukkitListener { + @SubscribeEvent + fun onJoin(event: PlayerJoinEvent) { + GameListener.onJoin(BukkitJoinEvent(event.player)) + } + + @SubscribeEvent + fun onQuit(event: PlayerQuitEvent) { + GameListener.onQuit(GQuitEvent(BukkitPlayer(event.player))) + } + + @SubscribeEvent + fun onChat(event: AsyncPlayerChatEvent) { + val name: String = StringTool.filterColor(event.player.displayName) + val message: String = StringTool.filterColor(event.message) + if (AuthMeHook.hasAuthMe) { + if (!AuthMeHook.authMeApi.isAuthenticated(event.player)) { + return + } + } + if (ResidenceHook.hasRes) { + if (ResidenceHook.resChatApi.getPlayerChannel(event.player.name) != null) { + return + } + } + if (QuickShopHook.hasQs) { + if (event.player === QsChatEvent.getQsSender() && event.message === QsChatEvent.getQsMessage()) { + return + } + } + if (QuickShopHook.hasQsHikari) { + if (event.player === QsHikariChatEvent.getQsSender() && event.message === QsHikariChatEvent.getQsMessage()) { + return + } + } + if (GriefDefenderHook.hasGriefDefender) { + if (GDClaimEvent.getGDMessage() === event.message) { + return + } + } + GameListener.onChat(GPlayerChatEvent(event.message, BukkitPlayer(event.player))) + } + + @SubscribeEvent + fun onDeath(event: PlayerDeathEvent) { + GameListener.onDie(GDeathEvent(BukkitPlayer(event.entity))) + } +} \ No newline at end of file diff --git a/bukkit/src/main/java/me/regadpole/plumbot/event/impl/BukkitJoinEvent.kt b/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/event/impl/BukkitJoinEvent.kt similarity index 71% rename from bukkit/src/main/java/me/regadpole/plumbot/event/impl/BukkitJoinEvent.kt rename to bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/event/impl/BukkitJoinEvent.kt index fb0aa68..b754285 100644 --- a/bukkit/src/main/java/me/regadpole/plumbot/event/impl/BukkitJoinEvent.kt +++ b/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/event/impl/BukkitJoinEvent.kt @@ -1,7 +1,7 @@ -package me.regadpole.plumbot.event.impl +package me.regadpole.plumbot.bukkit.event.impl import me.regadpole.plumbot.event.GJoinEvent -import me.regadpole.plumbot.util.impl.BukkitPlayer +import me.regadpole.plumbot.bukkit.util.impl.BukkitPlayer import org.bukkit.entity.Player class BukkitJoinEvent(private val bukkitPlayer: Player) : GJoinEvent(BukkitPlayer(bukkitPlayer)) { diff --git a/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/util/ServerManager.kt b/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/util/ServerManager.kt new file mode 100644 index 0000000..38ade98 --- /dev/null +++ b/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/util/ServerManager.kt @@ -0,0 +1,67 @@ +package me.regadpole.plumbot.bukkit.util + +import me.regadpole.plumbot.PlumBot +import me.regadpole.plumbot.bot.KookBot +import me.regadpole.plumbot.bot.QQBot +import me.regadpole.plumbot.bukkit.listener.ConsoleSender +import me.regadpole.plumbot.tool.TextToImg +import org.bukkit.Bukkit +import taboolib.common.platform.function.submitAsync + +object ServerManager { + + @JvmField + var msgList: MutableList = java.util.LinkedList() + + fun sendCmd(cmd: String, disp: Boolean): String { + val returnStr = java.util.concurrent.atomic.AtomicReference("无返回值") + + val commandSender: org.bukkit.command.CommandSender = ConsoleSender() + + submitAsync(now = true) { + msgList.clear() + Bukkit.dispatchCommand(commandSender, cmd) + } + + submitAsync(delay = 20L) { + synchronized(returnStr) { + (returnStr as Any).notify() + val stringBuilder = java.lang.StringBuilder() + if (msgList.size == 0) { + msgList.add("无返回值") + } + for (msg in msgList) { + if (msgList[msgList.size - 1].equals(msg, ignoreCase = true)) { + stringBuilder.append(msg) + } else { + stringBuilder.append(msg).append("\n") + } + } + if (!disp) { + msgList.clear() + returnStr.set("无返回值") + } + if (stringBuilder.toString().length <= 5000) { + // PlumBot.getBot().sendMsg(isGroup, stringBuilder.toString(), id); + when (PlumBot.getBot()) { + is QQBot -> returnStr.set(TextToImg.toImgCQCode(stringBuilder.toString())) + is KookBot -> returnStr.set(stringBuilder.toString()) + else -> {} + } + } else { + returnStr.set("返回值过长") + } + msgList.clear() + } + } + + synchronized(returnStr) { + try { + (returnStr as Any).wait() + } catch (e: InterruptedException) { + throw java.lang.RuntimeException(e) + } + return returnStr.get() + } + } +} diff --git a/bukkit/src/main/java/me/regadpole/plumbot/util/impl/BukkitPlayer.kt b/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/util/impl/BukkitPlayer.kt similarity index 91% rename from bukkit/src/main/java/me/regadpole/plumbot/util/impl/BukkitPlayer.kt rename to bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/util/impl/BukkitPlayer.kt index 4f39f70..0325a32 100644 --- a/bukkit/src/main/java/me/regadpole/plumbot/util/impl/BukkitPlayer.kt +++ b/bukkit/src/main/kotlin/me/regadpole/plumbot/bukkit/util/impl/BukkitPlayer.kt @@ -1,4 +1,4 @@ -package me.regadpole.plumbot.util.impl; +package me.regadpole.plumbot.bukkit.util.impl; import me.regadpole.plumbot.util.GPlayer import me.regadpole.plumbot.util.GPosition diff --git a/common/src/main/kotlin/me/regadpole/plumbot/PlatformImpl.kt b/common/src/main/kotlin/me/regadpole/plumbot/PlatformImpl.kt index 9dbf82f..025962c 100644 --- a/common/src/main/kotlin/me/regadpole/plumbot/PlatformImpl.kt +++ b/common/src/main/kotlin/me/regadpole/plumbot/PlatformImpl.kt @@ -1,6 +1,7 @@ package me.regadpole.plumbot abstract class PlatformImpl { + abstract fun load() abstract fun getPlayerList() : List abstract fun getTPS(): List abstract fun dispatchCommand(cmd: String): StringBuilder diff --git a/common/src/main/kotlin/me/regadpole/plumbot/PlumBot.kt b/common/src/main/kotlin/me/regadpole/plumbot/PlumBot.kt index 116506a..fbf1404 100644 --- a/common/src/main/kotlin/me/regadpole/plumbot/PlumBot.kt +++ b/common/src/main/kotlin/me/regadpole/plumbot/PlumBot.kt @@ -9,8 +9,10 @@ import me.regadpole.plumbot.config.LangConfig import me.regadpole.plumbot.database.Database import me.regadpole.plumbot.database.MySQL import me.regadpole.plumbot.database.SQLite +import taboolib.common.platform.Platform import taboolib.common.platform.Plugin import taboolib.common.platform.function.* +import taboolib.platform.util.isBukkitServerRunning object PlumBot : Plugin() { diff --git a/common/src/main/kotlin/me/regadpole/plumbot/tool/StringTool.kt b/common/src/main/kotlin/me/regadpole/plumbot/tool/StringTool.kt index 23453cd..ca55675 100644 --- a/common/src/main/kotlin/me/regadpole/plumbot/tool/StringTool.kt +++ b/common/src/main/kotlin/me/regadpole/plumbot/tool/StringTool.kt @@ -3,7 +3,7 @@ package me.regadpole.plumbot.tool import java.util.regex.Matcher import java.util.regex.Pattern -class StringTool { +object StringTool { fun filterColor(text: String?): String { val regEx = "§[0-9a-zA-Z]" val p: Pattern = Pattern.compile(regEx) diff --git a/common/src/main/kotlin/me/regadpole/plumbot/tool/TextToImg.kt b/common/src/main/kotlin/me/regadpole/plumbot/tool/TextToImg.kt index bfe30d5..8598435 100644 --- a/common/src/main/kotlin/me/regadpole/plumbot/tool/TextToImg.kt +++ b/common/src/main/kotlin/me/regadpole/plumbot/tool/TextToImg.kt @@ -10,183 +10,181 @@ import javax.imageio.ImageIO import javax.imageio.stream.MemoryCacheImageOutputStream -class TextToImg { - - companion object { - private var font: Font? = null - private var fm: FontMetrics? = null - private val ttfFile: File = File(getDataFolder(), "MiSans-Normal.ttf") - - @Throws(IOException::class) - private fun toImg(text: String): ByteArray { - if (fm == null) { - try { - font = Font.createFont(Font.TRUETYPE_FONT, ttfFile.toURI().toURL().openStream()) - font = font!!.deriveFont(32f) - fm = Toolkit.getDefaultToolkit().getFontMetrics(font) - } catch (e: FontFormatException) { - throw RuntimeException(e) - } +object TextToImg { + + private var font: Font? = null + private var fm: FontMetrics? = null + private val ttfFile: File = File(getDataFolder(), "MiSans-Normal.ttf") + + @Throws(IOException::class) + private fun toImg(text: String): ByteArray { + if (fm == null) { + try { + font = Font.createFont(Font.TRUETYPE_FONT, ttfFile.toURI().toURL().openStream()) + font = font!!.deriveFont(32f) + fm = Toolkit.getDefaultToolkit().getFontMetrics(font) + } catch (e: FontFormatException) { + throw RuntimeException(e) } + } - val strings = text.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - var minX = 0 - for (line in strings) { - var line = line - line = line.replace("ᄃ\\S".toRegex(), "") - line = line.replace("§\\S".toRegex(), "") + val strings = text.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + var minX = 0 + for (line in strings) { + var line = line + line = line.replace("ᄃ\\S".toRegex(), "") + line = line.replace("§\\S".toRegex(), "") - //font.getLineMetrics(line) - val result = fm!!.stringWidth(line) + //font.getLineMetrics(line) + val result = fm!!.stringWidth(line) - if (minX < result) minX = result - } - val Y = strings.size * 34 + (strings.size - 1) * 8 + 15 - minX += 32 - val image = BufferedImage( - minX, Y, - BufferedImage.TYPE_INT_BGR - ) - val g = image.graphics - g.setClip(0, 0, minX, Y) - g.color = Color("FFFFFF".toInt(16)) - g.fillRect(0, 0, minX, Y) // 先用黑色填充整张图片,也就是背景 - g.color = Color.black // 在换成黑色 - g.font = font // 设置画笔字体 - for (i in strings.indices) { - val nowLine = strings[i] - var dex = 0 - var nowX = 16 - - var j = 0 - while (j < nowLine.length) { - if (nowLine[j] == 'ᄃ' || nowLine[j] == '§') { - when (nowLine[j + 1]) { - '0' -> g.color = Color.black - '1' -> g.color = Color("0000AA".toInt(16)) - '2' -> g.color = Color("00AA00".toInt(16)) - '3' -> g.color = Color("00AAAA".toInt(16)) - '4' -> g.color = Color("AA0000".toInt(16)) - '5' -> g.color = Color("AA00AA".toInt(16)) - '6' -> g.color = Color("FFAA00".toInt(16)) - '7' -> g.color = Color("AAAAAA".toInt(16)) - '8' -> g.color = Color("555555".toInt(16)) - '9' -> g.color = Color("5555FF".toInt(16)) - 'a' -> g.color = Color("55FF55".toInt(16)) - 'b' -> g.color = Color("55FFFF".toInt(16)) - 'c' -> g.color = Color("FF5555".toInt(16)) - 'd' -> g.color = Color("FF55FF".toInt(16)) - 'e' -> g.color = Color("FFFF55".toInt(16)) - 'f' -> // g.setColor(new Color(Integer.parseInt("FFFFFF", 16))); - g.color = Color.black - - 'g' -> g.color = Color("DDD605".toInt(16)) - else -> g.color = Color.black - } - j++ - dex += 2 - } else { - g.drawString(nowLine[dex].toString(), nowX, if (i > 0) 34 + (i) * 34 + (i) * 8 else 34) - nowX += fm!!.charWidth(nowLine[dex]) - dex++ + if (minX < result) minX = result + } + val Y = strings.size * 34 + (strings.size - 1) * 8 + 15 + minX += 32 + val image = BufferedImage( + minX, Y, + BufferedImage.TYPE_INT_BGR + ) + val g = image.graphics + g.setClip(0, 0, minX, Y) + g.color = Color("FFFFFF".toInt(16)) + g.fillRect(0, 0, minX, Y) // 先用黑色填充整张图片,也就是背景 + g.color = Color.black // 在换成黑色 + g.font = font // 设置画笔字体 + for (i in strings.indices) { + val nowLine = strings[i] + var dex = 0 + var nowX = 16 + + var j = 0 + while (j < nowLine.length) { + if (nowLine[j] == 'ᄃ' || nowLine[j] == '§') { + when (nowLine[j + 1]) { + '0' -> g.color = Color.black + '1' -> g.color = Color("0000AA".toInt(16)) + '2' -> g.color = Color("00AA00".toInt(16)) + '3' -> g.color = Color("00AAAA".toInt(16)) + '4' -> g.color = Color("AA0000".toInt(16)) + '5' -> g.color = Color("AA00AA".toInt(16)) + '6' -> g.color = Color("FFAA00".toInt(16)) + '7' -> g.color = Color("AAAAAA".toInt(16)) + '8' -> g.color = Color("555555".toInt(16)) + '9' -> g.color = Color("5555FF".toInt(16)) + 'a' -> g.color = Color("55FF55".toInt(16)) + 'b' -> g.color = Color("55FFFF".toInt(16)) + 'c' -> g.color = Color("FF5555".toInt(16)) + 'd' -> g.color = Color("FF55FF".toInt(16)) + 'e' -> g.color = Color("FFFF55".toInt(16)) + 'f' -> // g.setColor(new Color(Integer.parseInt("FFFFFF", 16))); + g.color = Color.black + + 'g' -> g.color = Color("DDD605".toInt(16)) + else -> g.color = Color.black } j++ + dex += 2 + } else { + g.drawString(nowLine[dex].toString(), nowX, if (i > 0) 34 + (i) * 34 + (i) * 8 else 34) + nowX += fm!!.charWidth(nowLine[dex]) + dex++ } - - //System.out.println(strings[i]); + j++ } - g.dispose() - val os = ByteArrayOutputStream() - - // 创建一个MemoryCacheImageOutputStream对象,传入os作为参数 - val mcios = MemoryCacheImageOutputStream(os) - // 使用ImageIO.write方法将image写入mcios,指定图片格式为png - ImageIO.write(image, "png", mcios) - // 关闭mcios - mcios.close() - return os.toByteArray() + + //System.out.println(strings[i]); } + g.dispose() + val os = ByteArrayOutputStream() + + // 创建一个MemoryCacheImageOutputStream对象,传入os作为参数 + val mcios = MemoryCacheImageOutputStream(os) + // 使用ImageIO.write方法将image写入mcios,指定图片格式为png + ImageIO.write(image, "png", mcios) + // 关闭mcios + mcios.close() + return os.toByteArray() + } - /** - * 将inputstream转为Base64 - * - * @param bytes - * @return - * @throws Exception - */ - @Throws(Exception::class) - private fun getBase64FromInputStream(bytes: ByteArray): String? { - // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 - val data: ByteArray - - val inputStream: InputStream = ByteArrayInputStream(bytes) - - // 读取图片字节数组 + /** + * 将inputstream转为Base64 + * + * @param bytes + * @return + * @throws Exception + */ + @Throws(Exception::class) + private fun getBase64FromInputStream(bytes: ByteArray): String? { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + val data: ByteArray + + val inputStream: InputStream = ByteArrayInputStream(bytes) + + // 读取图片字节数组 + try { + val swapStream = ByteArrayOutputStream() + val buff = ByteArray(100) + var rc: Int + while ((inputStream.read(buff, 0, 100).also { rc = it }) > 0) { + swapStream.write(buff, 0, rc) + } + data = swapStream.toByteArray() + return Base64.getEncoder().encodeToString(data) + } catch (e: IOException) { + severe(e.toString()) + } finally { try { - val swapStream = ByteArrayOutputStream() - val buff = ByteArray(100) - var rc: Int - while ((inputStream.read(buff, 0, 100).also { rc = it }) > 0) { - swapStream.write(buff, 0, rc) - } - data = swapStream.toByteArray() - return Base64.getEncoder().encodeToString(data) + inputStream.close() } catch (e: IOException) { - severe(e.toString()) - } finally { - try { - inputStream.close() - } catch (e: IOException) { - throw Exception("输入流关闭异常") - } + throw Exception("输入流关闭异常") } - - return null } - /** - * 字节数组转字符串,如 A0 09 70 -> 101000000000100101110000。 - * @param bts 转入字节数组。 - * @return 转换好的只有“1”和“0”的字符串。 - */ - private fun bytes2String(bts: ByteArray): String { - val dic = arrayOf( - "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", - "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" - ) - val out = StringBuilder() - for (b in bts) { - var s = String.format("%x", b) - s = if (s.length == 1) "0$s" else s - out.append(dic[s.substring(0, 1).toInt(16)]) - out.append(dic[s.substring(1, 2).toInt(16)]) - } - return out.toString() - } + return null + } - fun toImgCQCode(string: String): String { - var base64: String? = null - try { - base64 = getBase64FromInputStream(toImg(string)) - } catch (e: Exception) { - severe(e.toString()) - } - return "[CQ:image,file=base64://$base64]" + /** + * 字节数组转字符串,如 A0 09 70 -> 101000000000100101110000。 + * @param bts 转入字节数组。 + * @return 转换好的只有“1”和“0”的字符串。 + */ + private fun bytes2String(bts: ByteArray): String { + val dic = arrayOf( + "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", + "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" + ) + val out = StringBuilder() + for (b in bts) { + var s = String.format("%x", b) + s = if (s.length == 1) "0$s" else s + out.append(dic[s.substring(0, 1).toInt(16)]) + out.append(dic[s.substring(1, 2).toInt(16)]) } + return out.toString() + } - fun toImgBinary(string: String): String { - var bytes = "" - try { - bytes = bytes2String(toImg(string)) - } catch (e: IOException) { - severe(e.toString()) - } - return bytes + fun toImgCQCode(string: String): String { + var base64: String? = null + try { + base64 = getBase64FromInputStream(toImg(string)) + } catch (e: Exception) { + severe(e.toString()) } + return "[CQ:image,file=base64://$base64]" + } - @Throws(IOException::class) - fun toImgBinArray(string: String): ByteArray { - return toImg(string) + fun toImgBinary(string: String): String { + var bytes = "" + try { + bytes = bytes2String(toImg(string)) + } catch (e: IOException) { + severe(e.toString()) } + return bytes + } + + @Throws(IOException::class) + fun toImgBinArray(string: String): ByteArray { + return toImg(string) } } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 573fe49..6c9c4b8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.0.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists \ No newline at end of file