diff --git a/api/src/main/java/net/azisaba/azipluginmessaging/api/AziPluginMessaging.java b/api/src/main/java/net/azisaba/azipluginmessaging/api/AziPluginMessaging.java index 3906297..f4e22cd 100644 --- a/api/src/main/java/net/azisaba/azipluginmessaging/api/AziPluginMessaging.java +++ b/api/src/main/java/net/azisaba/azipluginmessaging/api/AziPluginMessaging.java @@ -3,6 +3,7 @@ import net.azisaba.azipluginmessaging.api.entity.Player; import net.azisaba.azipluginmessaging.api.entity.PlayerAdapter; import net.azisaba.azipluginmessaging.api.protocol.PacketQueue; +import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundPunishMessage; import net.azisaba.azipluginmessaging.api.protocol.message.ServerboundCheckRankExpirationMessage; import net.azisaba.azipluginmessaging.api.server.PacketSender; import net.azisaba.azipluginmessaging.api.util.SQLThrowableConsumer; @@ -92,6 +93,10 @@ default void loadConfig(@NotNull YamlObject obj) { default void checkRankAsync(@NotNull UUID uuid) { throw new UnsupportedOperationException("Unsupported in current environment."); } + + default void handle(@NotNull ProxyboundPunishMessage msg) { + throw new UnsupportedOperationException("Unsupported in current environment."); + } } interface Server { diff --git a/api/src/main/java/net/azisaba/azipluginmessaging/api/AziPluginMessagingConfig.java b/api/src/main/java/net/azisaba/azipluginmessaging/api/AziPluginMessagingConfig.java index a2947d4..777837a 100644 --- a/api/src/main/java/net/azisaba/azipluginmessaging/api/AziPluginMessagingConfig.java +++ b/api/src/main/java/net/azisaba/azipluginmessaging/api/AziPluginMessagingConfig.java @@ -1,5 +1,6 @@ package net.azisaba.azipluginmessaging.api; +import net.azisaba.azipluginmessaging.api.yaml.YamlArray; import net.azisaba.azipluginmessaging.api.yaml.YamlConfiguration; import net.azisaba.azipluginmessaging.api.yaml.YamlObject; import org.jetbrains.annotations.NotNull; @@ -11,6 +12,7 @@ import java.nio.file.StandardOpenOption; import java.util.Arrays; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; public class AziPluginMessagingConfig { @@ -23,6 +25,7 @@ public class AziPluginMessagingConfig { public static final Map servers = new ConcurrentHashMap<>(); public static final Map saraShowServers = new ConcurrentHashMap<>(); public static final Map rankableServers = new ConcurrentHashMap<>(); + public static final Set unpunishableServers = ConcurrentHashMap.newKeySet(); @SuppressWarnings("DeprecatedIsStillUsed") // not used outside this class @Deprecated public static final Map contextualServers = new ConcurrentHashMap<>(); @@ -97,13 +100,17 @@ public static void reload() { " life: life", " lifepve: life", "", + "# List of servers that ProxyboundPunishPacket is not allowed on.", + "unpunishableServers: # this is meaningless in spigot", + " - life9000", + "", "# Database settings (required)", "# This setting is used for setting the rank temporary.", "database:", " # (scheme)://(host):(port)/(database)", " # Keep the line commented out unless you get an obvious error message indicating that the driver was not found.", " # Default driver (net.azisaba.taxoffice.libs.org.mariadb.jdbc.Driver) points to the bundled MariaDB driver in the TaxOffice jar.", - " #driver: net.azisaba.taxoffice.libs.org.mariadb.jdbc.Driver", + " #driver: net.azisaba.azipluginmessaging.libs.org.mariadb.jdbc.Driver", "", " # change to jdbc:mysql if you want to use MySQL instead of MariaDB", " scheme: jdbc:mariadb", @@ -139,6 +146,7 @@ public static void reload() { readMap(servers, obj, "servers"); readMap(rankableServers, obj, "rankableServers"); readMap(saraShowServers, obj, "saraShowServers"); + readSet(unpunishableServers, obj, "unpunishableServers"); AziPluginMessagingProvider.get().getProxy().loadConfig(obj); } } catch (IOException ex) { @@ -159,4 +167,11 @@ private static void readMap(@NotNull Map to, @NotNull YamlObject mapObject.getRawData().forEach((key, value) -> to.put(key, String.valueOf(value))); } } + + private static void readSet(@NotNull Set to, @NotNull YamlObject obj, @NotNull String configKey) { + YamlArray array = obj.getArray(configKey); + if (array != null) { + to.addAll(array.mapToString()); + } + } } diff --git a/api/src/main/java/net/azisaba/azipluginmessaging/api/entity/SimplePlayer.java b/api/src/main/java/net/azisaba/azipluginmessaging/api/entity/SimplePlayer.java index bcaf2dd..1405482 100644 --- a/api/src/main/java/net/azisaba/azipluginmessaging/api/entity/SimplePlayer.java +++ b/api/src/main/java/net/azisaba/azipluginmessaging/api/entity/SimplePlayer.java @@ -47,6 +47,14 @@ public boolean isChallengeEquals(@NotNull String challenge) { return false; } + @Override + public String toString() { + return "SimplePlayer{" + + "uuid=" + uuid + + ", username='" + username + '\'' + + '}'; + } + @Contract("_ -> new") @NotNull public static SimplePlayer read(@NotNull DataInputStream in) throws IOException { diff --git a/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/Protocol.java b/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/Protocol.java index ff79117..5a6ea67 100644 --- a/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/Protocol.java +++ b/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/Protocol.java @@ -3,40 +3,8 @@ import net.azisaba.azipluginmessaging.api.AziPluginMessagingConfig; import net.azisaba.azipluginmessaging.api.AziPluginMessagingProvider; import net.azisaba.azipluginmessaging.api.Logger; -import net.azisaba.azipluginmessaging.api.protocol.handler.MessageHandler; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyMessageHandler; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundCheckRankExpirationPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundClearPrefixPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundEncryptionPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundEncryptionResponsePacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundGiveGamingSaraPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundGiveNitroSaraPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundGiveSaraPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundSetPrefixPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundSetRankPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundToggleGamingSaraPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundToggleNitroSaraPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundToggleSaraHidePacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ProxyboundToggleSaraShowPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ServerMessageHandler; -import net.azisaba.azipluginmessaging.api.protocol.handler.ServerboundActionResponsePacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ServerboundCheckRankExpirationPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ServerboundEncryptionPacket; -import net.azisaba.azipluginmessaging.api.protocol.handler.ServerboundEncryptionResponsePacket; -import net.azisaba.azipluginmessaging.api.protocol.message.EmptyMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.EncryptionMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.Message; -import net.azisaba.azipluginmessaging.api.protocol.message.PlayerMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundCheckRankExpirationMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundClearPrefixMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundGiveNitroSaraMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundGiveSaraMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundSetPrefixMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundSetRankMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundToggleSaraHideMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundToggleSaraShowMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.ServerboundActionResponseMessage; -import net.azisaba.azipluginmessaging.api.protocol.message.ServerboundCheckRankExpirationMessage; +import net.azisaba.azipluginmessaging.api.protocol.handler.*; +import net.azisaba.azipluginmessaging.api.protocol.message.*; import net.azisaba.azipluginmessaging.api.server.PacketSender; import net.azisaba.azipluginmessaging.api.server.ServerConnection; import net.azisaba.azipluginmessaging.api.util.EncryptionUtil; @@ -81,6 +49,7 @@ public final class Protocol, M extends Message> { public static final Protocol P_GIVE_NITRO_SARA = new Protocol<>(PacketFlow.TO_PROXY, 0x0A, new ProxyboundGiveNitroSaraPacket()); public static final Protocol P_TOGGLE_NITRO_SARA = new Protocol<>(PacketFlow.TO_PROXY, 0x0B, new ProxyboundToggleNitroSaraPacket()); public static final Protocol P_CHECK_RANK_EXPIRATION = new Protocol<>(PacketFlow.TO_PROXY, 0x0C, new ProxyboundCheckRankExpirationPacket()); + public static final Protocol P_PUNISH = new Protocol<>(PacketFlow.TO_PROXY, 0x0D, new ProxyboundPunishPacket()); public static final Protocol S_ENCRYPTION = new Protocol<>(PacketFlow.TO_SERVER, 0x00, new ServerboundEncryptionPacket()); public static final Protocol S_ENCRYPTION_RESPONSE = new Protocol<>(PacketFlow.TO_SERVER, 0x01, new ServerboundEncryptionResponsePacket()); diff --git a/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/handler/ProxyboundPunishPacket.java b/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/handler/ProxyboundPunishPacket.java new file mode 100644 index 0000000..0f30b6b --- /dev/null +++ b/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/handler/ProxyboundPunishPacket.java @@ -0,0 +1,28 @@ +package net.azisaba.azipluginmessaging.api.protocol.handler; + +import net.azisaba.azipluginmessaging.api.AziPluginMessagingConfig; +import net.azisaba.azipluginmessaging.api.AziPluginMessagingProvider; +import net.azisaba.azipluginmessaging.api.Logger; +import net.azisaba.azipluginmessaging.api.protocol.Protocol; +import net.azisaba.azipluginmessaging.api.protocol.message.EmptyMessage; +import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundPunishMessage; +import net.azisaba.azipluginmessaging.api.server.PacketSender; +import net.azisaba.azipluginmessaging.api.server.ServerConnection; +import org.jetbrains.annotations.NotNull; + +import java.io.DataInputStream; +import java.io.IOException; + +public class ProxyboundPunishPacket implements ProxyMessageHandler { + @Override + public @NotNull ProxyboundPunishMessage read(@NotNull ServerConnection server, @NotNull DataInputStream in) throws IOException { + String serverName = server.getServerInfo().getName(); + serverName = AziPluginMessagingConfig.servers.getOrDefault(serverName, serverName); + return ProxyboundPunishMessage.read(serverName, in); + } + + @Override + public void handle(@NotNull PacketSender sender, @NotNull ProxyboundPunishMessage msg) throws Exception { + AziPluginMessagingProvider.get().getProxy().handle(msg); + } +} diff --git a/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/message/PlayerWithServerMessage.java b/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/message/PlayerWithServerMessage.java index a183c10..79c64c3 100644 --- a/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/message/PlayerWithServerMessage.java +++ b/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/message/PlayerWithServerMessage.java @@ -43,9 +43,9 @@ public void write(@NotNull DataOutputStream out) throws IOException { super.write(out); } - @Contract("null, _ -> fail; _, _ -> new") + @Contract("_, _ -> new") @NotNull - public static PlayerWithServerMessage read(@Nullable String server, @NotNull DataInputStream in) throws IOException { + public static PlayerWithServerMessage read(@NotNull String server, @NotNull DataInputStream in) throws IOException { UUID uuid = UUID.fromString(in.readUTF()); String username = null; if (in.readBoolean()) { diff --git a/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/message/ProxyboundGiveNitroSaraMessage.java b/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/message/ProxyboundGiveNitroSaraMessage.java index 06190b8..7b22f84 100644 --- a/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/message/ProxyboundGiveNitroSaraMessage.java +++ b/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/message/ProxyboundGiveNitroSaraMessage.java @@ -30,6 +30,6 @@ public TimeUnit getUnit() { public void write(@NotNull DataOutputStream out) throws IOException { super.write(out); out.writeInt(time); - out.writeUTF(unit.name()); // ordinal might be different with other versions of java + out.writeUTF(unit.name()); } } diff --git a/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/message/ProxyboundPunishMessage.java b/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/message/ProxyboundPunishMessage.java new file mode 100644 index 0000000..3d4e310 --- /dev/null +++ b/api/src/main/java/net/azisaba/azipluginmessaging/api/protocol/message/ProxyboundPunishMessage.java @@ -0,0 +1,132 @@ +package net.azisaba.azipluginmessaging.api.protocol.message; + +import net.azisaba.azipluginmessaging.api.entity.Player; +import net.azisaba.azipluginmessaging.api.entity.SimplePlayer; +import net.azisaba.azipluginmessaging.api.punishment.PunishmentType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +public class ProxyboundPunishMessage extends PlayerWithServerMessage { + private final Player sender; + private final PunishmentType type; + private final String reason; + private final int time; + private final TimeUnit unit; + + public ProxyboundPunishMessage( + @NotNull String server, + @NotNull Player player, + @NotNull Player sender, + @NotNull PunishmentType type, + @NotNull String reason, + int time, + @Nullable TimeUnit unit) { + super(server, player); + if (type.name().startsWith("TEMP_")) { + if (time <= 0 || unit == null) { + throw new IllegalArgumentException("Time and unit must be set for temporary punishments"); + } + } else { + if (time != 0 || unit != null) { + throw new IllegalArgumentException("Time and unit must not be set for permanent punishments"); + } + } + this.sender = Objects.requireNonNull(sender, "sender"); + this.type = Objects.requireNonNull(type, "type"); + this.reason = Objects.requireNonNull(reason, "reason"); + this.time = time; + this.unit = unit; + } + + public @NotNull Player getSender() { + return sender; + } + + public @NotNull PunishmentType getType() { + return type; + } + + public @NotNull String getReason() { + return reason; + } + + /** + * Returns the duration of the punishment. If the punishment is permanent, it returns 0. + * @return the duration of the punishment + */ + public int getTime() { + return unit == null ? 0 : time; + } + + /** + * Returns the unit of the duration. If the unit is null, it means the punishment is permanent. + * @return the unit of the duration + */ + public @Nullable TimeUnit getUnit() { + return unit; + } + + /** + * Returns whether the punishment is temporary or not. + * @return whether the punishment is temporary or not + */ + public boolean isTemporary() { + return getTime() > 0 && unit != null; + } + + /** + * Returns whether the punishment is permanent or not. + * @return whether the punishment is permanent or not + */ + public boolean isPermanent() { + return !isTemporary(); // time == 0 || unit == null + } + + @Override + public void write(@NotNull DataOutputStream out) throws IOException { + super.write(out); + out.writeUTF(sender.getUniqueId().toString()); + out.writeBoolean(sender.getUsername() != null); + if (sender.getUsername() != null) { + out.writeUTF(sender.getUsername()); + } + out.writeUTF(type.name()); + out.writeUTF(reason); + out.writeInt(time); + out.writeBoolean(unit != null); + if (unit != null) { + out.writeUTF(unit.name()); + } + } + + @Override + public String toString() { + return "ProxyboundPunishMessage{" + + "sender=" + sender + + ", type=" + type + + ", reason='" + reason + '\'' + + ", time=" + time + + ", unit=" + unit + + ", server='" + server + '\'' + + ", player=" + player + + '}'; + } + + public static @NotNull ProxyboundPunishMessage read(@NotNull String server, @NotNull DataInputStream in) throws IOException { + return new ProxyboundPunishMessage( + server, + SimplePlayer.read(in), + SimplePlayer.read(in), + PunishmentType.valueOf(in.readUTF()), + in.readUTF(), + in.readInt(), + in.readBoolean() ? TimeUnit.valueOf(in.readUTF()) : null + ); + } +} diff --git a/api/src/main/java/net/azisaba/azipluginmessaging/api/punishment/PunishmentType.java b/api/src/main/java/net/azisaba/azipluginmessaging/api/punishment/PunishmentType.java new file mode 100644 index 0000000..0ad4ba0 --- /dev/null +++ b/api/src/main/java/net/azisaba/azipluginmessaging/api/punishment/PunishmentType.java @@ -0,0 +1,15 @@ +package net.azisaba.azipluginmessaging.api.punishment; + +public enum PunishmentType { + BAN, + TEMP_BAN, + IP_BAN, + TEMP_IP_BAN, + MUTE, + TEMP_MUTE, + IP_MUTE, + TEMP_IP_MUTE, + WARNING, + CAUTION, + KICK, +} diff --git a/build.gradle.kts b/build.gradle.kts index bbbf252..a299614 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,11 +2,11 @@ plugins { java `java-library` `maven-publish` - id("com.github.johnrengelman.shadow") version "7.1.2" apply false + id("com.gradleup.shadow") version "8.3.3" apply false } group = "net.azisaba.azipluginmessaging" -version = "4.0.5" +version = "4.1.0" repositories { mavenCentral() @@ -29,7 +29,7 @@ subprojects { plugin("java") plugin("java-library") plugin("maven-publish") - plugin("com.github.johnrengelman.shadow") + plugin("com.gradleup.shadow") } repositories { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180..41d9927 100644 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 aa991fc..1e2fbf0 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.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 744e882..1b6c787 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,101 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# 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 +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +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"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MSYS* | MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + 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. Please set the JAVA_HOME variable in your environment to match the @@ -106,80 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# 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. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/spigot/src/main/java/net/azisaba/azipluginmessaging/spigot/command/CommandManager.java b/spigot/src/main/java/net/azisaba/azipluginmessaging/spigot/command/CommandManager.java index dbf5e6a..b7eb2f8 100644 --- a/spigot/src/main/java/net/azisaba/azipluginmessaging/spigot/command/CommandManager.java +++ b/spigot/src/main/java/net/azisaba/azipluginmessaging/spigot/command/CommandManager.java @@ -1,17 +1,6 @@ package net.azisaba.azipluginmessaging.spigot.command; -import net.azisaba.azipluginmessaging.spigot.commands.ClearPrefixCommand; -import net.azisaba.azipluginmessaging.spigot.commands.DumpProtocolCommand; -import net.azisaba.azipluginmessaging.spigot.commands.GiveGamingSaraCommand; -import net.azisaba.azipluginmessaging.spigot.commands.GiveNitroSaraCommand; -import net.azisaba.azipluginmessaging.spigot.commands.GiveSaraCommand; -import net.azisaba.azipluginmessaging.spigot.commands.HelpCommand; -import net.azisaba.azipluginmessaging.spigot.commands.SetPrefixCommand; -import net.azisaba.azipluginmessaging.spigot.commands.SetRankCommand; -import net.azisaba.azipluginmessaging.spigot.commands.ToggleGamingSaraCommand; -import net.azisaba.azipluginmessaging.spigot.commands.ToggleNitroSaraCommand; -import net.azisaba.azipluginmessaging.spigot.commands.ToggleSaraHideCommand; -import net.azisaba.azipluginmessaging.spigot.commands.ToggleSaraShowCommand; +import net.azisaba.azipluginmessaging.spigot.commands.*; import org.jetbrains.annotations.Nullable; import java.util.Arrays; @@ -30,7 +19,8 @@ public class CommandManager { new ClearPrefixCommand(), new GiveNitroSaraCommand(), new ToggleNitroSaraCommand(), - new DumpProtocolCommand() + new DumpProtocolCommand(), + new PunishCommand() ); public static @Nullable Command getCommand(String name) { diff --git a/spigot/src/main/java/net/azisaba/azipluginmessaging/spigot/commands/PunishCommand.java b/spigot/src/main/java/net/azisaba/azipluginmessaging/spigot/commands/PunishCommand.java new file mode 100644 index 0000000..7807fa8 --- /dev/null +++ b/spigot/src/main/java/net/azisaba/azipluginmessaging/spigot/commands/PunishCommand.java @@ -0,0 +1,81 @@ +package net.azisaba.azipluginmessaging.spigot.commands; + +import net.azisaba.azipluginmessaging.api.entity.Player; +import net.azisaba.azipluginmessaging.api.entity.SimplePlayer; +import net.azisaba.azipluginmessaging.api.protocol.Protocol; +import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundPunishMessage; +import net.azisaba.azipluginmessaging.api.punishment.PunishmentType; +import net.azisaba.azipluginmessaging.spigot.SpigotPlugin; +import net.azisaba.azipluginmessaging.spigot.command.Command; +import net.azisaba.azipluginmessaging.spigot.entity.PlayerImpl; +import net.azisaba.azipluginmessaging.spigot.util.PlayerUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import xyz.acrylicstyle.util.ArgumentParsedResult; +import xyz.acrylicstyle.util.ArgumentParser; +import xyz.acrylicstyle.util.ArgumentParserBuilder; +import xyz.acrylicstyle.util.InvalidArgumentException; + +import java.util.Locale; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public class PunishCommand implements Command { + private static final ArgumentParser PARSER = + ArgumentParserBuilder.builder() + .disallowEscapedLineTerminators() + .disallowEscapedTabCharacter() + .parseOptionsWithoutDash() + .create(); + + @Override + public void execute(@NotNull CommandSender sender, @NotNull String[] args) throws InvalidArgumentException { + ArgumentParsedResult result = PARSER.parse(String.join(" ", args)); + if (result.unhandledArguments().size() < 3) { + sender.sendMessage(ChatColor.RED + "Usage: " + getFullUsage()); + return; + } + new Thread(() -> { + Player target = PlayerUtil.getOfflinePlayer(result.unhandledArguments().get(0)); + Player senderPlayer = + sender instanceof org.bukkit.entity.Player + ? PlayerImpl.of((org.bukkit.entity.Player) sender) + : new SimplePlayer(new UUID(0, 0), "CONSOLE"); + PunishmentType type = PunishmentType.valueOf(result.unhandledArguments().get(1).toUpperCase(Locale.ROOT)); + String reason = result.unhandledArguments().get(2); + int time = result.unhandledArguments().size() == 3 ? 0 : Integer.parseInt(result.unhandledArguments().get(3)); + TimeUnit unit = result.unhandledArguments().size() == 3 ? null : TimeUnit.valueOf(result.unhandledArguments().get(4).toUpperCase(Locale.ROOT)); + ProxyboundPunishMessage message = new ProxyboundPunishMessage( + "", + target, + senderPlayer, + type, + reason, + time, + unit + ); + boolean res = Protocol.P_PUNISH.sendPacket(SpigotPlugin.getAnyPacketSenderOrNull(), message); + if (res) { + sender.sendMessage(ChatColor.GREEN + "Sent a request!"); + } else { + sender.sendMessage(ChatColor.RED + "Failed to send the packet. Maybe check console for errors?"); + } + }).start(); + } + + @Override + public @NotNull String getName() { + return "punish"; + } + + @Override + public @NotNull String getDescription() { + return "Punish a player."; + } + + @Override + public @NotNull String getUsage() { + return " [time] [unit]"; + } +} diff --git a/velocity/build.gradle.kts b/velocity/build.gradle.kts index 430e0b1..4427509 100644 --- a/velocity/build.gradle.kts +++ b/velocity/build.gradle.kts @@ -1,7 +1,10 @@ repositories { - maven { url = uri("https://nexus.velocitypowered.com/repository/maven-public/") } + maven { url = uri("https://repo.papermc.io/repository/maven-public/") } + maven("https://repo.azisaba.net/repository/maven-public/") } +java.toolchain.languageVersion.set(JavaLanguageVersion.of(17)) + dependencies { api(project(":api")) @@ -9,14 +12,28 @@ dependencies { implementation("com.zaxxer:HikariCP:4.0.3") implementation("org.mariadb.jdbc:mariadb-java-client:3.0.6") // velocity-api - compileOnly("com.velocitypowered:velocity-api:3.0.1") - annotationProcessor("com.velocitypowered:velocity-api:3.0.1") + compileOnly("com.velocitypowered:velocity-api:3.4.0-SNAPSHOT") + annotationProcessor("com.velocitypowered:velocity-api:3.4.0-SNAPSHOT") + // SpicyAzisaBan + compileOnly("net.azisaba.spicyazisaban:common:2.0.0-dev-f2b83cc") + compileOnly("xyz.acrylicstyle.util:promise:0.16.6") + compileOnly("xyz.acrylicstyle:minecraft-util:1.0.0") { + exclude("xyz.acrylicstyle.util", "http") + exclude("xyz.acrylicstyle.util", "reflect") + } } tasks { shadowJar { relocate("org.mariadb.jdbc", "net.azisaba.azipluginmessaging.libs.org.mariadb.jdbc") relocate("com.zaxxer.hikari", "net.azisaba.azipluginmessaging.libs.com.zaxxer.hikari") + relocate("kotlin", "net.azisaba.spicyAzisaBan.libs.kotlin") + relocate("util", "net.azisaba.spicyAzisaBan.libs.util") + relocate("xyz.acrylicstyle.sql", "net.azisaba.spicyAzisaBan.libs.xyz.acrylicstyle.sql") + relocate("xyz.acrylicstyle.mcutil", "net.azisaba.spicyAzisaBan.libs.xyz.acrylicstyle.mcutil") + relocate("org.objectweb", "net.azisaba.spicyAzisaBan.libs.org.objectweb") + relocate("org.json", "net.azisaba.spicyAzisaBan.libs.org.json") + relocate("com.google.guava", "net.azisaba.spicyAzisaBan.libs.com.google.guava") archiveFileName.set("AziPluginMessaging-Velocity-${project.version}.jar") } } diff --git a/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/AziPluginMessagingVelocity.java b/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/AziPluginMessagingVelocity.java index a09b273..bc5d4fa 100644 --- a/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/AziPluginMessagingVelocity.java +++ b/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/AziPluginMessagingVelocity.java @@ -2,17 +2,26 @@ import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ProxyServer; -import net.azisaba.azipluginmessaging.api.AziPluginMessaging; -import net.azisaba.azipluginmessaging.api.AziPluginMessagingProvider; -import net.azisaba.azipluginmessaging.api.EnvironmentType; -import net.azisaba.azipluginmessaging.api.Logger; +import net.azisaba.azipluginmessaging.api.*; import net.azisaba.azipluginmessaging.api.entity.PlayerAdapter; import net.azisaba.azipluginmessaging.api.protocol.PacketQueue; +import net.azisaba.azipluginmessaging.api.protocol.message.ProxyboundPunishMessage; import net.azisaba.azipluginmessaging.api.util.LuckPermsUtil; import net.azisaba.azipluginmessaging.api.util.SQLThrowableConsumer; import net.azisaba.azipluginmessaging.api.util.SQLThrowableFunction; import net.azisaba.azipluginmessaging.api.yaml.YamlObject; import net.azisaba.azipluginmessaging.velocity.entity.PlayerImpl; +import net.azisaba.azipluginmessaging.velocity.entity.SimplePlayerActor; +import net.azisaba.azipluginmessaging.velocity.util.DurationUtil; +import net.azisaba.azipluginmessaging.velocity.util.StringUtil; +import net.azisaba.spicyAzisaBan.SpicyAzisaBan; +import net.azisaba.spicyAzisaBan.commands.*; +import net.azisaba.spicyAzisaBan.common.Actor; +import net.azisaba.spicyAzisaBan.struct.PlayerData; +import net.azisaba.spicyAzisaBan.util.contexts.PlayerContext; +import net.azisaba.spicyAzisaBan.util.contexts.ReasonContext; +import net.azisaba.spicyAzisaBan.util.contexts.ServerContext; +import net.azisaba.spicyAzisaBan.util.contexts.TimeContext; import net.luckperms.api.LuckPerms; import net.luckperms.api.LuckPermsProvider; import net.luckperms.api.actionlog.Action; @@ -165,5 +174,125 @@ public void checkRankAsync(@NotNull UUID uuid) { } }); } + + @Override + public void handle(@NotNull ProxyboundPunishMessage msg) { + logger.info("Processing punish message:"); + logger.info(" - Type: {}", msg.getType()); + logger.info(" - Player: {}", msg.getPlayer()); + logger.info(" - Sender: {}", msg.getSender()); + logger.info(" - Server: {}", msg.getServer()); + logger.info(" - Reason: {}", msg.getReason()); + logger.info(" - Time: {}", msg.getTime()); + logger.info(" - Unit: {}", msg.getUnit()); + if (AziPluginMessagingConfig.unpunishableServers.contains(msg.getServer())) { + logger.warn("Failed to handle punishment for {} because the server is unpunishable", msg.getPlayer().getUniqueId()); + return; + } + PlayerData.Companion.getByUUID(msg.getPlayer().getUniqueId()) + .onCatch(e -> {}) + .thenDo(player -> { + if (player == null) { + logger.warn("Failed to handle punishment for {} because the player data does not exist on SpicyAzisaBan database", msg.getPlayer().getUniqueId()); + return; + } + Actor senderActor; + PlayerData sender = PlayerData.Companion.getByUUID(msg.getSender().getUniqueId()).onCatch(e -> {}).complete(); + if (sender == null) { + if (msg.getSender().getUniqueId().equals(new UUID(0L, 0L))) { + senderActor = SpicyAzisaBan.instance.getConsoleActor(); + } else { + logger.warn("Failed to handle punishment for {} because the sender data does not exist on SpicyAzisaBan database", msg.getSender().getUniqueId()); + return; + } + } else { + senderActor = new SimplePlayerActor(sender); + } + switch (msg.getType()) { + case BAN -> BanCommand.INSTANCE.doBan( + senderActor, + new PlayerContext(true, player), + new ServerContext(true, msg.getServer(), false), + new ReasonContext(msg.getReason()), + false, + false + ); + case TEMP_BAN -> TempBanCommand.INSTANCE.doTempBan( + senderActor, + new PlayerContext(true, player), + new ServerContext(true, msg.getServer(), false), + new ReasonContext(msg.getReason()), + new TimeContext(true, Objects.requireNonNull(msg.getUnit()).toMillis(msg.getTime())), + false, + false + ); + case IP_BAN -> IPBanCommand.INSTANCE.execute( + senderActor, + new String[]{ + player.getName(), + "reason=\"" + StringUtil.escapeQuotes(msg.getReason()) + "\"", + "server=\"" + StringUtil.escapeQuotes(msg.getServer()) + "\"" + }); + case TEMP_IP_BAN -> TempIPBanCommand.INSTANCE.execute( + senderActor, + new String[]{ + player.getName(), + "reason=\"" + StringUtil.escapeQuotes(msg.getReason()) + "\"", + "server=\"" + StringUtil.escapeQuotes(msg.getServer()) + "\"", + "time=\"" + DurationUtil.unProcessTime(Objects.requireNonNull(msg.getUnit()).toMillis(msg.getTime())) + "\"" + }); + case MUTE -> MuteCommand.INSTANCE.doMute( + senderActor, + new PlayerContext(true, player), + new ServerContext(true, msg.getServer(), false), + new ReasonContext(msg.getReason()), + false, + false + ); + case TEMP_MUTE -> TempMuteCommand.INSTANCE.doTempMute( + senderActor, + new PlayerContext(true, player), + new ServerContext(true, msg.getServer(), false), + new ReasonContext(msg.getReason()), + new TimeContext(true, Objects.requireNonNull(msg.getUnit()).toMillis(msg.getTime())), + false, + false + ); + case IP_MUTE -> IPMuteCommand.INSTANCE.execute( + senderActor, + new String[]{ + player.getName(), + "reason=\"" + StringUtil.escapeQuotes(msg.getReason()) + "\"", + "server=\"" + StringUtil.escapeQuotes(msg.getServer()) + "\"" + }); + case TEMP_IP_MUTE -> TempIPMuteCommand.INSTANCE.execute( + senderActor, + new String[]{ + player.getName(), + "reason=\"" + StringUtil.escapeQuotes(msg.getReason()) + "\"", + "server=\"" + StringUtil.escapeQuotes(msg.getServer()) + "\"", + "time=\"" + DurationUtil.unProcessTime(Objects.requireNonNull(msg.getUnit()).toMillis(msg.getTime())) + "\"" + }); + case WARNING -> WarningCommand.INSTANCE.doWarning( + senderActor, + new PlayerContext(true, player), + new ServerContext(true, msg.getServer(), false), + new ReasonContext(msg.getReason()) + ); + case CAUTION -> CautionCommand.INSTANCE.doCaution( + senderActor, + new PlayerContext(true, player), + new ServerContext(true, msg.getServer(), false), + new ReasonContext(msg.getReason()) + ); + case KICK -> KickCommand.INSTANCE.doKick( + senderActor, + new PlayerContext(true, player), + new ServerContext(true, msg.getServer(), false), + new ReasonContext(msg.getReason()) + ); + } + }); + } } } diff --git a/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/VelocityPlugin.java b/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/VelocityPlugin.java index 8244b3b..fa005e5 100644 --- a/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/VelocityPlugin.java +++ b/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/VelocityPlugin.java @@ -22,8 +22,8 @@ import java.util.concurrent.TimeUnit; -@Plugin(id = "azi-plugin-messaging", name = "AziPluginMessaging", version = "4.0.0", - dependencies = @Dependency(id = "luckperms")) +@Plugin(id = "azi-plugin-messaging", name = "AziPluginMessaging", version = "4.1.0", + dependencies = {@Dependency(id = "luckperms"), @Dependency(id = "spicyazisaban")}) public class VelocityPlugin { private final ProxyServer server; diff --git a/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/entity/SimplePlayerActor.java b/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/entity/SimplePlayerActor.java new file mode 100644 index 0000000..a4dfc46 --- /dev/null +++ b/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/entity/SimplePlayerActor.java @@ -0,0 +1,63 @@ +package net.azisaba.azipluginmessaging.velocity.entity; + +import net.azisaba.spicyAzisaBan.SpicyAzisaBan; +import net.azisaba.spicyAzisaBan.common.Actor; +import net.azisaba.spicyAzisaBan.common.chat.Component; +import net.azisaba.spicyAzisaBan.struct.PlayerData; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.query.QueryOptions; +import net.luckperms.api.util.Tristate; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public record SimplePlayerActor(@NotNull String name, @NotNull UUID uuid) implements Actor { + public SimplePlayerActor(@NotNull PlayerData playerData) { + this(playerData.getName(), playerData.getUniqueId()); + } + + @Override + public @NotNull String getName() { + return name; + } + + @Override + public @NotNull UUID getUniqueId() { + return uuid; + } + + @Override + public void sendMessage(@NotNull Component component) { + Component component2 = Component.text("behalf of [" + getName() + "] [" + getUniqueId() + "]: "); + component2.addChildren(component); + SpicyAzisaBan.instance.getConsoleActor().sendMessage(component2); + } + + @Override + public void sendMessage(@NotNull Component... components) { + Component component = Component.text("behalf of [" + getName() + "] [" + getUniqueId() + "]: "); + for (Component c : components) { + component.addChildren(c); + } + SpicyAzisaBan.instance.getConsoleActor().sendMessage(component); + } + + @Override + public boolean hasPermission(@NotNull String s) { + return LuckPermsProvider.get() + .getUserManager() + .loadUser(uuid) + .join() + .getCachedData() + .permissionData() + .calculate(QueryOptions.defaultContextualOptions()) + .checkPermission(s) == Tristate.TRUE; + } + + @Override + public void sendMessage(@NotNull net.kyori.adventure.text.Component component) { + SpicyAzisaBan.instance.getConsoleActor().sendMessage( + net.kyori.adventure.text.Component.text("behalf of [" + getName() + "] [" + getUniqueId() + "]: ").append(component) + ); + } +} diff --git a/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/util/DurationUtil.java b/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/util/DurationUtil.java new file mode 100644 index 0000000..aa8e570 --- /dev/null +++ b/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/util/DurationUtil.java @@ -0,0 +1,32 @@ +package net.azisaba.azipluginmessaging.velocity.util; + +import static net.azisaba.spicyAzisaBan.util.DateTimeConstantsKt.*; + +public class DurationUtil { + public static String unProcessTime(long l) { + if (l < 0L) return "0s"; + long time = l; + int d = 0, h = 0, m = 0, s = 0; + if (time > day) { + long t = (long) Math.floor(time / (double) day); + d = (int) t; + time -= t * day; + } + if (time > hour) { + long t = (long) Math.floor(time / (double) hour); + h = (int) t; + time -= t * hour; + } + if (time > minute) { + long t = (long) Math.floor(time / (double) minute); + m = (int) t; + time -= t * minute; + } + if (time > second) { + long t = (long) Math.floor(time / (double) second); + s = (int) t; + //time -= t * second; + } + return String.format("%dd%dh%dm%ds", d, h, m, s); + } +} diff --git a/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/util/StringUtil.java b/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/util/StringUtil.java new file mode 100644 index 0000000..6a49737 --- /dev/null +++ b/velocity/src/main/java/net/azisaba/azipluginmessaging/velocity/util/StringUtil.java @@ -0,0 +1,9 @@ +package net.azisaba.azipluginmessaging.velocity.util; + +import org.jetbrains.annotations.NotNull; + +public class StringUtil { + public static @NotNull String escapeQuotes(@NotNull String str) { + return str.replace("\"", "\\\"").replace("\\", "\\\\"); + } +}