155 Commits
Author SHA1 Message Date
Len 94484593f1 progress on requests 2024-01-13 19:14:57 +01:00
Len de04c6b80a Nick and Prefix requests 2024-01-04 17:11:00 +01:00
Len 8a5b407359 update gradle 2024-01-04 09:28:53 +01:00
Len f63c4c0836 Update velocity 2023-12-17 12:39:07 +01:00
Len eb7c1dd1e1 Update to 1.20.4 2023-12-17 12:37:21 +01:00
auto 278129e8d8 Changed pinging to prevent ping for not @'d user
Allowed \ to escape ping
2023-08-14 01:29:06 +02:00
auto f1deebf49e Merge remote-tracking branch 'origin/main' 2023-08-11 22:30:34 +02:00
auto 3e29fc7d17 Added minimum hex value for nick colors 2023-08-11 22:30:23 +02:00
Len ffa90b5c94 add MENTIONPLAYERTAG to Config.java 2023-07-15 17:45:03 +02:00
Len 9d7f944c88 Fix Tagging players and triggering a replacematcher not resetting chatcolor 2023-07-15 17:42:12 +02:00
auto 4b930e62c3 Log party messages that are from a toggled user on the local server as well 2023-07-10 23:33:42 +02:00
auto c02e4dd884 Log all party messages 2023-07-10 23:15:08 +02:00
auto 8a463696ed Made chatusermanager use synchronized functions 2023-07-07 23:16:32 +02:00
auto ce5ea19961 Removed unused imports 2023-07-07 23:16:15 +02:00
auto 591ca93981 Fixed first join messages only working if chat user is not loaded yet 2023-07-07 23:15:45 +02:00
auto d7cfe97644 Added first join messages back 2023-06-26 21:40:15 +02:00
auto c86a344d49 Trying a different way to see if a player is a new player 2023-06-22 02:00:51 +02:00
auto 5583abbbca Fix party info not showing if party owner is null 2023-06-20 23:44:32 +02:00
auto 55918670bc Maybe fixed mentions 2023-06-20 00:40:44 +02:00
auto f3c7a312c0 Added first join messages 2023-06-20 00:35:46 +02:00
auto d8f064e7ca Fix spy needing mute-server permission 2023-06-20 00:09:48 +02:00
auto 9b7868bea7 Fix mentions happening within words 2023-06-17 23:58:33 +02:00
auto 6c6b798677 Fix load order 2023-04-23 22:48:33 +02:00
auto 0c1b197054 Don't send players a ping sound if they have the player that's pinging them ignored 2022-11-25 19:49:37 +01:00
Len 57afbbe805 Update permissions for nicknames 2022-10-29 10:29:26 +02:00
Len 5398d97248 Merge branch 'main' of https://github.com/Altitude-Devs/Chat 2022-10-09 20:25:52 +02:00
Len d90f5ac376 Update nicknames for Player and CMI. 2022-10-09 20:25:40 +02:00
auto 0c7ad69e85 Only replace the first instance of a name/nickname 2022-10-09 19:33:06 +02:00
auto 7ef9b4a64a Make .replace require a TextReplacementConfig 2022-10-09 19:32:51 +02:00
auto 5b06049265 Fixed double @ if someone doesn't have a nickname (or has the same nickname as the username) 2022-10-09 18:04:41 +02:00
auto ea051fd905 Fixed spacing for target replacement 2022-10-09 01:21:10 +02:00
auto 87d5c1b264 Fixed blocked messages not highlighting what was blocked 2022-10-09 01:18:13 +02:00
auto 5e62786010 Fixed case-sensitive name matching for replacing names/nicknames 2022-10-09 00:47:43 +02:00
auto 4f01c86877 @ players when they are mentioned by name or nickname (case-insensitive) 2022-10-09 00:36:50 +02:00
auto 6beb398e10 Added a way to replace text with components and patterns with strings/components 2022-10-09 00:36:07 +02:00
Len e811b0ca9a Update permissions for nickcommand. V2 2022-10-08 22:36:46 +02:00
Len 3eff30a4be Update permissions for nickcommand. 2022-10-08 11:14:58 +02:00
Len 3aa0b09133 Fix ChatFilter.java not applying to message. 2022-10-08 11:05:56 +02:00
Len 5db22461cf Fix [i] duplicating in GC 2022-10-08 10:36:06 +02:00
Len 3bdaa798c3 Continue the loop do not break it. 2022-10-03 19:39:41 +02:00
Len 7fcfb2321f Update config style 2022-10-03 19:29:25 +02:00
Len 7af91c1c94 Fix permission for emoteslist 2022-10-03 19:13:42 +02:00
Len 7de83f536b Show correct nickname in previews 2022-10-03 18:27:58 +02:00
Len 76f713409b Parse components in nicktry 2022-10-03 12:04:08 +02:00
Len ef831c48b3 Remove legacy codes in Nicknames.java 2022-10-03 11:29:06 +02:00
Len 8baa254d5e Revert "Fix replacement filers not working."
This reverts commit df4ff7f6b3.
2022-10-03 11:29:06 +02:00
Len 3d14cca551 Update minimessage tags to be lowercase 2022-10-03 11:29:06 +02:00
Len d1df551f35 Update minimessage tags to be lowercase 2022-10-03 10:30:27 +02:00
Len db8524134e update player displayname when changing Nicknames 2022-10-02 16:33:01 +02:00
Len e99626cebb Remove deprecation usages 2022-10-02 10:53:26 +02:00
auto d7bd3aa222 Switched to using minimessage (mostly) 2022-10-02 04:52:33 +02:00
auto 9407ba8bec Switched to using minimessage (mostly) 2022-10-02 03:52:02 +02:00
destro174andGitHub aab68e5e7f Merge pull request #2 from Altitude-Devs/Changes
Make use of the new 1.19 chat features + other updates
2022-10-01 20:53:49 +02:00
Len 5ec1f08fe1 Update version in plugin.yml 2022-10-01 20:46:07 +02:00
Len a4e4982dc3 Update nicknames to use Chat's plugin message channels. 2022-10-01 20:42:35 +02:00
Len 3d432a5af6 Change Nicknames.getNick to use UUID 2022-10-01 19:39:20 +02:00
Len ac994d35a1 Update version 2022-10-01 18:24:42 +02:00
Len 4b947996da Change some minor things to Nicknames 2022-10-01 15:04:08 +02:00
Len df4ff7f6b3 Fix replacement filers not working. 2022-10-01 13:32:04 +02:00
Len 2764446e41 Switch to new formatting permissions. 2022-09-30 16:48:08 +02:00
Len 5db3bc5ffe update formatting and emotes in written books. 2022-09-29 17:00:53 +02:00
Len 271500bae3 Add permission for newline 2022-09-29 16:51:03 +02:00
Len 244b2aeda2 Register Nickname events and commands 2022-09-29 16:27:49 +02:00
Len d6562826e4 Add /nick current 2022-09-29 16:26:55 +02:00
Len 6329eacd07 Fix some deprecated issues 2022-09-29 16:26:55 +02:00
Len 99cbc01106 Update buildscript 2022-09-29 16:26:55 +02:00
Len 58b80e9eaf Fork NickNameAccepted to update nickname on proxy before forwarding. 2022-09-29 16:26:55 +02:00
Len 282fdde48b Use AsyncChatDecorateEvent. 2022-09-27 09:35:10 +02:00
Len a405862fe1 Update Config.java references for Nicknames 2022-09-27 00:45:23 +02:00
Len 11ecf1ad16 Merge Nicknames 2022-09-27 00:02:27 +02:00
Len fb997ae4ed Update ChatListener.java 2022-09-27 00:02:27 +02:00
Len b0e453295b Add addAdditionalChatCompletions 2022-09-27 00:02:27 +02:00
Len 1ea2c03fcd Add nicknameString getting in ChatUser.java 2022-09-27 00:02:27 +02:00
Len 4d01ccb065 Update Config.java 2022-09-27 00:02:27 +02:00
Len a15b13e8ac Add Nick.java 2022-09-27 00:02:27 +02:00
Len 00f4e00011 Add Pair.java 2022-09-27 00:02:27 +02:00
Len 3888298827 Add Emote to FilterType.java
Add EmoteList command.
2022-09-27 00:02:27 +02:00
Len 643fb5a633 Fix mail output message not showing recipient name. 2022-09-26 19:08:51 +02:00
Len 3ca854e507 Remove GitHub workflows 2022-09-26 19:08:51 +02:00
Len 1eb4d619d6 Remove plugin script 2022-09-26 19:08:51 +02:00
Len 9d7f50ad37 Update to apache commons lang3 2022-09-26 19:08:51 +02:00
Len d644dbef6e Add runserver task 2022-09-26 19:08:51 +02:00
Len 425c06af33 Update build scripts 2022-09-26 19:08:51 +02:00
Len fb3358e2ea Remove unused command 2022-09-26 19:08:51 +02:00
Len ee2a2c2225 Use 1.19.2 API 2022-09-26 19:08:51 +02:00
auto 341a330e3d Removed sout for adding party users 2022-09-22 23:53:09 +02:00
auto 0339458c66 Added logging for chat messages 2022-09-22 23:52:46 +02:00
Stijn d3be713c9a Added optional sender argument to /mail list <username> 2022-09-21 18:26:16 +02:00
Len 6e41a81ed1 Do not shade minimessage in velocity module 2022-09-19 18:27:19 +02:00
Stijn ce1ec164ef added confirmation message to mail send 2022-09-19 18:10:15 +02:00
auto 9832abbb90 Fixed only sending to ignored players 2022-06-25 06:10:17 +02:00
Stijn 66a058225d Fixed chat not sending messages by bypassing Microsoft's chat report system 2022-06-24 21:11:54 +02:00
auto 35ad214901 Fixed regex injection 2022-06-02 05:09:43 +02:00
auto 32e38ef32b spot the bug 2022-06-02 04:57:04 +02:00
auto b1f2370bec Added continue, fixed mail 2022-06-02 03:48:51 +02:00
auto 20c7f0a6d9 ez tmp fix for sendername receivername not being replaced properly 2022-05-30 23:59:54 +02:00
auto 40a6e6bcc9 Fixed colors not working in chat 2022-05-30 22:10:54 +02:00
auto 7ab95e437a Fixed bypass spam limits by spamming more than one character 2022-05-30 19:58:00 +02:00
auto 4068ad8ea6 Fixed message for toggling chat channel
Fixed stack overflow for untoggling chat channels
2022-05-30 19:43:31 +02:00
auto 82eecc3142 Colored toggle word, improved default party online/offline marker 2022-05-30 19:27:47 +02:00
auto 679602c1f7 Registered SilentJoinCommand 2022-05-30 19:19:41 +02:00
Len 8c3d03383d build using velocity 3.1.2-SNAPSHOT 2022-05-30 18:47:29 +02:00
Stijn fe64fb3785 Added the string that was filtered to the logs 2022-05-27 17:52:34 +02:00
Len c836452d19 Update minimessage references 2022-05-27 00:31:36 +02:00
auto 0997c2bab6 Disable toggles on join 2022-05-24 04:20:21 +02:00
auto e39bab34fd Moved class to more logical place 2022-05-24 04:18:34 +02:00
auto 41897f4b16 Added toggle to party as well and made it so it can be added to other channels if needed 2022-05-24 04:17:55 +02:00
auto 60e1ad2220 Added a way to toggle custom channels 2022-05-24 03:06:34 +02:00
auto c645201ef3 Removed variable, moved call inline 2022-05-24 02:50:18 +02:00
auto fdd9d81400 Fix party users not being removed correctly (they left the party but still had their party id set) 2022-05-24 02:49:36 +02:00
auto 3e313cb00b Fixed being able to bypass replacement filters by having multiple of the same match in one string 2022-05-24 02:41:11 +02:00
auto dac0f7936e Use util to parse message 2022-05-24 02:06:28 +02:00
Stijn 408d38fb78 Added silent join 2022-05-23 22:32:43 +02:00
Stijn faa0435131 Require reports to be at least 3 words long 2022-05-23 22:06:17 +02:00
Stijn 1946cd4ab7 Added online indicators for party info 2022-05-23 21:55:36 +02:00
destro174 29dd5d2d55 Commit reply/continue rework 2022-04-21 15:45:50 +02:00
auto 0a6dfe799e Properly handle filtered messages in party chat 2022-03-15 00:20:07 +01:00
destro174 e6dfd19b84 Merge branch 4.9 2022-03-14 16:48:35 +01:00
destro174 42585c97cf fix invalid urls in chat 2022-02-19 15:34:16 +01:00
destro174 342957ef68 Fix build! 2022-02-19 15:14:41 +01:00
destro174 ab852cf55e add minimessage snapshots repo 2022-02-17 09:32:02 +01:00
destro174 ef94169f04 Add gradle-wrapper to gitignore 2022-02-17 09:01:36 +01:00
destro174 5042d62247 Add gh actions 2022-02-17 08:58:12 +01:00
destro174 fe022a02fe null check in parsecolors 2022-02-17 08:32:27 +01:00
auto fbbe0d6ef3 Maybe added proxydiscordlink and added report command 2022-02-15 16:37:47 +01:00
auto 647ad2b62a Added party leave notif 2022-02-15 03:20:05 +01:00
auto 59781f486d Added confirmation message to mail sent 2022-02-15 03:07:56 +01:00
auto fa79491088 Maybe made nicknames auto sync 2022-02-15 02:57:50 +01:00
auto e6e1073958 Fixed party notifs and spy 2022-02-15 02:32:38 +01:00
auto 2b77607072 Maybe fixed party 2022-02-14 01:25:51 +01:00
auto 777415f97e Grammar in config message 2022-02-08 00:39:07 +01:00
auto bc010bea6e Notify players that chat was cleared 2022-02-07 00:22:33 +01:00
auto 8628dacd10 Fixed storing sender as receiver and receiver as sender 2022-02-06 18:07:16 +01:00
auto 3d42fb8bbf Added bypass perm and confirmation message 2022-02-06 03:39:53 +01:00
auto 08a695f2ac Added chatclear command 2022-02-06 03:31:07 +01:00
auto 2c0637b1d1 Parse / strip chat color tokens based on if the commandSender has permission for chat colors 2022-02-06 03:13:51 +01:00
destro174 e08c5a4a3b Update minimessage to 4.10.0 2022-02-05 21:16:20 +01:00
destro174 f00f6e7658 fix url in global admin chat 2022-02-05 10:17:49 +01:00
auto a5d5d8d985 Tweaked mails, added notifs, added config options 2022-02-05 02:45:38 +01:00
auto c18ffb9578 Added missing config messages 2022-01-31 03:15:58 +01:00
auto 79501c619a Check if a user has permission to see tab complete suggestions 2022-01-31 03:15:43 +01:00
auto 0c8a4a97d3 Added party disband command and a way to remove all users from a party 2022-01-31 03:06:52 +01:00
auto 032d0e2bef Added party chat help message 2022-01-31 02:54:23 +01:00
auto 8d0ed326b5 Changed api version 2022-01-30 21:54:01 +01:00
auto d40c3a45ed Removed todo 2022-01-30 20:23:45 +01:00
auto 040c8cfa96 Removed old chatparty command 2022-01-30 20:23:23 +01:00
auto 787927672a Added messages for commands that had no output 2022-01-30 20:20:42 +01:00
auto aed1885a59 Added logout notif 2022-01-30 20:13:38 +01:00
auto 43a2be1b1b Notify players if their party member joins 2022-01-30 20:11:25 +01:00
auto fd58617e44 Edited templates for spy/party format 2022-01-30 19:52:53 +01:00
auto 6360d74b30 Added more config messages 2022-01-30 19:50:33 +01:00
auto a0a60757f6 Check if a user is already in a party before letting them make another party 2022-01-30 19:50:22 +01:00
auto 89938338b1 Configure party invite messages 2022-01-30 19:50:06 +01:00
auto f8ede610b2 Parse commands before putting them in template 2022-01-30 19:49:53 +01:00
TeriuihiandGitHub 70d26a2255 Merge pull request #1 from Altitude-Devs/party
Party
2022-01-30 20:32:21 +01:00
79 changed files with 3439 additions and 635 deletions
-18
View File
@@ -1,18 +0,0 @@
name: Build
on: [ push, pull_request ]
jobs:
build:
runs-on: ubuntu-latest
if: "!contains(github.event.commits[0].message, '[ci-skip]')"
steps:
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v2
with:
distribution: temurin
java-version: 17
- name: Configure Git
run: git config --global user.email "[email protected]" && git config --global user.name "Github Actions"
- name: Build
run: ./gradlew build --stacktrace
+2 -7
View File
@@ -3,16 +3,11 @@ plugins {
}
dependencies {
compileOnly("com.alttd:Galaxy-API:1.18.1-R0.1-SNAPSHOT") {
exclude("net.kyori.adventure.text.minimessag")
}
compileOnly("net.kyori", "adventure-text-minimessage", "4.10.0-20220122.015731-43") { // Minimessage
exclude("net.kyori")
exclude("net.kyori.examination")
compileOnly("com.alttd:Galaxy-API:1.19.2-R0.1-SNAPSHOT") {
// exclude("net.kyori")
}
compileOnly("org.spongepowered:configurate-yaml:4.1.2") // Configurate
compileOnly("net.luckperms:api:5.3") // Luckperms
compileOnly(files("../libs/minimessage-4.10.0-SNAPSHOT.jar")) // Workaround for minimessage
}
publishing {
@@ -1,13 +1,15 @@
package com.alttd.chat.config;
import com.alttd.chat.objects.channels.CustomChannel;
import com.google.common.base.Throwables;
import com.alttd.chat.util.Utility;
import com.google.common.collect.Lists;
import io.leangen.geantyref.TypeToken;
import net.kyori.adventure.text.Component;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.ConfigurationOptions;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.yaml.NodeStyle;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import java.io.File;
import java.io.IOException;
@@ -16,8 +18,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.regex.Pattern;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import org.spongepowered.configurate.ConfigurationOptions;
public final class Config {
private static final Pattern PATH_PATTERN = Pattern.compile("\\.");
@@ -78,7 +78,7 @@ public final class Config {
method.setAccessible(true);
method.invoke(instance);
} catch (InvocationTargetException | IllegalAccessException ex) {
throw Throwables.propagate(ex.getCause());
ex.printStackTrace();
}
}
}
@@ -86,7 +86,7 @@ public final class Config {
try {
configLoader.save(config);
} catch (IOException ex) {
throw Throwables.propagate(ex.getCause());
ex.printStackTrace();
}
}
@@ -94,7 +94,7 @@ public final class Config {
try {
configLoader.save(config);
} catch (IOException ex) {
throw Throwables.propagate(ex.getCause());
ex.printStackTrace();
}
}
@@ -107,6 +107,7 @@ public final class Config {
try {
config.node(splitPath(path)).set(def);
} catch (SerializationException e) {
e.printStackTrace();
}
}
}
@@ -116,6 +117,7 @@ public final class Config {
if(config.node(splitPath(path)).virtual())
config.node(splitPath(path)).set(io.leangen.geantyref.TypeToken.get(String.class), def);
} catch(SerializationException ex) {
ex.printStackTrace();
}
}
@@ -149,6 +151,7 @@ public final class Config {
set(path, def);
return config.node(splitPath(path)).getList(TypeToken.get(String.class));
} catch(SerializationException ex) {
ex.printStackTrace();
}
return new ArrayList<>();
}
@@ -168,6 +171,8 @@ public final class Config {
public static String MINIMIUMSTAFFRANK = "trainee";
public static String CONSOLENAME = "Console";
public static UUID CONSOLEUUID = UUID.randomUUID();
public static int EMOTELIMIT = 3;
public static String MENTIONPLAYERTAG = "<aqua>@</aqua>";
private static void settings() {
PREFIXGROUPS = getList("settings.prefix-groups",
Lists.newArrayList("discord", "socialmedia", "eventteam", "eventleader", "youtube", "twitch", "developer"));
@@ -178,6 +183,8 @@ public final class Config {
CONSOLENAME = getString("settings.console-name", CONSOLENAME);
CONSOLEUUID = UUID.fromString(getString("settings.console-uuid", CONSOLEUUID.toString()));
MINIMIUMSTAFFRANK = getString("settings.minimum-staff-rank", MINIMIUMSTAFFRANK);
EMOTELIMIT = getInt("settings.emote-limit", EMOTELIMIT);
MENTIONPLAYERTAG = getString("settings.mention-player-tag", MENTIONPLAYERTAG);
}
public static List<String> MESSAGECOMMANDALIASES = new ArrayList<>();
@@ -290,6 +297,9 @@ public final class Config {
Password: <dark_aqua><password></dark_aqua>
Owner: <owner>
Members: <members>""";
public static Component ONLINE_PREFIX = null;
public static Component OFFLINE_PREFIX = null;
public static String PARTY_TOGGLED = "<dark_aqua>Party chat toggled <status>.</dark_aqua>";
private static void party() {
PARTY_FORMAT = getString("party.format", PARTY_FORMAT);
PARTY_SPY = getString("party.spy", PARTY_SPY);
@@ -321,6 +331,9 @@ public final class Config {
DISBANDED_PARTY = getString("party.messages.disbanded-party", DISBANDED_PARTY);
PARTY_INFO = getString("party.messages.party-info", PARTY_INFO);
ALREADY_IN_THIS_PARTY = getString("party.messages.already-in-this-party", ALREADY_IN_THIS_PARTY);
ONLINE_PREFIX = Utility.parseMiniMessage(getString("party.messages.online-prefix", "<green>■</green>"));
OFFLINE_PREFIX = Utility.parseMiniMessage(getString("party.messages.offline-prefix", "<red>■</red>"));
PARTY_TOGGLED = getString("party.messages.party-toggled", PARTY_TOGGLED);
}
public static String PARTY_HELP_WRAPPER = "<gold>ChatParty help:\n<commands></gold>";
@@ -352,6 +365,9 @@ public final class Config {
PARTY_HELP_CHAT = getString("party.help.chat", PARTY_HELP_CHAT);
}
public static String CUSTOM_CHANNEL_TOGGLED = "<yellow>Toggled <channel> <status>.</yellow>";
public static Component TOGGLED_ON = null;
public static Component TOGGLED_OFF = null;
private static void chatChannels() {
ConfigurationNode node = getNode("chat-channels");
if (node.empty()) {
@@ -369,13 +385,17 @@ public final class Config {
getList(key + "servers", Collections.EMPTY_LIST),
getBoolean(key + "proxy", false));
}
CUSTOM_CHANNEL_TOGGLED = getString("chat-channels-messages.channel-toggled", CUSTOM_CHANNEL_TOGGLED);
TOGGLED_ON = Utility.parseMiniMessage(getString("chat-channels-messages.channel-on", "<green>on</green><gray>"));
TOGGLED_OFF = Utility.parseMiniMessage(getString("chat-channels-messages.channel-off", "<red>off</red><gray>"));
}
public static String SERVERMUTEPERMISSION = "chat.command.mute-server";
public static String SPYPERMISSION = "chat.socialspy";
private static void permissions() {
SERVERMUTEPERMISSION = getString("permissions.server-mute", SERVERMUTEPERMISSION);
SPYPERMISSION = getString("permissions.server-mute", SPYPERMISSION);
SPYPERMISSION = getString("permissions.spy-permission", SPYPERMISSION);
}
public static String IP = "0.0.0.0";
@@ -416,6 +436,7 @@ public final class Config {
public static HashMap<String, Long> serverChannelId = new HashMap<>();
public static String REPORT_SENT = "<green>Your report was sent, staff will contact you asap to help resolve your issue!</green>";
public static String REPORT_TOO_SHORT = "<red>Please ensure your report is descriptive. We require at least 3 words per report</red>";
private static void loadChannelIds() {
serverChannelId.clear();
serverChannelId.put("general", getLong("discord-channel-id.general", (long) -1));
@@ -430,10 +451,96 @@ public final class Config {
serverChannelId.put(key.toLowerCase(), channelId);
}
REPORT_SENT = getString("messages.report-sent", REPORT_SENT);
REPORT_TOO_SHORT = getString("messages.report-too-short", REPORT_TOO_SHORT);
}
public static List<String> SILENT_JOIN_COMMAND_ALIASES = new ArrayList<>();
public static String SILENT_JOIN_NO_SERVER = "<red>Unable to find destination server</red>";
public static String SILENT_JOIN_JOINING = "<green>Sending you to <server> silently.</green>";
public static String SILENT_JOIN_JOINED_FROM = "<gold>* <player> silent joined from <from_server>...</gold>";
public static String SILENT_JOIN_JOINED = "<gold>* <player> silent joined...</gold>";
private static void silentJoinCommand() {
SILENT_JOIN_COMMAND_ALIASES = getList("commands.silent-join.aliases", Lists.newArrayList("sj"));
SILENT_JOIN_NO_SERVER = getString("commands.silent-join.no-server", SILENT_JOIN_NO_SERVER);
SILENT_JOIN_JOINING = getString("commands.silent-join.joining", SILENT_JOIN_JOINING);
SILENT_JOIN_JOINED_FROM = getString("commands.silent-join.joined-from", SILENT_JOIN_JOINED_FROM);
SILENT_JOIN_JOINED = getString("commands.silent-join.joined", SILENT_JOIN_JOINED);
}
public static String HELP_REPORT = "<red>/report <message></red>";
public static String FIRST_JOIN = "<green>* Welcome <light_purple><player></light_purple> to Altitude! They've joined for the first time.</green>";
private static void loadMessages() {
HELP_REPORT = getString("settings.mail.mail-sent", HELP_REPORT);
FIRST_JOIN = getString("settings.first-join.message", FIRST_JOIN);
}
public static String EMOTELIST_HEADER = "<bold>Available Chat Emotes</bold><newline>";
public static String EMOTELIST_ITEM = "<insert:\"<regex>\"><gold><regex></gold> : <emote></insert><newline>";
public static String EMOTELIST_FOOTER = "<green>----<< <gray>Prev</gray> <page> <gray>/</gray> <pages> <gray>Next</gray> >>----";
private static void emoteListCommand() {
EMOTELIST_HEADER = getString("commands.emotelist.header", EMOTELIST_HEADER);
EMOTELIST_ITEM = getString("commands.emotelist.item", EMOTELIST_ITEM);
EMOTELIST_FOOTER = getString("commands.emotelist.footer", EMOTELIST_FOOTER);
}
// nicknames TODO minimessage for colors and placeholders
public static String NICK_CHANGED = "<yellow>Your nickname was changed to <nickname><yellow>.";
public static String NICK_NOT_CHANGED = "<yellow>Your nickname request was denied.";
public static String NICK_RESET = "<yellow>Nickname changed back to normal.";
public static String NICK_CHANGED_OTHERS = "<gold><targetplayer><yellow>'s nickname was changed to <nickname><yellow>.";
public static String NICK_TARGET_NICK_CHANGE = "<yellow>Your nickname was changed to <nickname> <yellow>by <sendernick><yellow>";
public static String NICK_RESET_OTHERS = "<gold><player><gold>'s <yellow>nickname was reset back to normal.";
public static String NICK_INVALID_CHARACTERS = "<yellow>You can only use letters and numbers in nicknames.";
public static String NICK_INVALID_LENGTH = "<yellow>Nicknames need to be between 3 to 16 characters long.";
public static String NICK_PLAYER_NOT_ONLINE = "<red>That player is not online.";
public static String NICK_BLOCKED_COLOR_CODES = "<yellow>You have blocked color codes in that nickname.";
public static String NICK_USER_NOT_FOUND = "<red>Failed to set nickname from player, try again from a server this player has been on before.";
public static String NICK_ACCEPTED = "<green>You accepted <targetplayer><green>'s nickname. They are now called <newnick><green>.";
public static String NICK_DENIED = "<green>You denied <targetplayer><green>'s nickname. They are still called <oldnick><green>.";
public static String NICK_ALREADY_HANDLED = "<red><targetplayer><red>'s nickname was already accepted or denied.";
public static String NICK_NO_LUCKPERMS = "<red>Due to an issue with LuckPerms /nick try won't work at the moment.";
public static String NICK_TOO_SOON = "<red>Please wait <time><red> until requesting a new nickname";
public static String NICK_REQUEST_PLACED = "<green>Replaced your previous request <oldrequestednick><green> with <newrequestednick><green>.";
public static String NICK_REQUEST_NEW = "<green>New nickname request by <player><green>!";
public static String NICK_TRYOUT = "<white><prefix><white> <nick><gray>: <white>Hi, this is what my new nickname could look like!";
public static String NICK_REQUESTED = "<green>Your requested to be nicknamed <nick><green> has been received. Staff will accept or deny this request asap!";
public static String NICK_REVIEW_WAITING = "<green>There are <amount> nicknames waiting for review!";
public static String NICK_TAKEN = "<red>Someone else already has this nickname, or has this name as their username.";
public static String NICK_REQUESTS_ON_LOGIN = "<green>Current nick requests: <amount>";
public static long NICK_WAIT_TIME = 86400000;
public static List<String> NICK_ITEM_LORE = new ArrayList<>();
public static List<String> NICK_BLOCKED_COLOR_CODESLIST = new ArrayList<>();
public static List<String> NICK_ALLOWED_COLOR_CODESLIST = new ArrayList<>();
public static String NICK_CURRENT = "<gold>Current nickname: <nickname><white>(<insert:\"<currentnickname>\"><currentnickname></insert>)";
private static void nicknameSettings() {
NICK_CHANGED = getString("nicknames.messages.nick-changed", NICK_CHANGED);
NICK_NOT_CHANGED = getString("nicknames.messages.nick-not-changed", NICK_NOT_CHANGED);
NICK_RESET = getString("nicknames.messages.nick-reset", NICK_RESET);
NICK_CHANGED_OTHERS = getString("nicknames.messages.nick-changed-others", NICK_CHANGED_OTHERS);
NICK_TARGET_NICK_CHANGE = getString("nicknames.messages.nick-target-nick-change", NICK_TARGET_NICK_CHANGE);
NICK_RESET_OTHERS = getString("nicknames.messages.nick-reset-others", NICK_RESET_OTHERS);
NICK_INVALID_CHARACTERS = getString("nicknames.messages.nick-invalid-characters", NICK_INVALID_CHARACTERS);
NICK_INVALID_LENGTH = getString("nicknames.messages.nick-invalid-length", NICK_INVALID_LENGTH);
NICK_PLAYER_NOT_ONLINE = getString("nicknames.messages.nick-player-not-online", NICK_PLAYER_NOT_ONLINE);
NICK_BLOCKED_COLOR_CODES = getString("nicknames.messages.nick-blocked-color-codes", NICK_BLOCKED_COLOR_CODES);
NICK_USER_NOT_FOUND = getString("nicknames.messages.nick-user-not-found", NICK_USER_NOT_FOUND);
NICK_ACCEPTED = getString("nicknames.messages.nick-accepted", NICK_ACCEPTED);
NICK_DENIED = getString("nicknames.messages.nick-denied", NICK_DENIED);
NICK_ALREADY_HANDLED = getString("nicknames.messages.nick-already-handled", NICK_ALREADY_HANDLED);
NICK_NO_LUCKPERMS = getString("nicknames.messages.nick-no-luckperms", NICK_NO_LUCKPERMS);
NICK_TOO_SOON = getString("nicknames.messages.nick-too-soon", NICK_TOO_SOON);
NICK_REQUEST_PLACED = getString("nicknames.messages.nick-request-placed", NICK_REQUEST_PLACED);
NICK_REQUEST_NEW = getString("nicknames.messages.nick-request-new", NICK_REQUEST_NEW);
NICK_TRYOUT = getString("nicknames.messages.nick-tryout", NICK_TRYOUT);
NICK_REQUESTED = getString("nicknames.messages.nick-requested", NICK_REQUESTED);
NICK_REVIEW_WAITING = getString("nicknames.messages.nick-review-waiting", NICK_REVIEW_WAITING);
NICK_TAKEN = getString("nicknames.messages.nick-taken", NICK_TAKEN);
NICK_REQUESTS_ON_LOGIN = getString("nicknames.messages.nick-reauests-on-login", NICK_REQUESTS_ON_LOGIN);
NICK_WAIT_TIME = getLong("nicknames.wait-time", NICK_WAIT_TIME);
NICK_ITEM_LORE = getList("nicknames.item-lore", List.of("<aqua>New nick: <newnick>", "<aqua>Old nick: <oldnick>", "<aqua>Last changed: <lastchanged>", "<green>Left click to Accept <light_purple>| <red>Right click to Deny"));
NICK_BLOCKED_COLOR_CODESLIST = getList("nicknames.blocked-color-codes", List.of("&k", "&l", "&n", "&m", "&o"));
NICK_ALLOWED_COLOR_CODESLIST = getList("nicknames.allowed-color-codes", List.of("&0", "&1", "&2", "&3", "&4", "&5", "&6", "&7", "&8", "&9", "&a", "&b", "&c", "&d", "&e", "&f", "&r"));
NICK_CURRENT = getString("nicknames.messages.nick-current", NICK_CURRENT);
}
}
@@ -41,7 +41,7 @@ public final class PrefixConfig {
CONFIG_FILE = new File(Config.CONFIGPATH, "prefix.yml");
configLoader = YamlConfigurationLoader.builder()
.file(CONFIG_FILE)
.nodeStyle(NodeStyle.FLOW)
.nodeStyle(NodeStyle.BLOCK)
.build();
if (!CONFIG_FILE.getParentFile().exists()) {
if(!CONFIG_FILE.getParentFile().mkdirs()) {
@@ -80,7 +80,7 @@ public final class PrefixConfig {
method.setAccessible(true);
method.invoke(instance);
} catch (InvocationTargetException | IllegalAccessException ex) {
throw Throwables.propagate(ex.getCause());
ex.printStackTrace();
}
}
}
@@ -88,7 +88,7 @@ public final class PrefixConfig {
try {
configLoader.save(config);
} catch (IOException ex) {
throw Throwables.propagate(ex.getCause());
ex.printStackTrace();
}
}
@@ -96,7 +96,7 @@ public final class PrefixConfig {
try {
configLoader.save(config);
} catch (IOException ex) {
throw Throwables.propagate(ex.getCause());
ex.printStackTrace();
}
}
@@ -109,6 +109,7 @@ public final class PrefixConfig {
try {
config.node(splitPath(path)).set(def);
} catch (SerializationException e) {
e.printStackTrace();
}
}
}
@@ -118,6 +119,7 @@ public final class PrefixConfig {
if(config.node(splitPath(path)).virtual())
config.node(splitPath(path)).set(io.leangen.geantyref.TypeToken.get(String.class), def);
} catch(SerializationException ex) {
ex.printStackTrace();
}
}
@@ -3,14 +3,12 @@ package com.alttd.chat.config;
import com.alttd.chat.managers.RegexManager;
import com.alttd.chat.objects.ChatFilter;
import com.alttd.chat.util.ALogger;
import com.google.common.base.Throwables;
import io.leangen.geantyref.TypeToken;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.ConfigurationOptions;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.yaml.NodeStyle;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import org.yaml.snakeyaml.DumperOptions;
import java.io.File;
import java.io.IOException;
@@ -38,7 +36,7 @@ public final class RegexConfig {
CONFIG_FILE = new File(Config.CONFIGPATH, "filters.yml");
configLoader = YamlConfigurationLoader.builder()
.file(CONFIG_FILE)
.nodeStyle(NodeStyle.FLOW)
.nodeStyle(NodeStyle.BLOCK)
.build();
if (!CONFIG_FILE.getParentFile().exists()) {
@@ -78,7 +76,7 @@ public final class RegexConfig {
method.setAccessible(true);
method.invoke(instance);
} catch (InvocationTargetException | IllegalAccessException ex) {
throw Throwables.propagate(ex.getCause());
ex.printStackTrace();
}
}
}
@@ -86,7 +84,7 @@ public final class RegexConfig {
try {
configLoader.save(config);
} catch (IOException ex) {
throw Throwables.propagate(ex.getCause());
ex.printStackTrace();
}
}
@@ -74,9 +74,11 @@ public final class ServerConfig {
public boolean GLOBALCHAT = false;
public boolean JOINLEAVEMSSAGES = true;
public boolean MUTED = false;
public boolean FIRST_JOIN_MESSAGES = false;
private void ServerSettings() {
GLOBALCHAT = getBoolean("global-chat-enabled", GLOBALCHAT);
JOINLEAVEMSSAGES = getBoolean("joinleave-messages-enabled", JOINLEAVEMSSAGES);
MUTED = getBoolean("server-muted", MUTED);
FIRST_JOIN_MESSAGES = getBoolean("first-join-messages", FIRST_JOIN_MESSAGES);
}
}
@@ -1,18 +1,13 @@
package com.alttd.chat.database;
import com.alttd.chat.managers.PartyManager;
import com.alttd.chat.objects.ChatUser;
import com.alttd.chat.objects.Mail;
import com.alttd.chat.objects.Party;
import com.alttd.chat.objects.PartyUser;
import com.alttd.chat.objects.*;
import com.alttd.chat.objects.channels.Channel;
import com.alttd.chat.util.ALogger;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.Date;
public class Queries {
@@ -24,7 +19,8 @@ public class Queries {
tables.add("CREATE TABLE IF NOT EXISTS parties (`id` INT NOT NULL AUTO_INCREMENT, `owner_uuid` VARCHAR(36) NOT NULL, `party_name` VARCHAR(36) NOT NULL, `password` VARCHAR(36), PRIMARY KEY (`id`))");
tables.add("CREATE TABLE IF NOT EXISTS chat_users (`uuid` VARCHAR(36) NOT NULL, `party_id` INT NOT NULL, `toggled_channel` VARCHAR(36) NULL DEFAULT NULL, PRIMARY KEY (`uuid`))");
tables.add("CREATE TABLE IF NOT EXISTS mails (`id` INT NOT NULL AUTO_INCREMENT, `uuid` VARCHAR(36) NOT NULL, `sender` VARCHAR(36) NOT NULL, `message` VARCHAR(256) NOT NULL, `sendtime` BIGINT default 0, `readtime` BIGINT default 0, PRIMARY KEY (`id`))");
createNicknamesTable();
createRequestedNicknamesTable();
try {
Connection connection = DatabaseConnection.getConnection();
@@ -39,6 +35,51 @@ public class Queries {
//-----------------------------------------
//Nicknames
private static void createNicknamesTable() {
try {
String nicknamesTableQuery = "CREATE TABLE IF NOT EXISTS nicknames("
+ "uuid VARCHAR(48) NOT NULL,"
+ "PRIMARY KEY (uuid))";
DatabaseConnection.getConnection().prepareStatement(nicknamesTableQuery).executeUpdate();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
List<String> columns = new ArrayList<>();
columns.add("ALTER TABLE nicknames ADD nickname VARCHAR(192)");
columns.add("ALTER TABLE nicknames ADD date_changed BIGINT default 0");
for (String string : columns) {
try {
DatabaseConnection.getConnection().prepareStatement(string).executeUpdate();
} catch (Throwable ignored) {
}
}
}
private static void createRequestedNicknamesTable() {
try {
String requestedNicknamesTableQuery = "CREATE TABLE IF NOT EXISTS requested_nicknames("
+ "uuid VARCHAR(48) NOT NULL,"
+ "PRIMARY KEY (uuid))";
DatabaseConnection.getConnection().prepareStatement(requestedNicknamesTableQuery).executeUpdate();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
List<String> columns = new ArrayList<>();
columns.add("ALTER TABLE requested_nicknames ADD nickname VARCHAR(192)");
columns.add("ALTER TABLE requested_nicknames ADD date_requested BIGINT default 0");
for (String string : columns) {
try {
DatabaseConnection.getConnection().prepareStatement(string).executeUpdate();
} catch (Throwable ignored) {
}
}
}
public static String getNickname(UUID uuid) {
// View has been created.
@@ -564,4 +605,172 @@ public class Queries {
e.printStackTrace();
}
}
// Nicknames
public static void setNicknameInDatabase(final UUID uuid, final String nickName) {
final String sql = "INSERT INTO nicknames (uuid, nickname, date_changed) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE nickname = ?";
try (final PreparedStatement statement = DatabaseConnection.getConnection().prepareStatement(sql)) {
statement.setString(1, uuid.toString());
statement.setString(2, nickName);
statement.setLong(3, new java.util.Date().getTime());
statement.setString(4, nickName);
statement.execute();
}
catch (SQLException e) {
e.printStackTrace();
}
}
public static void removePlayerFromDataBase(final UUID uuid) throws SQLException {
final PreparedStatement insert = DatabaseConnection.getConnection().prepareStatement("DELETE FROM nicknames WHERE uuid = ?");
insert.setString(1, uuid.toString());
insert.executeUpdate();
insert.close();
}
public static ArrayList<Nick> getNicknamesList() {
ArrayList<Nick> nickList = new ArrayList<>();
String queryNicknames = "SELECT uuid, nickname, date_changed FROM nicknames ";
String queryRequests = "SELECT `requested_nicknames`.`nickname` AS new_nick, `requested_nicknames`.`date_requested`, " +
"`nicknames`.`nickname` AS old_nick, `nicknames`.`date_changed`, `requested_nicknames`.`uuid` " +
"FROM `requested_nicknames`" +
"LEFT JOIN `nicknames` ON `requested_nicknames`.`uuid` = `nicknames`.`uuid` ";
try {
ResultSet resultSetNicknames = getStringResult(queryNicknames);
while (resultSetNicknames.next()){
nickList.add(new Nick(
UUID.fromString(resultSetNicknames.getString("uuid")),
resultSetNicknames.getString("nickname"),
resultSetNicknames.getLong("date_changed")));
}
ResultSet resultSetRequests = getStringResult(queryRequests);
while (resultSetRequests.next()){
nickList.add(new Nick(
UUID.fromString(resultSetRequests.getString("uuid")),
resultSetRequests.getString("old_nick"),
resultSetRequests.getLong("date_changed"),
resultSetRequests.getString("new_nick"),
resultSetRequests.getLong("date_requested")));
}
} catch (SQLException e) {
ALogger.warn("Failed to get nicknames list\n" + Arrays.toString(e.getStackTrace())
.replace(",", "\n"));
}
return nickList;
}
public static Nick getNick(UUID uniqueId) {
String getNick = "SELECT nickname, date_changed, uuid FROM nicknames WHERE uuid = ?";
String getRequest = "SELECT nickname, date_requested, uuid FROM requested_nicknames WHERE uuid = ?";
try {
ResultSet resultSetNick = getStringResult(getNick, uniqueId.toString());
ResultSet resultSetRequest = getStringResult(getRequest, uniqueId.toString());
String uuid = null;
String currentNick = null;
long dateChanged = 0;
String requestedNick = null;
long dateRequested = 0;
if (resultSetNick.next()) {
uuid = resultSetNick.getString("uuid");
currentNick = resultSetNick.getString("nickname");
dateChanged = resultSetNick.getLong("date_changed");
}
if (resultSetRequest.next()) {
uuid = resultSetRequest.getString("uuid");
requestedNick = resultSetRequest.getString("nickname");
dateRequested = resultSetRequest.getLong("date_requested");
}
if (uuid != null) {
return new Nick(UUID.fromString(uuid), currentNick, dateChanged, requestedNick, dateRequested);
}
} catch (SQLException e){
ALogger.warn("Failed to get nicknames for "
+ uniqueId.toString() + "\n" + Arrays.toString(e.getStackTrace())
.replace(",", "\n"));
}
return null;
}
public static void denyNewNickname(UUID uniqueId) {
String query = "DELETE FROM requested_nicknames WHERE uuid = ?";
try {
PreparedStatement statement = DatabaseConnection.getConnection().prepareStatement(query);
statement.setString(1, uniqueId.toString());
statement.execute();
} catch (SQLException e) {
ALogger.warn("Failed to delete requested nickname for "
+ uniqueId.toString() + "\n" + Arrays.toString(e.getStackTrace())
.replace(",", "\n"));
}
}
public static void acceptNewNickname(UUID uniqueId, String newNick){
String delete = "DELETE FROM requested_nicknames WHERE uuid = ?";
String update = "INSERT INTO nicknames (uuid, nickname, date_changed) VALUES (?, ?, ?) " +
"ON DUPLICATE KEY UPDATE nickname = ?, date_changed = ?";
long time = new java.util.Date().getTime();
try {
PreparedStatement deleteStatement = DatabaseConnection.getConnection().prepareStatement(delete);
deleteStatement.setString(1, uniqueId.toString());
deleteStatement.execute();
PreparedStatement updateStatement = DatabaseConnection.getConnection().prepareStatement(update);
updateStatement.setString(1, uniqueId.toString());
updateStatement.setString(2, newNick);
updateStatement.setLong(3, time);
updateStatement.setString(4, newNick);
updateStatement.setLong(5, time);
updateStatement.execute();
} catch (SQLException e) {
ALogger.warn("Failed to accept requested nickname for "
+ uniqueId.toString() + "\n" + Arrays.toString(e.getStackTrace())
.replace(",", "\n"));
}
}
public static void newNicknameRequest(UUID uniqueId, String nickName) {
String requestQuery = "INSERT INTO requested_nicknames (uuid, nickname, date_requested) VALUES (?, ?, ?) " +
"ON DUPLICATE KEY UPDATE nickname = ?, date_requested = ?";
String nickQuery = "INSERT INTO nicknames (uuid, nickname, date_changed) VALUES (?, ?, 0) " +
"ON DUPLICATE KEY UPDATE uuid = uuid";
long time = new Date().getTime();
try {
PreparedStatement requestPreparedStatement = DatabaseConnection.getConnection().prepareStatement(requestQuery);
requestPreparedStatement.setString(1, uniqueId.toString());
requestPreparedStatement.setString(2, nickName);
requestPreparedStatement.setLong(3, time);
requestPreparedStatement.setString(4, nickName);
requestPreparedStatement.setLong(5, time);
requestPreparedStatement.execute();
PreparedStatement nickPreparedStatement = DatabaseConnection.getConnection().prepareStatement(nickQuery);
nickPreparedStatement.setString(1, uniqueId.toString());
nickPreparedStatement.setString(2, null);
nickPreparedStatement.execute();
} catch (SQLException e) {
ALogger.warn("Failed to store requested nickname for "
+ uniqueId.toString() + "\n" + Arrays.toString(e.getStackTrace())
.replace(",", "\n"));
}
}
private static ResultSet getStringResult(final String query, final String... parameters) throws SQLException {
final PreparedStatement statement = DatabaseConnection.getConnection().prepareStatement(query);
for (int i = 1; i < parameters.length + 1; ++i) {
statement.setString(i, parameters[i - 1]);
}
return statement.executeQuery();
}
}
@@ -0,0 +1,56 @@
package com.alttd.chat.events;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class NickEvent extends Event{
String senderName;
String targetName;
String nickName;
NickEventType nickEventType;
public NickEvent(String senderName, String targetName, String nickName, NickEventType nickEventType) {
this.senderName = senderName;
this.targetName = targetName;
this.nickName = nickName;
this.nickEventType = nickEventType;
}
public String getSenderName() {
return this.senderName;
}
public String getTargetName() {
return this.targetName;
}
public String getNickName() {
return this.nickName;
}
public NickEventType getNickEventType() {
return this.nickEventType;
}
private static final HandlerList HANDLERS = new HandlerList();
public static HandlerList getHandlerList() {
return HANDLERS;
}
@NotNull
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
public enum NickEventType {
ACCEPTED,
DENIED,
SET,
RESET
}
}
@@ -2,10 +2,10 @@ package com.alttd.chat.managers;
import com.alttd.chat.database.Queries;
import com.alttd.chat.objects.ChatUser;
import com.alttd.chat.objects.Mail;
import java.util.*;
import java.util.stream.Collectors;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
public final class ChatUserManager {
@@ -15,15 +15,15 @@ public final class ChatUserManager {
chatUsers = new TreeMap<>();
}
public static void addUser(ChatUser user) {
public static synchronized void addUser(ChatUser user) {
chatUsers.put(user.getUuid(), user);
}
public static void removeUser(ChatUser user) {
public static synchronized void removeUser(ChatUser user) {
chatUsers.remove(user.getUuid());
}
public static ChatUser getChatUser(UUID uuid) {
public static synchronized ChatUser getChatUser(UUID uuid) {
return chatUsers.computeIfAbsent(uuid, k -> Queries.loadChatUser(uuid));
}
@@ -3,6 +3,7 @@ package com.alttd.chat.managers;
import com.alttd.chat.ChatAPI;
import com.alttd.chat.config.RegexConfig;
import com.alttd.chat.objects.ChatFilter;
import com.alttd.chat.objects.FilterType;
import com.alttd.chat.objects.ModifiableString;
import com.alttd.chat.util.ALogger;
import net.luckperms.api.cacheddata.CachedPermissionData;
@@ -17,11 +18,24 @@ public class RegexManager {
private static List<ChatFilter> chatFilters;
private static final Pattern pattern = Pattern.compile("(.)\\1{4,}");
private static final List<ChatFilter> emotes = new ArrayList<>();
public static final List<String> emotesList = new ArrayList<>();
public static void initialize() {
chatFilters = new ArrayList<>();
RegexConfig.init();
loadEmotes();
}
private static void loadEmotes() {
emotes.clear();
for(ChatFilter chatFilter : chatFilters) {
if (chatFilter.getType() != FilterType.EMOTE) continue;
emotes.add(chatFilter);
emotesList.add(chatFilter.getRegex());
}
}
public static void addFilter(ChatFilter filter) {
@@ -50,7 +64,8 @@ public class RegexManager {
if(!permissionData.checkPermission("chat.bypass-filter-channel." + channel).asBoolean() &&
!permissionData.checkPermission("chat.bypass-filter." + chatFilter.getName()).asBoolean() &&
chatFilter.matches(modifiableString)) { // todo find a better way to do this?
ALogger.info(playerName + " triggered the chat filter for " + chatFilter.getName() + ".");
ALogger.info(playerName + " triggered the chat filter for " + chatFilter.getName()
+ " with: " + modifiableString.string() + ".");
return false;
}
break;
@@ -64,4 +79,11 @@ public class RegexManager {
return true;
}
public static List<ChatFilter> getChatFilters() {
return chatFilters;
}
public static List<ChatFilter> getEmoteFilters() {
return emotes;
}
}
@@ -1,5 +1,10 @@
package com.alttd.chat.objects;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.Style;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -47,7 +52,13 @@ public class ChatFilter {
Matcher matcher = pattern.matcher(input);
while (matcher.find())
if (!isException(input, matcher.start())) {
filterableString.string(filterableString.string().replaceFirst(matcher.group(), "<gold>" + matcher.group() + "</gold>"));
// filterableString.string(filterableString.string().replaceFirst(matcher.group(), "<gold>" + matcher.group() + "</gold>"));
filterableString.string(filterableString.component()
.replaceText(
TextReplacementConfig.builder()
.match(matcher.pattern())
.replacement(Component.text(matcher.group()).style(Style.style(NamedTextColor.GOLD)))
.build()));
return true;
}
return matcher.matches();
@@ -76,7 +87,12 @@ public class ChatFilter {
while (matcher.find()) {
String group = matcher.group(); // todo debug
if (getExclusions().stream().noneMatch(s -> s.equalsIgnoreCase(group))) { // idk how heavy this is:/
modifiableString.string(input.replace(group, getReplacement()));
modifiableString.replace(
TextReplacementConfig.builder()
.matchLiteral(group)
.replacement(getReplacement())
.build()
);
}
}
}
@@ -92,7 +108,10 @@ public class ChatFilter {
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
String group = matcher.group();
modifiableString.string(input.replace(group, group.substring(0, length)));
modifiableString.replace(TextReplacementConfig.builder()
.matchLiteral(group)
.replacement(Component.text(group.substring(0, length), modifiableString.component().color()))
.build());
}
}
}
@@ -21,6 +21,7 @@ public class ChatUser {
// private Component prefixAll; // doesn't need saving, we get this from luckperms
//private boolean toggleGc; // should be saved, this toggles if the player can see and use global chat
private String replyTarget; // reply target for use in /msg i don't mind setting this to null on login, feedback?
private String replyContinueTarget; // reply target for use in /c
private long gcCooldown; // the time when they last used gc, is used for the cooldown, i wouldn't save this, but setting this to the login time means they can't use gc for 30 seconds after logging in
private boolean spy;
private List<Mail> mails; // mails aren't finalized yet, so for now a table sender, reciever, sendtime, readtime(if emtpy mail isn't read yet?, could also do a byte to control this), the actual message
@@ -44,7 +45,8 @@ public class ChatUser {
//
// prefixAll = Utility.getPrefix(uuid, false);
replyTarget = null;
replyTarget = "";
replyContinueTarget = "";
gcCooldown = System.currentTimeMillis(); // players can't use gc for 30 seconds after logging in if we use this?
mails = Queries.getMails(uuid);
ignoredPlayers = Queries.getIgnoredUsers(uuid);
@@ -101,10 +103,18 @@ public class ChatUser {
return replyTarget;
}
public String getReplyContinueTarget() {
return replyContinueTarget;
}
public void setReplyTarget(String replyTarget) {
this.replyTarget = replyTarget;
}
public void setReplyContinueTarget(String replyTarget) {
this.replyContinueTarget = replyTarget;
}
public List<Mail> getMails() {
return mails;
}
@@ -170,4 +180,8 @@ public class ChatUser {
}
setDisplayName(name);
}
public String getNickNameString() {
return name;
}
}
@@ -0,0 +1,64 @@
package com.alttd.chat.objects;
import com.alttd.chat.config.Config;
import com.alttd.chat.managers.RegexManager;
import com.alttd.chat.util.Utility;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class EmoteList {
public static final Map<UUID, EmoteList> emoteLists = new HashMap<>();
public static final int pageSize = 7;
// public static int pages = RegexManager.getEmoteFilters().size() / pageSize;// TODO reload this when config is reloaded.
public static EmoteList getEmoteList(UUID uuid) {
synchronized (emoteLists) {
return emoteLists.computeIfAbsent(uuid, k -> new EmoteList());
}
}
private int page;
public Component showEmotePage() {
int startIndex = page * pageSize;
int pages = RegexManager.getEmoteFilters().size() / pageSize;
int endIndex = Math.min(startIndex + pageSize, RegexManager.getEmoteFilters().size());
TagResolver placeholders = TagResolver.resolver(
Placeholder.unparsed("page", String.valueOf(page)),
Placeholder.unparsed("pages", String.valueOf(pages))
);
Component list = Utility.parseMiniMessage(Config.EMOTELIST_HEADER, placeholders);
for (int i = startIndex; i < endIndex; i++) {
ChatFilter emote = RegexManager.getEmoteFilters().get(i);
TagResolver emotes = TagResolver.resolver(
Placeholder.parsed("regex", emote.getRegex()),
Placeholder.parsed("emote", emote.getReplacement())
);
list = list.append(Utility.parseMiniMessage(Config.EMOTELIST_ITEM, emotes));
}
list = list.append(Utility.parseMiniMessage(Config.EMOTELIST_FOOTER, placeholders));
return list;
}
public void setPage(int page) {
this.page = Math.min(page, RegexManager.getEmoteFilters().size() / pageSize);
}
public void nextPage() {
this.page = Math.min(page + 1, RegexManager.getEmoteFilters().size() / pageSize);
}
public void prevPage() {
this.page -= 1;
this.page = Math.max(page - 1, 0);
}
}
@@ -2,6 +2,7 @@ package com.alttd.chat.objects;
public enum FilterType {
REPLACE("replace"),
EMOTE("emote"),
CHAT("chat"),
REPLACEMATCHER("replacematcher"),
BLOCK("block");
@@ -1,17 +1,33 @@
package com.alttd.chat.objects;
public class ModifiableString {
private String string;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.intellij.lang.annotations.RegExp;
public ModifiableString(String string) {
this.string = string;
import javax.annotation.RegEx;
import java.util.regex.Pattern;
public class ModifiableString {
private Component text;
public ModifiableString(Component text) {
this.text = text;
}
public void string(String string) {
this.string = string;
public void string(Component text) {
this.text = text;
}
public void replace(TextReplacementConfig textReplacementConfig) {
text = text.replaceText(textReplacementConfig);
}
public String string() {
return string;
return PlainTextComponentSerializer.plainText().serialize(text);
}
public Component component() {
return text;
}
}
@@ -0,0 +1,99 @@
package com.alttd.chat.objects;
import com.alttd.chat.util.Utility;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
public class Nick {
private final UUID uuid;
private String currentNick;
private String currentNickNoColor;
private long lastChangedDate;
private String newNick;
private String newNickNoColor;
private long requestedDate;
private boolean hasRequest;
public Nick(UUID uuid, String currentNick, long lastChangedDate) {
this.uuid = uuid;
this.currentNick = currentNick;
currentNickNoColor = currentNick == null ? null : Utility.removeAllColors(currentNick);
this.lastChangedDate = lastChangedDate;
newNick = null;
newNickNoColor = null;
requestedDate = 0;
hasRequest = false;
}
public Nick(UUID uuid, String currentNick, long lastChangedDate, String newNick, long requestedDate) {
this.uuid = uuid;
this.currentNick = currentNick;
currentNickNoColor = currentNick == null ? null : Utility.removeAllColors(currentNick);
this.lastChangedDate = lastChangedDate;
this.newNick = newNick;
newNickNoColor = newNick == null ? null : Utility.removeAllColors(newNick);
this.requestedDate = requestedDate;
hasRequest = newNick != null;
}
public UUID getUuid() {
return uuid;
}
public String getCurrentNickNoColor() {
return currentNickNoColor;
}
public String getCurrentNick() {
return currentNick;
}
public void setCurrentNick(String currentNick) {
this.currentNick = currentNick;
currentNickNoColor = currentNick == null ? null : Utility.removeAllColors(currentNick);
}
public long getLastChangedDate(){
return lastChangedDate;
}
public String getLastChangedDateFormatted() {
return new SimpleDateFormat("yyyy-MM-dd").format(new Date(lastChangedDate));
}
public void setLastChangedDate(long lastChangedDate) {
this.lastChangedDate = lastChangedDate;
}
public String getNewNickNoColor() {
return newNickNoColor;
}
public String getNewNick() {
return newNick;
}
public void setNewNick(String newNick) {
this.newNick = newNick;
newNickNoColor = newNick == null ? null : Utility.removeAllColors(newNick);
hasRequest = newNick != null;
}
public long getRequestedDate(){
return requestedDate;
}
public String getRequestedDateFormatted() {
return new SimpleDateFormat("yyyy-MM-dd").format(new Date(requestedDate));
}
public void setRequestedDate(long requestedDate) {
this.requestedDate = requestedDate;
}
public boolean hasRequest() {
return hasRequest;
}
}
@@ -48,6 +48,7 @@ public class Party {
.findFirst();
if (first.isEmpty()) return;
partyUsers.remove(first.get());
chatUser.setPartyId(-1);
Queries.removePartyUser(uuid);
}
@@ -0,0 +1,62 @@
package com.alttd.chat.objects;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public abstract class Toggleable {
private static final List<Toggleable> togglableClasses = new ArrayList<>();
public Toggleable() {
togglableClasses.add(this);
}
public static Toggleable getToggleable(UUID uuid) {
for (Toggleable toggleableClass : togglableClasses) {
if (toggleableClass.isToggled(uuid))
return toggleableClass;
}
return null;
}
public abstract boolean isToggled(UUID uuid);
public abstract void setOff(UUID uuid);
public boolean toggle(UUID uuid) {
if (isToggled(uuid)) {
setOff(uuid);
return (false);
}
for (Toggleable toggleable : togglableClasses) {
if (toggleable.isToggled(uuid)) {
setOff(uuid);
break;
}
}
setOn(uuid);
return (true);
}
public abstract void setOn(UUID uuid);
public static void disableToggles(UUID uuid) {
for (Toggleable toggleable : togglableClasses) {
if (toggleable.isToggled(uuid)) {
toggleable.setOff(uuid);
}
}
}
public void sendMessage(Player player, Component message) {
sendMessage(player, PlainTextComponentSerializer.plainText().serialize(message));
}
public abstract void sendMessage(Player player, String message);
}
@@ -3,7 +3,7 @@ package com.alttd.chat.objects.channels;
import java.util.Collection;
import java.util.HashMap;
public abstract class Channel {
public class Channel {
public static HashMap<String, Channel> channels = new HashMap<>();
protected String permission;
@@ -1,6 +1,6 @@
package com.alttd.chat.objects.channels;
public class DefaultChannel extends Channel{
public abstract class DefaultChannel extends Channel{
public DefaultChannel(String channelName, String format, boolean proxy) {
super(channelName, format, proxy);
}
@@ -0,0 +1,20 @@
package com.alttd.chat.util;
public class Pair<X, Y> {
private final X x;
private final Y y;
public Pair(X x, Y y) {
this.x = x;
this.y = y;
}
public X getX() {
return x;
}
public Y getY() {
return y;
}
}
@@ -3,15 +3,16 @@ package com.alttd.chat.util;
import com.alttd.chat.ChatAPI;
import com.alttd.chat.config.Config;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.placeholder.PlaceholderResolver;
import net.kyori.adventure.text.minimessage.placeholder.Replacement;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.minimessage.tag.standard.StandardTags;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.model.group.Group;
import net.luckperms.api.model.user.User;
import net.luckperms.api.node.Node;
import org.bukkit.permissions.Permission;
import java.util.*;
import java.util.regex.Matcher;
@@ -20,6 +21,7 @@ import java.util.stream.Collectors;
public class Utility {
private static final List<String> EMPTY_LIST = new ArrayList<>();
static final Pattern DEFAULT_URL_PATTERN = Pattern.compile("(?:(https?)://)?([-\\w_.]+\\.\\w{2,})(/\\S*)?");
private static MiniMessage miniMessage = null;
@@ -46,6 +48,38 @@ public class Utility {
colors.put("&e", "<yellow>");
colors.put("&f", "<white>");
}
public static HashMap<String, Pair<TagResolver, List<String>>> formattingPerms = new HashMap<>();
static {
formattingPerms.put("chat.format.color",
new Pair<>(StandardTags.color(), colors.values().stream().toList()));
formattingPerms.put("chat.format.bold",
new Pair<>(StandardTags.decorations(TextDecoration.BOLD), List.of("<bold>", "<b>")));
formattingPerms.put("chat.format.italic",
new Pair<>(StandardTags.decorations(TextDecoration.ITALIC), List.of("<italic>", "<i>")));
formattingPerms.put("chat.format.underlined",
new Pair<>(StandardTags.decorations(TextDecoration.UNDERLINED), List.of("<underlined>", "<u>")));
formattingPerms.put("chat.format.strikethrough",
new Pair<>(StandardTags.decorations(TextDecoration.STRIKETHROUGH), List.of("<strikethrough>", "<st>")));
formattingPerms.put("chat.format.obfuscated",
new Pair<>(StandardTags.decorations(TextDecoration.OBFUSCATED), List.of("<obfuscated>", "<obf>")));
formattingPerms.put("chat.format.gradient",
new Pair<>(StandardTags.gradient(), EMPTY_LIST));
formattingPerms.put("chat.format.font",
new Pair<>(StandardTags.font(), EMPTY_LIST));
formattingPerms.put("chat.format.rainbow",
new Pair<>(StandardTags.rainbow(), List.of("<rainbow>")));
formattingPerms.put("chat.format.hover",
new Pair<>(StandardTags.hoverEvent(), EMPTY_LIST));
formattingPerms.put("chat.format.click",
new Pair<>(StandardTags.clickEvent(), EMPTY_LIST));
formattingPerms.put("chat.format.transition",
new Pair<>(StandardTags.transition(), EMPTY_LIST));
formattingPerms.put("chat.format.reset",
new Pair<>(StandardTags.reset(), List.of("<reset>", "<r>")));
formattingPerms.put("chat.format.newline",
new Pair<>(StandardTags.newline(), List.of("<newline>")));
}
public static String parseColors(String message) {
if (message == null) return "";
@@ -215,6 +249,47 @@ public class Utility {
: Utility.parseMiniMessage(stringBuilder.toString());
}
public static boolean checkNickBrightEnough(String nickname) {
if (!nickname.matches(".*" + stringRegen + ".*")) {
return true;
}
Pattern pattern = Pattern.compile(stringRegen);
Matcher matcher = pattern.matcher(nickname);
while (matcher.find()) {
String hexColor = matcher.group();
if (!checkHexHighEnough(hexColor)) {
return false;
}
}
return true;
}
private static boolean checkHexHighEnough(String hexColor) {
// Remove the leading "#" if present
if (hexColor.startsWith("{")) {
hexColor = hexColor.substring(1);
}
if (hexColor.startsWith("#")) {
hexColor = hexColor.substring(1);
}
// Extract the color parts
String redPart = hexColor.substring(0, 2);
String greenPart = hexColor.substring(2, 4);
String bluePart = hexColor.substring(4, 6);
// Convert the color parts to integers
int red = Integer.parseInt(redPart, 16);
int green = Integer.parseInt(greenPart, 16);
int blue = Integer.parseInt(bluePart, 16);
// Check if any part is over 30 in hexadecimal
return red > 0x30 || green > 0x30 || blue > 0x30;
}
public static String formatText(String message) {
/*
.match(pattern)
@@ -241,24 +316,24 @@ public class Utility {
return getMiniMessage().deserialize(message);
}
public static Component parseMiniMessage(String message, Map<String, Replacement<?>> placeholders) {
public static Component parseMiniMessage(String message, TagResolver placeholders) {
if (placeholders == null) {
return getMiniMessage().deserialize(message);
} else {
return getMiniMessage().deserialize(message, PlaceholderResolver.map(placeholders));
return getMiniMessage().deserialize(message, placeholders);
}
}
public static Component parseMiniMessage(String message, Placeholder<?> ... placeholders) {
public static Component parseMiniMessage(String message, TagResolver ... placeholders) {
if (placeholders == null) {
return getMiniMessage().deserialize(message);
} else {
return getMiniMessage().deserialize(message, PlaceholderResolver.placeholders(placeholders));
return getMiniMessage().deserialize(message, TagResolver.resolver(placeholders));
}
}
public static String stripTokens(String input) {
return getMiniMessage().stripTokens(input);
return getMiniMessage().stripTags(input);
}
public static MiniMessage getMiniMessage() {
@@ -266,4 +341,13 @@ public class Utility {
return miniMessage;
}
public static String removeAllColors(String string) {
for (String colorCodes : colors.keySet()) {
string = string.replace(colorCodes, "");
}
return string.replaceAll("\\{#[A-Fa-f0-9]{6}(<)?(>)?}", "");
}
}
+19 -3
View File
@@ -5,8 +5,21 @@ plugins {
allprojects {
group = "com.alttd.chat"
version = "1.0.0-SNAPSHOT"
version = "2.0.0-SNAPSHOT"
description = "All in one minecraft chat plugin"
// repositories {
// mavenCentral()
// maven("https://repo.destro.xyz/snapshots") // Altitude - Galaxy
// maven("https://oss.sonatype.org/content/groups/public/") // Adventure
// maven("https://oss.sonatype.org/content/repositories/snapshots/") // Minimessage
// maven("https://oss.sonatype.org/content/repositories/") // Minimessage
// maven("https://nexus.velocitypowered.com/repository/") // Velocity
// maven("https://nexus.velocitypowered.com/repository/maven-public/") // Velocity
// maven("https://repo.spongepowered.org/maven") // Configurate
// maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") // Papi
// maven("https://jitpack.io")
// }
}
subprojects {
@@ -48,13 +61,13 @@ dependencies {
tasks {
shadowJar {
archiveFileName.set("${project.name}-${project.version}.jar")
archiveFileName.set("${project.name}.jar")
minimize() {
exclude { it.moduleName == "galaxy" }
exclude { it.moduleName == "velocity" }
}
listOf(
"net.kyori.adventure.text.minimessage",
// "net.kyori.adventure.text.minimessage",
"org.spongepowered.configurate"
// ).forEach { relocate(it, "${rootProject.group}.lib.$it") }
).forEach { relocate(it, "${rootProject.group}.lib.${it.substringAfterLast(".")}") }
@@ -64,4 +77,7 @@ tasks {
dependsOn(shadowJar)
}
jar {
enabled = false
}
}
+37 -8
View File
@@ -1,29 +1,58 @@
import java.io.FileOutputStream
import java.net.URL
plugins {
`maven-publish`
id("com.github.johnrengelman.shadow")
id("xyz.jpenilla.run-paper") version "1.0.6"
}
dependencies {
implementation(project(":api")) // API
compileOnly("com.alttd:Galaxy-API:1.18.1-R0.1-SNAPSHOT") {
exclude("net.kyori.adventure.text.minimessag")
} // Galaxy
compileOnly("net.kyori", "adventure-text-minimessage", "4.10.0-20220122.015731-43") { // Minimessage
exclude("net.kyori")
exclude("net.kyori.examination")
}
compileOnly("com.alttd:Galaxy-API:1.20.4-R0.1-SNAPSHOT") // Galaxy
compileOnly("com.gitlab.ruany:LiteBansAPI:0.3.5") // move to proxy
compileOnly("org.apache.commons:commons-lang3:3.12.0") // needs an alternative, already removed from upstream api and will be removed in server
compileOnly("net.luckperms:api:5.3") // Luckperms
compileOnly(files("../libs/CMI.jar"))
}
tasks {
shadowJar {
archiveFileName.set("${project.name}-${project.version}.jar")
archiveFileName.set("${rootProject.name}-${project.name}-${project.version}.jar")
// minimize()
}
build {
// setBuildDir("${rootProject.buildDir}")
dependsOn(shadowJar)
}
runServer {
val dir = File(System.getProperty("user.home") + "/share/devserver/");
if (!dir.parentFile.exists()) {
dir.parentFile.mkdirs()
}
runDirectory.set(dir)
val fileName = "/galaxy.jar"
var file = File(dir.path + fileName)
if (!file.parentFile.exists()) {
file.parentFile.mkdirs()
}
if (!file.exists()) {
download("https://repo.destro.xyz/snapshots/com/alttd/Galaxy-Server/Galaxy-paperclip-1.19.2-R0.1-SNAPSHOT-reobf.jar", file)
}
serverJar(file)
minecraftVersion("1.19.2")
}
}
fun download(link: String, path: File) {
URL(link).openStream().use { input ->
FileOutputStream(path).use { output ->
input.copyTo(output)
}
}
}
@@ -5,11 +5,15 @@ import com.alttd.chat.config.Config;
import com.alttd.chat.config.ServerConfig;
import com.alttd.chat.database.DatabaseConnection;
import com.alttd.chat.handler.ChatHandler;
import com.alttd.chat.listeners.BookListener;
import com.alttd.chat.listeners.ChatListener;
import com.alttd.chat.listeners.PlayerListener;
import com.alttd.chat.listeners.PluginMessage;
import com.alttd.chat.nicknames.Nicknames;
import com.alttd.chat.nicknames.NicknamesEvents;
import com.alttd.chat.objects.channels.Channel;
import com.alttd.chat.objects.channels.CustomChannel;
import com.alttd.chat.requests.RequestHandler;
import com.alttd.chat.util.ALogger;
import com.alttd.chat.util.Utility;
import org.bukkit.Bukkit;
@@ -26,6 +30,7 @@ public class ChatPlugin extends JavaPlugin {
private ChatAPI chatAPI;
private ChatHandler chatHandler;
private RequestHandler requestHandler;
private String messageChannel;
private ServerConfig serverConfig;
@@ -37,14 +42,17 @@ public class ChatPlugin extends JavaPlugin {
chatAPI = new ChatImplementation();
chatHandler = new ChatHandler();
DatabaseConnection.initialize();
requestHandler = new RequestHandler();
requestHandler.loadRequests();
serverConfig = new ServerConfig(Bukkit.getServerName());
registerListener(new PlayerListener(), new ChatListener());
registerListener(new PlayerListener(serverConfig), new ChatListener(), new BookListener());
if(serverConfig.GLOBALCHAT) {
registerCommand("globalchat", new GlobalChat());
registerCommand("toggleglobalchat", new ToggleGlobalChat());
}
registerCommand("message", new Message());
registerCommand("reply", new Reply());
registerCommand("continue", new Continue());
registerCommand("ignore", new Ignore());
registerCommand("unignore", new Unignore());
registerCommand("muteserver", new MuteServer());
@@ -52,6 +60,7 @@ public class ChatPlugin extends JavaPlugin {
registerCommand("chatclear", new ChatClear());
// registerCommand("chatparty", new ChatParty());
registerCommand("p", new PartyChat());
registerCommand("emotes", new Emotes());
for (Channel channel : Channel.getChannels()) {
if (!(channel instanceof CustomChannel customChannel)) continue;
this.getServer().getCommandMap().register(channel.getChannelName().toLowerCase(), new ChatChannel(customChannel));
@@ -60,6 +69,11 @@ public class ChatPlugin extends JavaPlugin {
messageChannel = Config.MESSAGECHANNEL;
getServer().getMessenger().registerOutgoingPluginChannel(this, messageChannel);
getServer().getMessenger().registerIncomingPluginChannel(this, messageChannel, new PluginMessage());
NicknamesEvents nicknamesEvents = new NicknamesEvents();
getServer().getMessenger().registerIncomingPluginChannel(this, messageChannel, nicknamesEvents);
getServer().getPluginManager().registerEvents(nicknamesEvents, this);
registerCommand("nick", new Nicknames());
}
@Override
@@ -95,6 +109,10 @@ public class ChatPlugin extends JavaPlugin {
return chatHandler;
}
public RequestHandler getRequestHandler() {
return requestHandler;
}
public boolean serverGlobalChatEnabled() {
return serverConfig.GLOBALCHAT;
}
@@ -1,20 +1,24 @@
package com.alttd.chat.commands;
import com.alttd.chat.ChatPlugin;
import com.alttd.chat.config.Config;
import com.alttd.chat.objects.channels.CustomChannel;
import org.apache.commons.lang.StringUtils;
import com.alttd.chat.util.ToggleableForCustomChannel;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.*;
public class ChatChannel extends BukkitCommand {
CustomChannel channel;
String command;
ToggleableForCustomChannel toggleableForCustomChannel;
private static List<ChatChannel> activeCommands = new ArrayList<>();
public ChatChannel(CustomChannel channel) {
super(channel.getChannelName().toLowerCase());
@@ -23,6 +27,8 @@ public class ChatChannel extends BukkitCommand {
this.description = "Chat channel named " + channel.getChannelName() + ".";
this.usageMessage = "/" + command + " <message>";
this.setAliases(Collections.emptyList());
activeCommands.add(this);
this.toggleableForCustomChannel = new ToggleableForCustomChannel(channel);
}
@Override
@@ -30,16 +36,18 @@ public class ChatChannel extends BukkitCommand {
if(!(sender instanceof Player player)) { // must be a player
return true;
}
if(args.length == 0) return false;
if(args.length == 0 && player.hasPermission(channel.getPermission())) {
player.sendMiniMessage(Config.CUSTOM_CHANNEL_TOGGLED, TagResolver.resolver(
Placeholder.unparsed("channel", channel.getChannelName()),
Placeholder.component("status", toggleableForCustomChannel.toggle(player.getUniqueId())
? Config.TOGGLED_ON : Config.TOGGLED_OFF)));
return false;
}
String message = StringUtils.join(args, " ", 0, args.length);
new BukkitRunnable() {
@Override
public void run() {
ChatPlugin.getInstance().getChatHandler().chatChannel(player, channel, message);
}
}.runTaskAsynchronously(ChatPlugin.getInstance());
toggleableForCustomChannel.sendMessage(player, message);
return false;
}
@@ -3,8 +3,7 @@ package com.alttd.chat.commands;
import com.alttd.chat.util.Utility;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.placeholder.PlaceholderResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -25,10 +24,11 @@ public class ChatClear implements CommandExecutor {
for (Player player : Bukkit.getOnlinePlayers())
if (!player.hasPermission("chat.clear-bypass"))
player.sendMessage(component);
Bukkit.getServer().sendMessage(miniMessage.deserialize(
"<gold><player> cleared chat.</gold>", PlaceholderResolver.placeholders(
Placeholder.component("player", miniMessage.deserialize(sender.getName()))
)));
"<gold><player> cleared chat.</gold>",
Placeholder.component("player",sender.name()))
);
return true;
}
}
@@ -0,0 +1,27 @@
package com.alttd.chat.commands;
import com.alttd.chat.ChatPlugin;
import com.alttd.chat.managers.ChatUserManager;
import com.alttd.chat.objects.ChatUser;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class Continue implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if(!(sender instanceof Player player)) {
return true;
}
ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
if (user.getReplyContinueTarget() == null) return false;
if(args.length == 0) return false; // todo error message or command info
String message = StringUtils.join(args, " ", 0, args.length);
ChatPlugin.getInstance().getChatHandler().continuePrivateMessage(player, user.getReplyContinueTarget(), message);
return false;
}
}
@@ -0,0 +1,33 @@
package com.alttd.chat.commands;
import com.alttd.chat.objects.EmoteList;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class Emotes implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if(!(sender instanceof Player player)) { // must be a player
return true;
}
EmoteList emoteList = EmoteList.getEmoteList(player.getUniqueId());
if(args.length > 0) {
try {
int page = Integer.parseInt(args[0]);
emoteList.setPage(page);
} catch (NumberFormatException ignored) {
switch (args[0].toLowerCase()) {
case "next" -> emoteList.nextPage();
case "prev", "previous" -> emoteList.prevPage();
default -> {}
}
}
}
player.sendMessage(emoteList.showEmotePage());
return false;
}
}
@@ -1,7 +1,7 @@
package com.alttd.chat.commands;
import com.alttd.chat.ChatPlugin;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -1,25 +0,0 @@
package com.alttd.chat.commands;
import com.alttd.chat.ChatPlugin;
import org.apache.commons.lang.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class Mail implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if(!(sender instanceof Player)) { // must be a player, @teri should console be able to /msg?
return true;
}
Player player = (Player) sender;
if(args.length > 2) return false; // todo error message or command info
String message = StringUtils.join(args, " ", 1, args.length);
ChatPlugin.getInstance().getChatHandler().privateMessage(player, args[0], message);
return false;
}
}
@@ -1,22 +1,25 @@
package com.alttd.chat.commands;
import com.alttd.chat.ChatPlugin;
import org.apache.commons.lang.StringUtils;
import com.alttd.chat.managers.ChatUserManager;
import com.alttd.chat.objects.ChatUser;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class Message implements CommandExecutor {
public class Message implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if(!(sender instanceof Player)) {
if(!(sender instanceof Player player)) {
return true;
}
Player player = (Player) sender;
if(args.length < 2) return false; // todo error message or command info
ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
user.setReplyContinueTarget(args[0]);
String message = StringUtils.join(args, " ", 1, args.length);
ChatPlugin.getInstance().getChatHandler().privateMessage(player, args[0], message);
return false;
@@ -1,11 +1,11 @@
package com.alttd.chat.commands;
import com.alttd.chat.ChatPlugin;
import com.alttd.chat.managers.PartyManager;
import com.alttd.chat.objects.Party;
import com.alttd.chat.util.Utility;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.apache.commons.lang.StringUtils;
import com.alttd.chat.config.Config;
import com.alttd.chat.objects.Toggleable;
import com.alttd.chat.util.ALogger;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -13,7 +13,12 @@ import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
public class PartyChat implements CommandExecutor {
import java.util.HashSet;
import java.util.UUID;
public class PartyChat extends Toggleable implements CommandExecutor {
private final HashSet<UUID> toggledUsers = new HashSet<>();
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
@@ -22,7 +27,8 @@ public class PartyChat implements CommandExecutor {
}
if(args.length == 0) {
// TODO: 08/08/2021 lock into party chat
player.sendMiniMessage(Config.PARTY_TOGGLED, Placeholder.component("status",
toggle(player.getUniqueId()) ? Config.TOGGLED_ON : Config.TOGGLED_OFF));
return true;
}
@@ -37,4 +43,31 @@ public class PartyChat implements CommandExecutor {
return true;
}
@Override
public boolean isToggled(UUID uuid) {
return toggledUsers.contains(uuid);
}
@Override
public void setOff(UUID uuid) {
toggledUsers.remove(uuid);
}
@Override
public void setOn(UUID uuid) {
disableToggles(uuid);
toggledUsers.add(uuid);
}
@Override
public void sendMessage(Player player, String message) {
ALogger.info(player.getName() + " sent party message: " + message);
new BukkitRunnable() {
@Override
public void run() {
ChatPlugin.getInstance().getChatHandler().partyMessage(player, message);
}
}.runTaskAsynchronously(ChatPlugin.getInstance());
}
}
@@ -3,7 +3,7 @@ package com.alttd.chat.commands;
import com.alttd.chat.ChatPlugin;
import com.alttd.chat.managers.ChatUserManager;
import com.alttd.chat.objects.ChatUser;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -8,7 +8,7 @@ import com.alttd.chat.objects.ChatUser;
import com.alttd.chat.util.Utility;
import jdk.jshell.execution.Util;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -4,6 +4,7 @@ import com.alttd.chat.ChatPlugin;
import com.alttd.chat.config.Config;
import com.alttd.chat.managers.ChatUserManager;
import com.alttd.chat.managers.RegexManager;
import com.alttd.chat.objects.ChatFilter;
import com.alttd.chat.objects.ChatUser;
import com.alttd.chat.objects.ModifiableString;
import com.alttd.chat.objects.channels.CustomChannel;
@@ -12,8 +13,11 @@ import com.alttd.chat.util.Utility;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.placeholder.Replacement;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@@ -34,10 +38,51 @@ public class ChatHandler {
GCNOTENABLED = Utility.parseMiniMessage(Config.GCNOTENABLED);
}
public void continuePrivateMessage(Player player, String target, String message) {
// ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
// user.setReplyTarget(target);
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("message", parseMessageContent(player, message)),
Placeholder.component("sendername", player.name()),
Placeholder.parsed("receivername", target)
);
Component component = Utility.parseMiniMessage("<message>", placeholders);
ModifiableString modifiableString = new ModifiableString(component);
// todo a better way for this
if(!RegexManager.filterText(player.getName(), player.getUniqueId(), modifiableString, "privatemessage")) {
GalaxyUtility.sendBlockedNotification("DM Language",
player,
Utility.parseMiniMessage(Utility.parseColors(modifiableString.string())),
target);
return; // the message was blocked
}
component = modifiableString.component();
sendPrivateMessage(player, target, "privatemessage", component);
Component spymessage = Utility.parseMiniMessage(Config.MESSAGESPY, placeholders);
for(Player pl : Bukkit.getOnlinePlayers()) {
if(pl.hasPermission(Config.SPYPERMISSION) && ChatUserManager.getChatUser(pl.getUniqueId()).isSpy() && !pl.equals(player) && !pl.getName().equalsIgnoreCase(target)) {
pl.sendMessage(spymessage);
}
}
}
public void privateMessage(Player player, String target, String message) {
// ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
// user.setReplyTarget(target);
ModifiableString modifiableString = new ModifiableString(message);
Component messageComponent = parseMessageContent(player, message);
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("message", messageComponent),
Placeholder.component("sendername", player.name()),
Placeholder.parsed("receivername", target)
);
ModifiableString modifiableString = new ModifiableString(messageComponent);
// todo a better way for this
if(!RegexManager.filterText(player.getName(), player.getUniqueId(), modifiableString, "privatemessage")) {
GalaxyUtility.sendBlockedNotification("DM Language",
@@ -46,28 +91,13 @@ public class ChatHandler {
target);
return; // the message was blocked
}
String updatedMessage = modifiableString.string();
if(!player.hasPermission("chat.format")) {
updatedMessage = Utility.stripTokens(updatedMessage);
} else {
updatedMessage = Utility.parseColors(updatedMessage);
}
messageComponent = modifiableString.component();
if(updatedMessage.contains("[i]"))
updatedMessage = updatedMessage.replace("[i]", "<[i]>");
// Component component = Utility.parseMiniMessage("<message>", placeholders)
// .replaceText(TextReplacementConfig.builder().once().matchLiteral("[i]").replacement(ChatHandler.itemComponent(player.getInventory().getItemInMainHand())).build());
updatedMessage = Utility.formatText(updatedMessage);
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("message", Replacement.miniMessage(updatedMessage));
placeholders.put("sendername", Replacement.miniMessage(player.getName()));
placeholders.put("receivername", Replacement.miniMessage(target));
placeholders.put("[i]", Replacement.component(itemComponent(player.getInventory().getItemInMainHand())));
Component component = Utility.parseMiniMessage("<message>", placeholders);
sendPrivateMessage(player, target, "privatemessage", component);
sendPrivateMessage(player, target, "privatemessage", messageComponent);
Component spymessage = Utility.parseMiniMessage(Config.MESSAGESPY, placeholders);
for(Player pl : Bukkit.getOnlinePlayers()) {
if(pl.hasPermission(Config.SPYPERMISSION) && ChatUserManager.getChatUser(pl.getUniqueId()).isSpy() && !pl.equals(player) && !pl.getName().equalsIgnoreCase(target)) {
@@ -89,16 +119,23 @@ public class ChatHandler {
long timeLeft = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - user.getGcCooldown());
if(timeLeft <= Config.GCCOOLDOWN && !player.hasPermission("chat.globalchat.cooldownbypass")) { // player is on cooldown and should wait x seconds
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("cooldown", Replacement.miniMessage(Config.GCCOOLDOWN-timeLeft+""));
player.sendMessage(Utility.parseMiniMessage(Config.GCONCOOLDOWN, placeholders));
player.sendMessage(Utility.parseMiniMessage(Config.GCONCOOLDOWN, Placeholder.parsed("cooldown", Config.GCCOOLDOWN-timeLeft+"")));
return;
}
Component senderName = user.getDisplayName();
Component prefix = user.getPrefix();
ModifiableString modifiableString = new ModifiableString(message);
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("sender", senderName),
Placeholder.component("prefix", prefix),
Placeholder.component("message", parseMessageContent(player, message)),
Placeholder.parsed("server", Bukkit.getServerName())
);
Component component = Utility.parseMiniMessage(Config.GCFORMAT, placeholders);
ModifiableString modifiableString = new ModifiableString(component);
// todo a better way for this
if (!RegexManager.filterText(player.getName(), player.getUniqueId(), modifiableString, "globalchat")) {
GalaxyUtility.sendBlockedNotification("GC Language",
@@ -107,27 +144,8 @@ public class ChatHandler {
"");
return; // the message was blocked
}
component = modifiableString.component();
String updatedMessage = modifiableString.string();
if(!player.hasPermission("chat.format")) {
updatedMessage = Utility.stripTokens(updatedMessage);
} else {
updatedMessage = Utility.parseColors(updatedMessage);
}
if(updatedMessage.contains("[i]"))
updatedMessage = updatedMessage.replace("[i]", "<[i]>");
updatedMessage = Utility.formatText(updatedMessage);
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("sender", Replacement.component(senderName));
placeholders.put("prefix", Replacement.component(prefix));
placeholders.put("message", Replacement.miniMessage(updatedMessage));
placeholders.put("server", Replacement.miniMessage(Bukkit.getServerName()));
placeholders.put("[i]", Replacement.component(itemComponent(player.getInventory().getItemInMainHand())));
Component component = Utility.parseMiniMessage(Config.GCFORMAT, placeholders);
user.setGcCooldown(System.currentTimeMillis());
sendPluginMessage(player, "globalchat", component);
}
@@ -143,7 +161,15 @@ public class ChatHandler {
ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
Component senderName = user.getDisplayName();
ModifiableString modifiableString = new ModifiableString(message);
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("sender", senderName),
Placeholder.component("message", parseMessageContent(player, message)),
Placeholder.parsed("server", Bukkit.getServerName()),
Placeholder.parsed("channel", channel.getChannelName())
);
Component component = Utility.parseMiniMessage(channel.getFormat(), placeholders);
ModifiableString modifiableString = new ModifiableString(component);
if(!RegexManager.filterText(player.getName(), player.getUniqueId(), modifiableString, channel.getChannelName())) {
GalaxyUtility.sendBlockedNotification(channel.getChannelName() + " Language",
player,
@@ -152,23 +178,7 @@ public class ChatHandler {
return; // the message was blocked
}
String updatedMessage = modifiableString.string();
if(!player.hasPermission("chat.format")) {
updatedMessage = Utility.stripTokens(updatedMessage);
}
if(updatedMessage.contains("[i]")) updatedMessage = updatedMessage.replace("[i]", "<[i]>");
updatedMessage = Utility.formatText(updatedMessage);
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("sender", Replacement.component(senderName));
placeholders.put("message", Replacement.miniMessage(updatedMessage));
placeholders.put("server", Replacement.miniMessage(Bukkit.getServerName()));
placeholders.put("channel", Replacement.miniMessage(channel.getChannelName()));
placeholders.put("[i]", Replacement.component(itemComponent(player.getInventory().getItemInMainHand())));
Component component = Utility.parseMiniMessage(channel.getFormat(), placeholders);
component = modifiableString.component();
if (channel.isProxy()) {
sendChatChannelMessage(player, channel.getChannelName(), "chatchannel", component);
@@ -203,11 +213,11 @@ public class ChatHandler {
// updatedMessage = Utility.stripTokens(updatedMessage);
// }
//
// if(updatedMessage.contains("[i]")) updatedMessage = updatedMessage.replace("[i]", "<[i]>");
// if(updatedMessage.contains("[i]")) updatedMessage = updatedMessage.replaceFirst("[i]", "<item>");
//
// updatedMessage = Utility.formatText(updatedMessage);
//
// List<Template> templates = new ArrayList<>(List.of(
// List<Placeholder> Placeholders = new ArrayList<>(List.of(
// Placeholder.miniMessage("sender", senderName),
// Placeholder.miniMessage("sendername", senderName),
// Placeholder.miniMessage("partyname", party.getPartyName()),
@@ -215,10 +225,10 @@ public class ChatHandler {
// Placeholder.miniMessage("server", Bukkit.getServerName()),
// Placeholder.miniMessage("[i]", itemComponent(player.getInventory().getItemInMainHand()))));
//
// Component component = Utility.parseMiniMessage(Config.PARTY_FORMAT, templates);
// Component component = Utility.parseMiniMessage(Config.PARTY_FORMAT, Placeholders);
//// sendPartyMessage(player, party.getPartyId(), component);
//
// Component spyMessage = Utility.parseMiniMessage(Config.PARTY_SPY, templates);
// Component spyMessage = Utility.parseMiniMessage(Config.PARTY_SPY, Placeholders);
// for(Player pl : Bukkit.getOnlinePlayers()) {
// if(pl.hasPermission(Config.SPYPERMISSION) && !party.getPartyUsersUuid().contains(pl.getUniqueId())) {
// pl.sendMessage(spyMessage);
@@ -313,4 +323,34 @@ public class ChatHandler {
}
// end - move these to util
private Component parseMessageContent(Player player, String rawMessage) {
TagResolver.Builder tagResolver = TagResolver.builder();
Utility.formattingPerms.forEach((perm, pair) -> {
if (player.hasPermission(perm)) {
tagResolver.resolver(pair.getX());
}
});
MiniMessage miniMessage = MiniMessage.builder().tags(tagResolver.build()).build();
Component component = miniMessage.deserialize(rawMessage);
for(ChatFilter chatFilter : RegexManager.getEmoteFilters()) {
component = component.replaceText(
TextReplacementConfig.builder()
.times(Config.EMOTELIMIT)
.match(chatFilter.getRegex())
.replacement(chatFilter.getReplacement()).build());
}
component = component
.replaceText(
TextReplacementConfig.builder()
.once()
.matchLiteral("[i]")
.replacement(ChatHandler.itemComponent(player.getInventory().getItemInMainHand()))
.build());
return component;
}
}
@@ -0,0 +1,61 @@
package com.alttd.chat.listeners;
import com.alttd.chat.config.Config;
import com.alttd.chat.managers.RegexManager;
import com.alttd.chat.objects.ChatFilter;
import com.alttd.chat.util.Utility;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerEditBookEvent;
import org.bukkit.inventory.meta.BookMeta;
import java.util.ArrayList;
import java.util.List;
public class BookListener implements Listener {
private final PlainTextComponentSerializer plainTextComponentSerializer = PlainTextComponentSerializer.plainText();
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onPlayerEditBookEvent(PlayerEditBookEvent event) {
BookMeta bookMeta = event.getNewBookMeta();
List<Component> pages = new ArrayList<>();
for (Component component : bookMeta.pages()) {
Component formatComponent = Component.text("%message%");
Component message = parseMessageContent(event.getPlayer(), plainTextComponentSerializer.serialize(component));
pages.add(formatComponent.replaceText(TextReplacementConfig.builder().match("%message%").replacement(message).build()));
}
bookMeta.pages(pages);
event.setNewBookMeta(bookMeta);
}
private Component parseMessageContent(Player player, String rawMessage) {
TagResolver.Builder tagResolver = TagResolver.builder();
Utility.formattingPerms.forEach((perm, pair) -> {
if (player.hasPermission(perm)) {
tagResolver.resolver(pair.getX());
}
});
MiniMessage miniMessage = MiniMessage.builder().tags(tagResolver.build()).build();
Component component = miniMessage.deserialize(rawMessage);
for(ChatFilter chatFilter : RegexManager.getEmoteFilters()) {
component = component.replaceText(
TextReplacementConfig.builder()
.times(Config.EMOTELIMIT)
.match(chatFilter.getRegex())
.replacement(chatFilter.getReplacement()).build());
}
return component;
}
}
@@ -5,89 +5,190 @@ import com.alttd.chat.config.Config;
import com.alttd.chat.handler.ChatHandler;
import com.alttd.chat.managers.ChatUserManager;
import com.alttd.chat.managers.RegexManager;
import com.alttd.chat.objects.ChatFilter;
import com.alttd.chat.objects.ChatUser;
import com.alttd.chat.objects.ModifiableString;
import com.alttd.chat.objects.Toggleable;
import com.alttd.chat.util.ALogger;
import com.alttd.chat.util.GalaxyUtility;
import com.alttd.chat.util.Utility;
import io.papermc.paper.chat.ChatRenderer;
import io.papermc.paper.event.player.AsyncChatCommandDecorateEvent;
import io.papermc.paper.event.player.AsyncChatDecorateEvent;
import io.papermc.paper.event.player.AsyncChatEvent;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.placeholder.Replacement;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class ChatListener implements Listener, ChatRenderer {
public class ChatListener implements Listener {
private final PlainTextComponentSerializer plainTextComponentSerializer = PlainTextComponentSerializer.plainText();
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onChatCommandDecorate(AsyncChatCommandDecorateEvent event) {
if (event.player() == null) return;
Component formatComponent = Component.text("%message%");
Component message = parseMessageContent(event.player(), plainTextComponentSerializer.serialize(event.originalMessage()));
event.result(formatComponent.replaceText(TextReplacementConfig.builder().match("%message%").replacement(message).build()));
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onChatDecorate(AsyncChatDecorateEvent event) {
if (event.player() == null) return;
Component formatComponent = Component.text("%message%");
Component message = parseMessageContent(event.player(), plainTextComponentSerializer.serialize(event.originalMessage()));
event.result(formatComponent.replaceText(TextReplacementConfig.builder().match("%message%").replacement(message).build()));
}
private final Component mention = MiniMessage.miniMessage().deserialize(Config.MENTIONPLAYERTAG);
@EventHandler(ignoreCancelled = true)
public void onPlayerChat(AsyncChatEvent event) {
event.setCancelled(true); //Always cancel the event because we do not want to deal with Microsoft's stupid bans
Toggleable toggleable = Toggleable.getToggleable(event.getPlayer().getUniqueId());
if (toggleable != null) {
toggleable.sendMessage(event.getPlayer(), event.message());
return;
}
if (ChatPlugin.getInstance().serverMuted() && !event.getPlayer().hasPermission("chat.bypass-server-muted")) {
event.setCancelled(true);
Player player = event.getPlayer();
GalaxyUtility.sendBlockedNotification("Chat Muted", player, event.message(), "");
return;
}
Player player = event.getPlayer();
// ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
event.viewers().removeIf(audience -> audience instanceof Player receiver
&& ChatUserManager.getChatUser(receiver.getUniqueId()).getIgnoredPlayers().contains(player.getUniqueId()));
Set<Player> receivers = event.viewers().stream().filter(audience -> audience instanceof Player)
.map(audience -> (Player) audience)
.filter(receiver -> !ChatUserManager.getChatUser(receiver.getUniqueId()).getIgnoredPlayers().contains(player.getUniqueId()))
.collect(Collectors.toSet());
Component input = event.message().colorIfAbsent(NamedTextColor.WHITE);
ModifiableString modifiableString = new ModifiableString(input);
Component input = event.message();
String message = PlainTextComponentSerializer.plainText().serialize(input);
ModifiableString modifiableString = new ModifiableString(message);
// todo a better way for this
if(!RegexManager.filterText(player.getName(), player.getUniqueId(), modifiableString, "chat")) {
event.setCancelled(true);
GalaxyUtility.sendBlockedNotification("Language", player,
Utility.parseMiniMessage(Utility.parseColors(modifiableString.string())),
modifiableString.component(),
"");
return; // the message was blocked
}
message = modifiableString.string();
if(!player.hasPermission("chat.format")) {
message = Utility.stripTokens(message);
} else {
message = Utility.parseColors(message);
Set<Player> playersToPing = new HashSet<>();
pingPlayers(playersToPing, modifiableString, player);
input = render(player, modifiableString.component());
for (Player receiver : receivers) {
receiver.sendMessage(input);
}
if(message.contains("[i]"))
message = message.replace("[i]", "<[i]>"); // end of todo
message = Utility.formatText(message);
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("message", Replacement.miniMessage(message));
placeholders.put("[i]", Replacement.component(ChatHandler.itemComponent(player.getInventory().getItemInMainHand())));
Component component = Utility.parseMiniMessage("<message>", placeholders);
event.message(component);
event.renderer(this);
for (Player pingPlayer : playersToPing) {
pingPlayer.playSound(pingPlayer.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1, 1);
}
ALogger.info(PlainTextComponentSerializer.plainText().serialize(input));
}
@Override
public @NotNull Component render(@NotNull Player player, @NotNull Component sourceDisplayName, @NotNull Component message, @NotNull Audience viewer) {
ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
private void pingPlayers(Set<Player> playersToPing, ModifiableString modifiableString, Player player) {
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
String name = onlinePlayer.getName();
String nickName = PlainTextComponentSerializer.plainText().serialize(onlinePlayer.displayName());
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("sender", Replacement.component(player.displayName()));
placeholders.put("sendername", Replacement.component(player.name()));
placeholders.put("prefix", Replacement.component(user.getPrefix()));
placeholders.put("prefixall", Replacement.component(user.getPrefixAll()));
placeholders.put("staffprefix", Replacement.component(user.getStaffPrefix()));
placeholders.put("message", Replacement.component(message));
Pattern namePattern = Pattern.compile("\\b(?<!\\\\)" + name + "\\b", Pattern.CASE_INSENSITIVE);
// Pattern escapedNamePattern = Pattern.compile("\\b\\\\" + name + "\\b", Pattern.CASE_INSENSITIVE);
Pattern nickPattern = Pattern.compile("\\b(?<!\\\\)" + nickName + "\\b", Pattern.CASE_INSENSITIVE);
// Pattern escapedNickPattern = Pattern.compile("\\b\\\\" + nickName + "\\b", Pattern.CASE_INSENSITIVE);
if (namePattern.matcher(modifiableString.string()).find()) {
modifiableString.replace(TextReplacementConfig.builder()
.once()
.match(namePattern)
.replacement(mention.append(onlinePlayer.displayName()))
.build());
//TODO replace all instances of \name with just name but using the match result so the capitalization doesn't change
// modifiableString.replace(TextReplacementConfig.builder()
// .once()
// .match(escapedNamePattern)
// .replacement((a, b) -> {
// String substring = a.group().substring(1);
// return ;
// });
if (!ChatUserManager.getChatUser(onlinePlayer.getUniqueId()).getIgnoredPlayers().contains(player.getUniqueId()))
playersToPing.add(onlinePlayer);
} else if (nickPattern.matcher(modifiableString.string()).find()) {
modifiableString.replace(TextReplacementConfig.builder()
.once()
.match(nickPattern)
.replacement(mention.append(onlinePlayer.displayName()))
.build());
if (!ChatUserManager.getChatUser(onlinePlayer.getUniqueId()).getIgnoredPlayers().contains(player.getUniqueId()))
playersToPing.add(onlinePlayer);
}
}
}
public @NotNull Component render(@NotNull Player player, @NotNull Component message) {
ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("sender", user.getDisplayName()),
Placeholder.parsed("sendername", player.getName()),
Placeholder.component("prefix", user.getPrefix()),
Placeholder.component("prefixall", user.getPrefixAll()),
Placeholder.component("staffprefix", user.getStaffPrefix()),
Placeholder.component("message", message)
);
return Utility.parseMiniMessage(Config.CHATFORMAT, placeholders);
}
private Component parseMessageContent(Player player, String rawMessage) {
TagResolver.Builder tagResolver = TagResolver.builder();
Utility.formattingPerms.forEach((perm, pair) -> {
if (player.hasPermission(perm)) {
tagResolver.resolver(pair.getX());
}
});
MiniMessage miniMessage = MiniMessage.builder().tags(tagResolver.build()).build();
Component component = miniMessage.deserialize(rawMessage);
for(ChatFilter chatFilter : RegexManager.getEmoteFilters()) {
component = component.replaceText(
TextReplacementConfig.builder()
.times(Config.EMOTELIMIT)
.match(chatFilter.getRegex())
.replacement(chatFilter.getReplacement()).build());
}
component = component
.replaceText(
TextReplacementConfig.builder()
.once()
.matchLiteral("[i]")
.replacement(ChatHandler.itemComponent(player.getInventory().getItemInMainHand()))
.build());
return component;
}
}
@@ -1,14 +1,18 @@
package com.alttd.chat.listeners;
import com.alttd.chat.config.Config;
import com.alttd.chat.config.ServerConfig;
import com.alttd.chat.database.Queries;
import com.alttd.chat.managers.ChatUserManager;
import com.alttd.chat.managers.RegexManager;
import com.alttd.chat.objects.ChatUser;
import com.alttd.chat.objects.ModifiableString;
import com.alttd.chat.objects.Toggleable;
import com.alttd.chat.util.GalaxyUtility;
import com.alttd.chat.util.Utility;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -17,15 +21,31 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class PlayerListener implements Listener {
private final ServerConfig serverConfig;
public PlayerListener(ServerConfig serverConfig) {
this.serverConfig = serverConfig;
}
@EventHandler
private void onPlayerLogin(PlayerJoinEvent event) {
UUID uuid = event.getPlayer().getUniqueId();
Player player = event.getPlayer();
GalaxyUtility.addAdditionalChatCompletions(player);
UUID uuid = player.getUniqueId();
Toggleable.disableToggles(uuid);
if (serverConfig.FIRST_JOIN_MESSAGES && System.currentTimeMillis() - player.getFirstPlayed() < TimeUnit.SECONDS.toMillis(10)) {
player.getServer().sendMessage(MiniMessage.miniMessage().deserialize(Config.FIRST_JOIN, Placeholder.parsed("player", player.getName())));
}
ChatUser user = ChatUserManager.getChatUser(uuid);
if(user != null) return;
// user failed to load - create a new one
ChatUser chatUser = new ChatUser(uuid, -1, null);
ChatUserManager.addUser(chatUser);
@@ -47,8 +67,8 @@ public class PlayerListener implements Listener {
for (int i = 0; i < 4; i++) {
Component component = event.line(i);
if (component != null) {
String message = PlainTextComponentSerializer.plainText().serialize(component);
ModifiableString modifiableString = new ModifiableString(message);
ModifiableString modifiableString = new ModifiableString(component);
Player player = event.getPlayer();
// todo a better way for this
@@ -58,9 +78,8 @@ public class PlayerListener implements Listener {
Utility.parseMiniMessage(Utility.parseColors(modifiableString.string())),
"");
}
message = modifiableString.string();
component = message == null ? Component.empty() : Component.text(message);
component = modifiableString.component() == null ? Component.empty() : modifiableString.component();
event.line(i, component);
}
@@ -47,7 +47,8 @@ public class PluginMessage implements PluginMessageListener {
p.sendMessage(GsonComponentSerializer.gson().deserialize(message));
p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1, 1); // todo load this from config
ChatUser user = ChatUserManager.getChatUser(uuid);
user.setReplyTarget(target);
if (!user.getReplyContinueTarget().equalsIgnoreCase(target))
user.setReplyTarget(target);
}
}
break;
@@ -61,9 +62,10 @@ public class PluginMessage implements PluginMessageListener {
if (p != null) {
ChatUser chatUser = ChatUserManager.getChatUser(uuid);
if (!chatUser.getIgnoredPlayers().contains(targetuuid)) {
chatUser.setReplyTarget(target);
p.sendMessage(GsonComponentSerializer.gson().deserialize(message));
ChatUser user = ChatUserManager.getChatUser(uuid);
user.setReplyTarget(target);
// ChatUser user = ChatUserManager.getChatUser(uuid);
// user.setReplyTarget(target);
}
}
break;
@@ -0,0 +1,225 @@
package com.alttd.chat.nicknames;
import com.alttd.chat.ChatPlugin;
import com.alttd.chat.config.Config;
import com.alttd.chat.database.Queries;
import com.alttd.chat.objects.Nick;
import com.alttd.chat.util.Utility;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.adventure.text.serializer.legacy.LegacyFormat;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.UUID;
public class NickUtilities
{
public static String stringRegen;
public static String applyColor(String message) {
ChatColor hexColor1 = null;
ChatColor hexColor2;
StringBuilder stringBuilder = new StringBuilder();
message = ChatColor.translateAlternateColorCodes('&', message);
boolean startsWithColor = false;
boolean lastColorMatters = false;
if (message.matches(".*" + NickUtilities.stringRegen + ".*")) {
String[] split = message.split(NickUtilities.stringRegen);
ArrayList<String> list = new ArrayList<>();
int nextIndex = 0;
if (message.indexOf("}") <= 11) {
startsWithColor = true;
list.add(message.substring(0, message.indexOf("}") + 1));
}
for (String s : split) {
nextIndex += s.length();
int tmp = message.indexOf("}", nextIndex);
if (tmp < message.length() && tmp>=0) {
list.add(message.substring(nextIndex, tmp + 1));
nextIndex = tmp + 1;
}
}
int i;
boolean firstLoop = true;
if (startsWithColor) {
i = -1;
} else {
i = 0;
stringBuilder.append(split[i]);
}
for (String s : list) {
boolean lesser = s.contains("<");
boolean bigger = s.contains(">");
if (bigger && lesser) {
hexColor2 = ChatColor.of(s.substring(1, s.length() - 3));
} else if (bigger || lesser) {
hexColor2 = ChatColor.of(s.substring(1, s.length() - 2));
} else {
hexColor2 = ChatColor.of(s.substring(1, s.length() -1));
}
if (firstLoop) {
lastColorMatters = bigger;
hexColor1 = hexColor2;
firstLoop = false;
i++;
continue;
}
if (lesser && lastColorMatters) {
stringBuilder.append(hexGradient(hexColor1.getColor(), hexColor2.getColor(), split[i]));
} else {
stringBuilder.append(hexColor1).append(split[i]);
}
hexColor1 = hexColor2;
lastColorMatters = bigger;
i++;
}
if (split.length > i){
stringBuilder.append(hexColor1).append(split[i]);
}
}
return stringBuilder.length()==0 ? message : stringBuilder.toString();
}
public static String removeAllColors(String string) {
for (final String colorCodes : Config.NICK_ALLOWED_COLOR_CODESLIST) {
string = string.replace(colorCodes, "");
}
return string.replaceAll("\\{#[A-Fa-f0-9]{6}(<)?(>)?}", "");
}
static {
NickUtilities.stringRegen = "\\{#[A-Fa-f0-9]{6}(<)?(>)?}";
}
public static String hexGradient(Color color1, Color color2, String text){
double r = color1.getRed();
double g = color1.getGreen();
double b = color1.getBlue();
double rDifference = (color1.getRed() - color2.getRed()) / ((double) text.length() - 1);
double gDifference = (color1.getGreen() - color2.getGreen()) / ((double) text.length() - 1);
double bDifference = (color1.getBlue() - color2.getBlue()) / ((double) text.length() - 1);
StringBuilder stringBuilder = new StringBuilder();
char[] chars = text.toCharArray();
for (int i = 0; i < text.length(); i++) {
if (i > 0) {
r = r - rDifference;
g = g - gDifference;
b = b - bDifference;
}
stringBuilder.append(ChatColor.of(new Color((int) r, (int) g, (int) b))).append(chars[i]);
}
return stringBuilder.toString();
}
public static void updateCache() {
if (!Nicknames.getInstance().nickCacheUpdate.isEmpty()){
Nicknames.getInstance().nickCacheUpdate.forEach(uuid ->{
Nick nick = Queries.getNick(uuid);
if (nick == null){
Nicknames.getInstance().NickCache.remove(uuid);
} else {
Nicknames.getInstance().NickCache.put(uuid, nick);
}
});
}
}
public static boolean validNick(Player sender, OfflinePlayer target, String nickName) {
if (!noBlockedCodes(nickName)) {
sender.sendMiniMessage(Config.NICK_BLOCKED_COLOR_CODES, null);
return false;
}
if (!Utility.checkNickBrightEnough(nickName)) {
sender.sendMiniMessage("<red>At least one color must be brighter than 30 for each color</red>", null);
return false;
}
String cleanNick = NickUtilities.removeAllColors(nickName);
if (cleanNick.length() < 3 || cleanNick.length() > 16) {
sender.sendMiniMessage(Config.NICK_INVALID_LENGTH, null);
return false;
}
if (!cleanNick.matches("[a-zA-Z0-9_]*") || nickName.length() > 192) { //192 is if someone puts {#xxxxxx<>} in front of every letter
sender.sendMiniMessage(Config.NICK_INVALID_CHARACTERS, null);
return false;
}
if (cleanNick.equalsIgnoreCase(target.getName())) {
return true;
}
for (Nick nick : Nicknames.getInstance().NickCache.values()){
if (!nick.getUuid().equals(target.getUniqueId())
&& ((nick.getCurrentNickNoColor() != null && nick.getCurrentNickNoColor().equalsIgnoreCase(cleanNick))
|| (nick.getNewNickNoColor() != null && nick.getNewNickNoColor().equalsIgnoreCase(cleanNick)))){
UUID uuid = nick.getUuid();
UUID uniqueId = target.getUniqueId();
if (uniqueId.equals(uuid)){
ChatPlugin.getInstance().getLogger().info(uuid + " " + uniqueId);
}
sender.sendMiniMessage(Config.NICK_TAKEN, null);
return false;
}
}
return true;
}
public static boolean noBlockedCodes(final String getNick) {
for (final String blockedCodes : Config.NICK_BLOCKED_COLOR_CODESLIST) {
if (getNick.contains(blockedCodes)) {
return false;
}
}
return true;
}
public static void bungeeMessageHandled(UUID uniqueId, Player player, String channel) {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
// out.writeUTF("Forward"); // So BungeeCord knows to forward it
// out.writeUTF("ALL");
out.writeUTF("NickName" + channel); // The channel name to check if this your data
ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
DataOutputStream msgout = new DataOutputStream(msgbytes);
try {
msgout.writeUTF(uniqueId.toString());
} catch (IOException exception){
exception.printStackTrace();
return;
}
byte[] bytes = msgbytes.toByteArray();
out.writeShort(bytes.length);
out.write(bytes);
player.sendPluginMessage(ChatPlugin.getInstance(), Config.MESSAGECHANNEL, out.toByteArray());
}
}
@@ -0,0 +1,446 @@
package com.alttd.chat.nicknames;
import com.Zrips.CMI.CMI;
import com.Zrips.CMI.Containers.CMIUser;
import com.alttd.chat.ChatAPI;
import com.alttd.chat.ChatPlugin;
import com.alttd.chat.config.Config;
import com.alttd.chat.database.Queries;
import com.alttd.chat.events.NickEvent;
import com.alttd.chat.managers.ChatUserManager;
import com.alttd.chat.objects.ChatUser;
import com.alttd.chat.objects.Nick;
import com.alttd.chat.util.Utility;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.luckperms.api.LuckPerms;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.*;
public class Nicknames implements CommandExecutor, TabCompleter {
static Nicknames instance;
HashMap<UUID, Nick> NickCache;
ArrayList<UUID> nickCacheUpdate;
public Nicknames() {
instance = this;
NickCache = new HashMap<>();
nickCacheUpdate = new ArrayList<>();
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
if (sender instanceof Player player) {
if (args.length == 0) {
sender.sendMessage(Utility.parseMiniMessage(helpMessage(sender, HelpType.ALL)));
return true;
}
switch (args[0].toLowerCase()) {
case "set":
if (args.length == 2 && hasPermission(sender, "chat.command.nick.set")) {
handleNick(player, player, args[1]);
} else if (args.length == 3 && hasPermission(sender, "chat.command.nick.set.others")) {
OfflinePlayer offlinePlayer = sender.getServer().getOfflinePlayer(args[1]);
if (offlinePlayer.isOnline() || offlinePlayer.hasPlayedBefore()) {
handleNick(player, offlinePlayer, args[2]);
} else {
sender.sendMessage(Utility.parseMiniMessage(helpMessage(sender, HelpType.SET_OTHERS)));
}
} else if (args.length > 3) {
sender.sendMessage(Utility.parseMiniMessage(helpMessage(sender, HelpType.SET_SELF, HelpType.SET_OTHERS)));
}
break;
case "review":
if (args.length == 1 && hasPermission(sender, "chat.command.nick.review")) {
NicknamesGui nicknamesGui = new NicknamesGui();
ChatPlugin.getInstance().getServer().getPluginManager().registerEvents(nicknamesGui, ChatPlugin.getInstance());
nicknamesGui.openInventory(player);
} else {
sender.sendMessage(Utility.parseMiniMessage(helpMessage(sender, HelpType.REVIEW)));
}
break;
case "request":
if (args.length == 2 && hasPermission(sender, "chat.command.nick.request")) {
new BukkitRunnable() {
@Override
public void run() {
handleNickRequest(player, args[1]);
}
}.runTaskAsynchronously(ChatPlugin.getInstance());
} else {
sender.sendMessage(Utility.parseMiniMessage(helpMessage(sender, HelpType.REQUEST)));
}
break;
case "try":
if (args.length == 2 && hasPermission(sender, "chat.command.nick.try")) {
LuckPerms api = ChatAPI.get().getLuckPerms();
if (api != null) {
if (NickUtilities.validNick(player, player, args[1])) {
sender.sendMessage(Utility.parseMiniMessage(Config.NICK_TRYOUT,
Placeholder.component("prefix", Utility.applyColor(api.getUserManager().getUser(player.getUniqueId())
.getCachedData().getMetaData().getPrefix())), // TODO pull this from chatuser?
Placeholder.component("nick", Utility.applyColor(args[1]))));
}
} else {
sender.sendMessage(Utility.parseMiniMessage(Config.NICK_NO_LUCKPERMS));
}
} else {
sender.sendMessage(Utility.parseMiniMessage(helpMessage(sender, HelpType.TRY)));
}
break;
case "current":
if (hasPermission(sender, "chat.command.nick.current")) {
ChatUser chatUser = ChatUserManager.getChatUser(player.getUniqueId());
TagResolver placeholders = TagResolver.resolver(
Placeholder.component("nickname", chatUser.getDisplayName()),
Placeholder.parsed("currentnickname", chatUser.getNickNameString())
);
player.sendMiniMessage(Config.NICK_CURRENT, placeholders);
}
break;
case "help":
sender.sendMessage(Utility.parseMiniMessage(helpMessage(sender, HelpType.ALL)
+ "For more info on nicknames and how to use rgb colors go to: <aqua>https://alttd.com/nicknames<white>"));
break;
default:
sender.sendMessage(Utility.parseMiniMessage(helpMessage(sender, HelpType.ALL)));
}
} else {
sender.sendMessage("Console commands are disabled.");
}
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
List<String> completions = new ArrayList<>();
if (!sender.hasPermission("chat.command.nick")) return completions;
if (args.length == 1) {
List<String> choices = new ArrayList<>();
if (sender.hasPermission("chat.command.nick.set")) {
choices.add("set");
}
if (sender.hasPermission("chat.command.nick.review")) {
choices.add("review");
}
if (sender.hasPermission("chat.command.nick.request")) {
choices.add("request");
}
if (sender.hasPermission("chat.command.nick.try")) {
choices.add("try");
}
if (sender.hasPermission("chat.command.nick.current")) {
choices.add("current");
}
choices.add("help");
for (String s : choices) {
if (s.startsWith(args[0])) {
completions.add(s);
}
}
} else if (args.length == 2) {
if (args[0].equalsIgnoreCase("set")) {
List<String> choices = new ArrayList<>();
List<String> onlinePlayers = new ArrayList<>();
Bukkit.getOnlinePlayers().forEach(a -> onlinePlayers.add(a.getName()));
if (sender.hasPermission("chat.command.nick.set.others")) {
choices.addAll(onlinePlayers);
}
for (String s : choices) {
if (s.startsWith(args[1])) {
completions.add(s);
}
}
}
}
return completions;
}
private void handleNickRequest(Player player, String nickName) {
if (!NickUtilities.validNick(player, player, nickName)) {
return;
}
NickUtilities.updateCache();
UUID uniqueId = player.getUniqueId();
if (NickCache.containsKey(uniqueId)) {
Nick nick = NickCache.get(uniqueId);
long timeSinceLastChange = new Date().getTime() - nick.getLastChangedDate();
long waitTime = Config.NICK_WAIT_TIME;
if (timeSinceLastChange > waitTime || player.hasPermission("chat.command.nick.bypasswaittime")) {
if (nick.hasRequest()) {
player.sendMessage(Utility.parseMiniMessage(Config.NICK_REQUEST_PLACED,
Placeholder.component("oldrequestednick", Utility.applyColor(nick.getNewNick())),
Placeholder.component("newrequestednick", Utility.applyColor(nickName))));
}
nick.setNewNick(nickName);
nick.setRequestedDate(new Date().getTime());
} else {
player.sendMessage(Utility.parseMiniMessage(Config.NICK_TOO_SOON,
Placeholder.unparsed("time", formatTime((timeSinceLastChange-waitTime)*-1))));
return;
}
} else {
NickCache.put(uniqueId, new Nick(uniqueId, null, 0, nickName, new Date().getTime()));
}
Queries.newNicknameRequest(uniqueId, nickName);
bungeeMessageRequest(player);
player.sendMessage(Utility.parseMiniMessage(Config.NICK_REQUESTED,
Placeholder.component("nick", Utility.applyColor(nickName))));
}
private void bungeeMessageRequest(Player player) {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
UUID uniqueId = player.getUniqueId();
// out.writeUTF("Forward"); // So BungeeCord knows to forward it
// out.writeUTF("ALL");
out.writeUTF("NickNameRequest"); // The channel name to check if this your data
ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
DataOutputStream msgout = new DataOutputStream(msgbytes);
try {
msgout.writeUTF(uniqueId.toString());
} catch (IOException exception) {
exception.printStackTrace();
return;
}
byte[] bytes = msgbytes.toByteArray();
out.writeShort(bytes.length);
out.write(bytes);
player.sendPluginMessage(ChatPlugin.getInstance(), Config.MESSAGECHANNEL, out.toByteArray());
Nicknames.getInstance().nickCacheUpdate.add(uniqueId);
}
private String formatTime(long timeInMillis) {
long second = (timeInMillis / 1000) % 60;
long minute = (timeInMillis / (1000 * 60)) % 60;
long hour = (timeInMillis / (1000 * 60 * 60)) % 24;
long days = (timeInMillis / (1000 * 60 * 60 * 24));
StringBuilder stringBuilder = new StringBuilder();
if (days!=0) {
stringBuilder.append(days).append(" days ");
}
if (days!=0 || hour!=0) {
stringBuilder.append(hour).append(" hours ");
}
if (days!=0 || hour!=0 || minute != 0) {
stringBuilder.append(minute).append(" minutes and ");
}
stringBuilder.append(second).append(" seconds");
return stringBuilder.toString();
}
private void handleNick(Player sender, OfflinePlayer target, final String nickName) {
if (nickName.equalsIgnoreCase("off")) {
try {
if (target.isOnline()) {
resetNick(target.getPlayer());
}
Queries.removePlayerFromDataBase(target.getUniqueId());
NickCache.remove(target.getUniqueId());
nickCacheUpdate.add(target.getUniqueId());
} catch (SQLException e) {
e.printStackTrace();
}
if (!sender.equals(target)) {
sender.sendMessage(Utility.parseMiniMessage(Config.NICK_RESET_OTHERS,
Placeholder.unparsed("player", target.getName())));
}
if (target.isOnline() && target.getPlayer() != null) {
target.getPlayer().sendMessage(Utility.parseMiniMessage(Config.NICK_RESET));
}
NickEvent nickEvent = new NickEvent(sender.getName(), target.getName(), null, NickEvent.NickEventType.RESET);
nickEvent.callEvent();
} else if (NickUtilities.validNick(sender, target, nickName)) {
if (target.isOnline()) {
setNick(target.getPlayer(), nickName);
} else {
NickUtilities.bungeeMessageHandled(target.getUniqueId(), sender, "Set");
}
Queries.setNicknameInDatabase(target.getUniqueId(), nickName);
NickEvent nickEvent = new NickEvent(sender.getName(), target.getName(), nickName, NickEvent.NickEventType.SET);
nickEvent.callEvent();
if (NickCache.containsKey(target.getUniqueId())) {
Nick nick = NickCache.get(target.getUniqueId());
nick.setCurrentNick(nickName);
nick.setLastChangedDate(new Date().getTime());
setNick(target.getPlayer(), nickName);
} else {
NickCache.put(target.getUniqueId(), new Nick(target.getUniqueId(), nickName, new Date().getTime()));
}
if (!sender.equals(target)) {
sender.sendMessage(Utility.parseMiniMessage(Config.NICK_CHANGED_OTHERS,
Placeholder.unparsed("targetplayer", target.getName()),
Placeholder.unparsed("nickname", nickName)));
if (target.isOnline()) {
target.getPlayer().sendMessage(Utility.parseMiniMessage(Config.NICK_TARGET_NICK_CHANGE,
Placeholder.unparsed("nickname", getNick(target.getPlayer())),
Placeholder.unparsed("sendernick", getNick(sender)),
Placeholder.unparsed("player", target.getName())));
}
} else if (target.isOnline()) {
target.getPlayer().sendMessage(Utility.parseMiniMessage(Config.NICK_CHANGED,
Placeholder.unparsed("nickname", getNick(target.getPlayer()))));
}
}
}
private String helpMessage(final CommandSender sender, final HelpType... helpTypes) {
StringBuilder message = new StringBuilder();
for (HelpType helpType : helpTypes) {
if (helpType.equals(HelpType.ALL)) {
return helpMessage(sender, helpType);
}
message.append(helpMessage(sender, helpType));
}
return message.toString();
}
private String helpMessage(CommandSender sender, HelpType type) {
StringBuilder message = new StringBuilder();
switch (type) {
case ALL:
message.append(helpMessage(sender, HelpType.SET_SELF));
message.append(helpMessage(sender, HelpType.SET_OTHERS));
message.append(helpMessage(sender, HelpType.REQUEST));
message.append(helpMessage(sender, HelpType.REVIEW));
message.append(helpMessage(sender, HelpType.TRY));
break;
case SET_SELF:
if (sender.hasPermission("chat.command.nick.set")) {
message.append("<gold>/nick set <nickname><white> - Sets your nickname to the specified name.\n");
}
break;
case SET_OTHERS:
if (sender.hasPermission("chat.command.nick.set.others")) {
message.append("<gold>/nick set <username> <nickname><white> - Sets the specified user's nickname to the specified name.\n");
}
break;
case REQUEST:
if (sender.hasPermission("chat.command.nick.request")) {
message.append("<gold>/nick request <nickname><white> - Requests a username to be reviewed by staff.\n" +
" <gray>Try using <dark_gray>/nick try <nickname><gray> to see if you like the name, you can only change it once per day!\n");
}
break;
case REVIEW:
if (sender.hasPermission("chat.command.nick.review")) {
message.append("<gold>/nick review<white> - Opens the nickname review GUI (left click to accept a nick, right click to deny it)\n");
}
break;
case TRY:
if (sender.hasPermission("chat.command.nick.try")) {
message.append("<gold>/nick try <nickname><white> - Shows you what your nickname will look like in chat.\n");
}
}
return message.toString();
}
private boolean hasPermission(CommandSender sender, String permission) {
if (!sender.hasPermission(permission)) {
sender.sendMessage(Utility.parseMiniMessage(Config.NO_PERMISSION));
return false;
}
return true;
}
public void resetNick(final Player player) {
ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
user.setDisplayName(player.getName());
player.displayName(user.getDisplayName());
updateCMIUser(player, null);
}
public String getNick(final Player player) {
ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
return user.getNickNameString();
}
public void setNick(final Player player, final String nickName) {
if (player == null)
return;
ChatUser user = ChatUserManager.getChatUser(player.getUniqueId());
user.setDisplayName(nickName);
player.displayName(user.getDisplayName());
updateCMIUser(player, nickName);
}
// public static String format(final String m) {
// return NickUtilities.applyColor(m);
// }
public void updateCMIUser(Player player, String nickName) {
if (!isCMIEnabled())
return;
CMIUser cmiUser = CMI.getInstance().getPlayerManager().getUser(player);
if (nickName == null){
cmiUser.setNickName(null, true);
} else {
cmiUser.setNickName(NickUtilities.applyColor(nickName), true);
}
cmiUser.updateDisplayName();
}
private Boolean isCMIEnabled = null;
private Boolean isCMIEnabled() {
if (!(isCMIEnabled == null))
return isCMIEnabled;
Plugin plugin = Bukkit.getPluginManager().getPlugin("CMI");
if (plugin != null && plugin.isEnabled())
return isCMIEnabled = true;
return isCMIEnabled = false;
}
public static Nicknames getInstance() {
return Nicknames.instance;
}
private enum HelpType {
ALL,
SET_SELF,
SET_OTHERS,
REVIEW,
REQUEST,
TRY
}
}
@@ -0,0 +1,195 @@
package com.alttd.chat.nicknames;
import com.Zrips.CMI.commands.list.colorlimits;
import com.Zrips.CMI.utils.Util;
import com.alttd.chat.ChatPlugin;
import com.alttd.chat.config.Config;
import com.alttd.chat.database.Queries;
import com.alttd.chat.managers.ChatUserManager;
import com.alttd.chat.objects.ChatUser;
import com.alttd.chat.objects.Nick;
import com.alttd.chat.util.ALogger;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.messaging.PluginMessageListener;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.util.UUID;
public class NicknamesEvents implements Listener, PluginMessageListener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerJoin(PlayerJoinEvent e) {
new BukkitRunnable() {
@Override
public void run() {
if (Nicknames.instance.NickCache.isEmpty()) {
Queries.getNicknamesList().forEach(nick -> Nicknames.instance.NickCache.put(nick.getUuid(), nick));
}
final Player player = e.getPlayer();
final Nick nick = Queries.getNick(player.getUniqueId());
if (nick == null) {
Nicknames.getInstance().resetNick(player);
return;
}
String nickName = nick.getCurrentNick();
String strippedNick = Nicknames.getInstance().getNick(player);
try {
strippedNick = MiniMessage.miniMessage().stripTags(Nicknames.getInstance().getNick(player));
} catch (NullPointerException ignored) {
}
// final String strippedNick = CMIChatColor.stripColor(Nicknames.getInstance().getNick(player));
// final String cmiNick = Util.CMIChatColor.deColorize(Nicknames.getInstance().getNick(player));
if (nickName == null) {
Nicknames.getInstance().resetNick(player);
} else if (!nickName.equals(strippedNick)) {
Nicknames.getInstance().setNick(player, nickName);
}
Nicknames.getInstance().NickCache.put(e.getPlayer().getUniqueId(), nick);
if (player.hasPermission("chat.command.nick.review")) {
int i = 0;
for (Nick iNick : Nicknames.getInstance().NickCache.values()) {
if (iNick.hasRequest()) {
i++;
}
}
if (i > 0) {
player.sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_REQUESTS_ON_LOGIN,
Placeholder.unparsed("amount", String.valueOf(i))));
}
}
}
}.runTaskAsynchronously(ChatPlugin.getInstance());
}
@Override
public void onPluginMessageReceived(String channel, @NotNull Player player, byte[] message) {
if (!channel.equals(Config.MESSAGECHANNEL)) {
return;
}
ByteArrayDataInput in = ByteStreams.newDataInput(message);
String subChannel = in.readUTF();
ALogger.info(channel + ": " + subChannel);
if (!subChannel.equals("NickNameRequest") && !subChannel.equals("NickNameAccepted")
&& !subChannel.equals("NickNameDenied") && !subChannel.equals("NickNameSet")) {
return;
}
UUID playerUUID;
OfflinePlayer offlinePlayer;
String name;
try {
short len = in.readShort();
byte[] msgbytes = new byte[len];
in.readFully(msgbytes);
DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes));
playerUUID = UUID.fromString(msgin.readUTF());
offlinePlayer = ChatPlugin.getInstance().getServer().getOfflinePlayer(playerUUID);
name = offlinePlayer.getName() == null ? playerUUID.toString() : offlinePlayer.getName();
} catch (Exception e) {
e.printStackTrace();
return;
}
MiniMessage miniMessage = MiniMessage.miniMessage();
switch (subChannel) {
case "NickNameRequest":
Component component = miniMessage.deserialize(Config.NICK_REQUEST_NEW, Placeholder.parsed("player", name))
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND,
"/nick review"))
.hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT,
miniMessage.deserialize("<gold>Click this text to review the request!")));
ChatPlugin.getInstance().getServer().getOnlinePlayers().forEach(p -> {
if (p.hasPermission("chat.command.nick.review")) {
p.sendMessage(component);
}
});
Nicknames.getInstance().nickCacheUpdate.add(playerUUID);
if (offlinePlayer.isOnline()) {
Nick nick = Queries.getNick(playerUUID);
if (nick != null && nick.getCurrentNick() != null) {
Nicknames.getInstance().setNick(offlinePlayer.getPlayer(), nick.getCurrentNick());
}
}
break;
case "NickNameAccepted":
Component deserialize = miniMessage.deserialize("<green><name>'s nickname was accepted!",
Placeholder.unparsed("name", name));
ChatPlugin.getInstance().getServer().getOnlinePlayers().forEach(p -> {
if (p.hasPermission("chat.command.nick.review")) {
p.sendMessage(deserialize);
}
});
//No break on purpose
case "NickNameSet":
Nicknames.getInstance().nickCacheUpdate.add(playerUUID);
if (offlinePlayer.isOnline()) {
Nick nick = Queries.getNick(playerUUID);
Player target = Bukkit.getPlayer(playerUUID);
if (target != null && nick != null && nick.getCurrentNick() != null) {
Nicknames.getInstance().setNick(target, nick.getCurrentNick());
target.sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_CHANGED,
Placeholder.unparsed("nickname", nick.getCurrentNick())));
}
}
break;
case "NickNameDenied":
final Component messageDenied = miniMessage.deserialize("<red><name>'s nickname was denied",
Placeholder.unparsed("name", name));
Nick nick = Nicknames.getInstance().NickCache.get(playerUUID);
ChatPlugin.getInstance().getServer().getOnlinePlayers().forEach(p -> {
if (p.hasPermission("chat.command.nick.review")) {
p.sendMessage(messageDenied);
}
});
if (nick.getCurrentNick() == null) {
Nicknames.getInstance().NickCache.remove(playerUUID);
} else {
nick.setNewNick(null);
nick.setRequestedDate(0);
Nicknames.getInstance().NickCache.put(playerUUID, nick);
}
if (offlinePlayer.isOnline()) {
Player target = Bukkit.getPlayer(playerUUID);
if (target == null) break;
target.sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_NOT_CHANGED,
Placeholder.unparsed("nickname", nick.getCurrentNick())));
}
break;
}
}
}
@@ -0,0 +1,297 @@
package com.alttd.chat.nicknames;
import com.alttd.chat.ChatPlugin;
import com.alttd.chat.config.Config;
import com.alttd.chat.database.Queries;
import com.alttd.chat.events.NickEvent;
import com.alttd.chat.objects.Nick;
import com.alttd.chat.util.Utility;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
public class NicknamesGui implements Listener {
private final Inventory inv;
private final int currentPage;
public NicknamesGui() {
// Create a new inventory, with no owner (as this isn't a real inventory)
inv = Bukkit.createInventory(null, 36, Utility.parseMiniMessage("Nicknames GUI"));
// Put the items into the inventory
currentPage = 1;
setItems(currentPage);
}
public void setItems(int currentPage) {
new BukkitRunnable() {
@Override
public void run() {
inv.clear();
NickUtilities.updateCache();
boolean hasNextPage = false;
int i = (currentPage - 1) * 27; //TODO set to 1 or 2 to test
int limit = i / 27;
for (Nick nick : Nicknames.getInstance().NickCache.values()) {
if (nick.hasRequest()) {
if (limit >= i / 27) {
inv.setItem(i % 27, createPlayerSkull(nick, Config.NICK_ITEM_LORE));
i++;
} else {
hasNextPage = true;
break;
}
}
}
if (currentPage != 1) {
inv.setItem(28, createGuiItem(Material.PAPER, "§bPrevious page",
"§aCurrent page: %page%".replace("%page%", String.valueOf(currentPage)),
"§aPrevious page: %previousPage%".replace("%previousPage%", String.valueOf(currentPage - 1))));
}
if (hasNextPage) {
inv.setItem(36, createGuiItem(Material.PAPER, "§bNext page",
"§aCurrent page: %page%".replace("%page%", String.valueOf(currentPage)),
"§aNext page: §b%nextPage%".replace("%nextPage%", String.valueOf(currentPage + 1))));
}
}
}.runTaskAsynchronously(ChatPlugin.getInstance());
}
private ItemStack createPlayerSkull(Nick nick, List<String> lore) {
MiniMessage miniMessage = MiniMessage.miniMessage();
ItemStack playerHead = new ItemStack(Material.PLAYER_HEAD);
SkullMeta meta = (SkullMeta) playerHead.getItemMeta();
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(nick.getUuid());
meta.setOwningPlayer(offlinePlayer);
String name = offlinePlayer.getName();
if (name == null)
meta.displayName(miniMessage.deserialize("UNKNOWN PLAYER NAME"));
else
meta.displayName(miniMessage.deserialize(offlinePlayer.getName()));
TagResolver resolver = TagResolver.resolver(
Placeholder.component("newnick", Utility.applyColor(nick.getNewNick())),
Placeholder.component("oldnick", Utility.applyColor(nick.getCurrentNick() == null ? "None" : nick.getCurrentNick())),
Placeholder.unparsed("lastchanged", nick.getLastChangedDate() == 0 ? "Not Applicable" : nick.getLastChangedDateFormatted()));
meta.lore(lore.stream().map(a -> miniMessage.deserialize(a, resolver)).collect(Collectors.toList()));
playerHead.setItemMeta(meta);
return playerHead;
}
// Nice little method to create a gui item with a custom name, and description
private ItemStack createGuiItem(final Material material, final String name, final String... lore) {
final ItemStack item = new ItemStack(material, 1);
final ItemMeta meta = item.getItemMeta();
// Set the name of the item
meta.displayName(Component.text(name));
// Set the lore of the item
MiniMessage miniMessage = MiniMessage.miniMessage();
meta.lore(Arrays.stream(lore).map(miniMessage::deserialize).collect(Collectors.toList()));
item.setItemMeta(meta);
return item;
}
// You can open the inventory with this
public void openInventory(final HumanEntity ent) {//Possibly with a boolean to show if it should get from cache or update cache
ent.openInventory(inv);
}
// Check for clicks on items
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onInventoryClick(InventoryClickEvent e) {
if (e.getInventory() != inv) return;
e.setCancelled(true);
final ItemStack clickedItem = e.getCurrentItem();
if (clickedItem == null || clickedItem.getType() == Material.AIR) return;
final Player p = (Player) e.getWhoClicked();
if (clickedItem.getType().equals(Material.PAPER)) {
String serialize = PlainTextComponentSerializer.plainText().serialize(clickedItem.getItemMeta().displayName());
if (serialize.equals("Next Page")) {
setItems(currentPage + 1);
}
} else if (clickedItem.getType().equals(Material.PLAYER_HEAD)) {
SkullMeta meta = (SkullMeta) clickedItem.getItemMeta();
if (meta.hasEnchants()) {
return;
}
OfflinePlayer owningPlayer = meta.getOwningPlayer();
if (owningPlayer == null) {
p.sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_USER_NOT_FOUND));
return;
}
new BukkitRunnable() {
@Override
public void run() {
NickUtilities.updateCache();
Nick nick;
UUID uniqueId = owningPlayer.getUniqueId();
if (Nicknames.getInstance().NickCache.containsKey(uniqueId)) {
nick = Nicknames.getInstance().NickCache.get(uniqueId);
} else {
nick = Queries.getNick(uniqueId);
}
if (nick == null || !nick.hasRequest()) {
p.sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_ALREADY_HANDLED,
Placeholder.component("targetplayer", clickedItem.getItemMeta().displayName())));
return;
}
if (e.isLeftClick()) {
if (owningPlayer.hasPlayedBefore()) {
Queries.acceptNewNickname(uniqueId, nick.getNewNick());
String newNick = nick.getNewNick();
new BukkitRunnable() {
@Override
public void run() {
NickEvent nickEvent = new NickEvent(e.getWhoClicked().getName(), clickedItem.getItemMeta().getDisplayName(), newNick, NickEvent.NickEventType.ACCEPTED);
nickEvent.callEvent();
}
}.runTask(ChatPlugin.getInstance());
p.sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_ACCEPTED,
Placeholder.component("targetplayer", clickedItem.getItemMeta().displayName()),
Placeholder.component("newnick", Utility.applyColor(nick.getNewNick())),
Placeholder.component("oldnick", Utility.applyColor(nick.getCurrentNick() == null ? clickedItem.getItemMeta().getDisplayName() : nick.getCurrentNick()))));
if (owningPlayer.isOnline() && owningPlayer.getPlayer() != null) {
Nicknames.getInstance().setNick(owningPlayer.getPlayer(), nick.getNewNick());
// owningPlayer.getPlayer().sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_CHANGED // This message is also send when the plugin message is received
// .replace("%nickname%", nick.getNewNick())));
}
NickUtilities.bungeeMessageHandled(uniqueId, e.getWhoClicked().getServer().getPlayer(e.getWhoClicked().getName()), "Accepted");
nick.setCurrentNick(nick.getNewNick());
nick.setLastChangedDate(new Date().getTime());
nick.setNewNick(null);
nick.setRequestedDate(0);
Nicknames.getInstance().NickCache.put(uniqueId, nick);
ItemStack itemStack = new ItemStack(Material.SKELETON_SKULL);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.displayName(clickedItem.getItemMeta().displayName());
itemMeta.lore(clickedItem.lore());
itemStack.setItemMeta(itemMeta);
e.getInventory().setItem(e.getSlot(), itemStack);
p.updateInventory();
} else {
p.sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_PLAYER_NOT_ONLINE,
Placeholder.component("playerName", clickedItem.getItemMeta().displayName())));
}
} else if (e.isRightClick()) {
Component displayName = clickedItem.getItemMeta().displayName();
if (owningPlayer.hasPlayedBefore()) {
Queries.denyNewNickname(uniqueId);
String newNick = nick.getNewNick();
new BukkitRunnable() {
@Override
public void run() {
NickEvent nickEvent = new NickEvent(e.getWhoClicked().getName(), clickedItem.getItemMeta().getDisplayName(), newNick, NickEvent.NickEventType.DENIED);
nickEvent.callEvent();
}
}.runTask(ChatPlugin.getInstance());
p.sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_DENIED,
Placeholder.unparsed("targetplayer", owningPlayer.getName()),
Placeholder.component("newnick", Utility.applyColor(nick.getNewNick())),
Placeholder.component("oldnick", Utility.applyColor(nick.getCurrentNick() == null ? owningPlayer.getName() : nick.getCurrentNick()))));
if (Nicknames.getInstance().NickCache.containsKey(uniqueId)
&& Nicknames.getInstance().NickCache.get(uniqueId).getCurrentNick() != null) {
nick.setNewNick(null);
nick.setRequestedDate(0);
Nicknames.getInstance().NickCache.put(uniqueId, nick);
} else {
Nicknames.getInstance().NickCache.remove(uniqueId);
}
if (owningPlayer.isOnline() && owningPlayer.getPlayer() != null) {
Nicknames.getInstance().setNick(owningPlayer.getPlayer(), nick.getCurrentNick() == null ? owningPlayer.getName() : nick.getCurrentNick());
owningPlayer.getPlayer().sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_NOT_CHANGED));
}
NickUtilities.bungeeMessageHandled(uniqueId, e.getWhoClicked().getServer().getPlayer(e.getWhoClicked().getName()), "Denied");
final Component messageDenied = MiniMessage.miniMessage().deserialize("<red><name>'s nickname was denied!",
Placeholder.unparsed("name", owningPlayer.getName()));
ChatPlugin.getInstance().getServer().getOnlinePlayers().forEach(p -> {
if (p.hasPermission("chat.command.nick.review")) {
p.sendMessage(messageDenied);
}
});
ItemStack itemStack = new ItemStack(Material.SKELETON_SKULL);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.displayName(displayName);
itemMeta.lore(clickedItem.lore());
itemStack.setItemMeta(itemMeta);
e.getInventory().setItem(e.getSlot(), itemStack);
p.updateInventory();
} else {
if (displayName == null)
p.sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_PLAYER_NOT_ONLINE, Placeholder.parsed("playerName", "UNKNOWN PLAYER NAME")));
else
p.sendMessage(MiniMessage.miniMessage().deserialize(Config.NICK_PLAYER_NOT_ONLINE, Placeholder.component("playerName", displayName)));
}
}
}
}.runTaskAsynchronously(ChatPlugin.getInstance());
}
}
// Cancel dragging in our inventory
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onInventoryClick(InventoryDragEvent e) {
if (e.getInventory() == inv) {
e.setCancelled(true);
}
}
}
@@ -0,0 +1,23 @@
package com.alttd.chat.requests;
import java.util.UUID;
public class NickNameRequest extends Request {
public NickNameRequest(UUID requester, String request) {
super(requester, request);
this.requestType = RequestType.NICKNAME;
}
public NickNameRequest(UUID requester, String request, boolean completed, UUID completedBy, long dateRequested, long dateCompleted) {
super(requester, request, completed, completedBy, dateRequested, dateCompleted);
this.requestType = RequestType.NICKNAME;
}
@Override
public boolean processRequest(UUID processor) {
return false;
}
}
@@ -0,0 +1,24 @@
package com.alttd.chat.requests;
import java.util.UUID;
public class PrefixRequest extends Request{
public PrefixRequest(UUID requester, String request) {
super(requester, request);
this.requestType = RequestType.PREFIX;
}
public PrefixRequest(UUID requester, String request, boolean completed, UUID completedBy, long dateRequested, long dateCompleted) {
super(requester, request, completed, completedBy, dateRequested, dateCompleted);
this.requestType = RequestType.NICKNAME;
}
@Override
public boolean processRequest(UUID processor) {
return false;
}
}
@@ -0,0 +1,69 @@
package com.alttd.chat.requests;
import org.bukkit.Bukkit;
import java.util.Date;
import java.util.UUID;
public abstract class Request {
protected UUID requester;
protected RequestType requestType;
protected String serverName;
protected String request;
protected boolean completed;
protected UUID completedBy;
protected long dateRequested;
protected long dateCompleted;
Request(UUID requester, String request) {
this.requester = requester;
this.request = request;
this.serverName = Bukkit.getServerName();
this.dateRequested = new Date().getTime();
saveRequest();
}
Request(UUID requester, String request, boolean completed, UUID completedBy, long dateRequested, long dateCompleted) {
this.requester = requester;
this.request = request;
this.completed = completed;
this.completedBy = completedBy;
this.dateRequested = dateRequested;
this.dateCompleted = dateCompleted;
}
public static Request of(UUID requester, RequestType requestType, String request) {
return switch (requestType) {
case PREFIX -> new PrefixRequest(requester, request);
case NICKNAME -> new NickNameRequest(requester, request);
};
}
public static Request load(UUID requester, RequestType requestType, String request, boolean completed, UUID completedBy, long dateRequested, long dateCompleted) {
return switch (requestType) {
case PREFIX -> new PrefixRequest(requester, request, completed, completedBy, dateRequested, dateCompleted);
case NICKNAME -> new NickNameRequest(requester, request, completed, completedBy, dateRequested, dateCompleted);
};
}
public boolean processRequest(UUID completedBy) {
completeRequest(completedBy);
return true;
}
public boolean isCompleted() {
return completed;
}
void completeRequest(UUID completedBy) {
this.completed = true;
this.completedBy = completedBy;
this.dateCompleted = new Date().getTime();
saveRequest();
}
public void saveRequest() {
// upsert into database
}
}
@@ -0,0 +1,61 @@
package com.alttd.chat.requests;
import com.alttd.chat.config.Config;
import com.alttd.chat.database.DatabaseConnection;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
public class RequestHandler {
private final List<Request> requests;
public RequestHandler() {
requests = new ArrayList<>();
}
public boolean addRequest(Request request) {
return requests.add(request);
}
public boolean removeRequest(Request request) {
return requests.remove(request);
}
public List<Request> getRequests() {
return requests;
}
public void loadRequests() {
long time = new Date().getTime() - Config.NICK_WAIT_TIME;
// Load all requests that have not been completed yet
String query = "SELECT * FROM requests WHERE completed=false and (datechanged = 0 or datechanged > " + time + ")";
try {
Connection connection = DatabaseConnection.getConnection();
ResultSet resultSet = connection.prepareStatement(query).executeQuery();
while (resultSet.next()) {
UUID requester = UUID.fromString(resultSet.getString("requester"));
RequestType requestType = RequestType.valueOf(resultSet.getString("requesttype"));
String requestString = resultSet.getString("request");
boolean completed = resultSet.getBoolean("completed");
UUID completedby = UUID.fromString(resultSet.getString("completedby"));
long dateRequested = resultSet.getLong("daterequested");
long dateCompleted = resultSet.getLong("datecompleted");
Request request = Request.load(requester, requestType, requestString, completed, completedby, dateRequested, dateCompleted);
addRequest(request);
}
} catch (SQLException exception) {
exception.printStackTrace();
}
}
}
@@ -0,0 +1,8 @@
package com.alttd.chat.requests;
public enum RequestType {
NICKNAME,
PREFIX
}
@@ -0,0 +1,22 @@
package com.alttd.chat.requests;
import org.bukkit.Bukkit;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.jetbrains.annotations.NotNull;
public class RequestsGui implements InventoryHolder {
private final Inventory inventory;
private final int inventorySize = 54;
RequestsGui() {
inventory = Bukkit.createInventory(this, inventorySize, "A title");
}
@Override
public @NotNull Inventory getInventory() {
return inventory;
}
}
@@ -1,22 +1,28 @@
package com.alttd.chat.util;
import com.alttd.chat.config.Config;
import com.alttd.chat.managers.RegexManager;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.placeholder.Replacement;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.minimessage.tag.standard.StandardTags;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
public class GalaxyUtility {
public static void sendBlockedNotification(String prefix, Player player, Component input, String target) {
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("prefix", Replacement.miniMessage(prefix));
placeholders.put("displayname", Replacement.miniMessage(Utility.getDisplayName(player.getUniqueId(), player.getName())));
placeholders.put("target", Replacement.miniMessage((target.isEmpty() ? "tried to say:" : " -> " + target + ": ")));
placeholders.put("input", Replacement.component(input));
public static void sendBlockedNotification(String prefix, Player player, String input, String target) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.parsed("prefix", prefix),
Placeholder.parsed("displayname", Utility.getDisplayName(player.getUniqueId(), player.getName())),
Placeholder.parsed("target", (target.isEmpty() ? "tried to say:" : "-> " + target + ":")),
Placeholder.parsed("input", input)
);
Component blockedNotification = Utility.parseMiniMessage(Config.NOTIFICATIONFORMAT, placeholders);
Bukkit.getOnlinePlayers().forEach(a ->{
@@ -27,4 +33,33 @@ public class GalaxyUtility {
player.sendMessage(Utility.parseMiniMessage("<red>The language you used in your message is not allowed, " +
"this constitutes as your only warning. Any further attempts at bypassing the filter will result in staff intervention.</red>"));
}
public static void sendBlockedNotification(String prefix, Player player, Component input, String target) {
TagResolver placeholders = TagResolver.resolver(
Placeholder.parsed("prefix", prefix),
Placeholder.parsed("displayname", Utility.getDisplayName(player.getUniqueId(), player.getName())),
Placeholder.parsed("target", (target.isEmpty() ? "tried to say:" : "-> " + target + ":")),
Placeholder.component("input", input)
);
Component blockedNotification = Utility.parseMiniMessage(Config.NOTIFICATIONFORMAT, placeholders);
Bukkit.getOnlinePlayers().forEach(a ->{
if (a.hasPermission("chat.alert-blocked")) {
a.sendMessage(blockedNotification);
}
});
player.sendMessage(Utility.parseMiniMessage("<red>The language you used in your message is not allowed, " +
"this constitutes as your only warning. Any further attempts at bypassing the filter will result in staff intervention.</red>"));
}
public static void addAdditionalChatCompletions(Player player) {
List<String> completions = new ArrayList<>(RegexManager.emotesList);
Utility.formattingPerms.forEach((perm, pair) -> {
if (player.hasPermission(perm)) {
completions.addAll(pair.getY());
}
});
player.addCustomChatCompletions(completions);
}
}
@@ -0,0 +1,48 @@
package com.alttd.chat.util;
import com.alttd.chat.ChatPlugin;
import com.alttd.chat.objects.Toggleable;
import com.alttd.chat.objects.channels.CustomChannel;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashSet;
import java.util.UUID;
public class ToggleableForCustomChannel extends Toggleable {
private final CustomChannel customChannel;
public ToggleableForCustomChannel(CustomChannel customChannel) {
super();
this.customChannel = customChannel;
}
private final HashSet<UUID> toggledUsers = new HashSet<>();
@Override
public boolean isToggled(UUID uuid) {
return toggledUsers.contains(uuid);
}
@Override
public void setOff(UUID uuid) {
toggledUsers.remove(uuid);
}
@Override
public void setOn(UUID uuid) {
disableToggles(uuid);
toggledUsers.add(uuid);
}
@Override
public void sendMessage(Player player, String message) {
new BukkitRunnable() {
@Override
public void run() {
ChatPlugin.getInstance().getChatHandler().chatChannel(player, customChannel, message);
}
}.runTaskAsynchronously(ChatPlugin.getInstance());
}
}
+14 -3
View File
@@ -1,9 +1,12 @@
name: ChatPlugin
version: ${project.version}
version: 2.0.0-SNAPSHOT
main: com.alttd.chat.ChatPlugin
api-version: 1.18
api-version: 1.19
authors: [Destro, Teriuihi]
depend: [LuckPerms]
loadbefore:
- mcMMO
- GriefPrevention
commands:
globalchat:
permission: command.chat.globalchat
@@ -19,6 +22,9 @@ commands:
reply:
permission: command.chat.message
aliases: r
continue:
permission: command.chat.message
aliases: c
ignore:
permission: command.chat.ignore
unignore:
@@ -30,4 +36,9 @@ commands:
p:
permission: command.chat.p
chatclear:
permission: chat.command.clear-chat
permission: chat.command.clear-chat
emoteslist:
permission: chat.command.emoteslist
aliases: [emotes]
nick:
permission: chat.command.nick
Binary file not shown.
+3 -1
View File
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+179 -115
View File
@@ -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,99 @@
#
##############################################################################
##
## 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/HEAD/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_NAME="Gradle"
APP_BASE_NAME=`basename "$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"'
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
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
;;
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 +119,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,88 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "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
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
# 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
# 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\""
fi
i=`expr $i + 1`
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" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
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, 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.
# 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"
# For Cygwin or MSYS, switch paths to Windows format before running java
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
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
# 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
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# 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.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+9 -6
View File
@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
Executable
BIN
View File
Binary file not shown.
-58
View File
@@ -1,58 +0,0 @@
#!/usr/bin/env bash
# get base dir regardless of execution location
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
SOURCE=$([[ "$SOURCE" = /* ]] && echo "$SOURCE" || echo "$PWD/${SOURCE#./}")
basedir=$(dirname "$SOURCE")
. "$basedir"/scripts/init.sh
case "$1" in
"d" | "deploy") # deploy api to repo
;;
"b" | "build")
(
cd "$basedir"
mvn package
)
;;
"upload")
(
cd "$basedir"
scp ./galaxy/target/galaxy-chat.jar sid@leo:/home/sid/servers/meadowTest/plugins/galaxy-chat.jar
scp ./velocity/target/velocity-chat.jar sid@leo:/home/sid/servers/velocity/plugins/velocity-chat.jar
)
;;
"queue")
(
cd "$basedir"
scp ./galaxy/target/galaxy-chat.jar sid@lyra:/home/sid/share/updates/all/plugins/galaxy-chat.jar
scp ./velocity/target/velocity-chat.jar sid@lyra:/home/sid/share/updates/plugins/proxy/velocity-chat.jar
)
;;
"setup")
if [[ -f ~/.bashrc ]] ; then
NAME="${PLUGIN_NAME}"
if [[ ! -z "${2+x}" ]] ; then
NAME="$2"
fi
(grep "alias $NAME=" ~/.bashrc > /dev/null) && (sed -i "s|alias $NAME=.*|alias $NAME='. $SOURCE'|g" ~/.bashrc) || (echo "alias $NAME='. $SOURCE'" >> ~/.bashrc)
alias "$NAME=. $SOURCE"
echo "You can now just type '$NAME' at any time to access the build tool."
fi
;;
*)
echo "${PLUGIN_NAME} build tool. This provides a variety of commands to control the build."
echo "View below for details of the available commands."
echo ""
echo "Commands:"
echo " * b, build | Builds the project"
echo " * upload | uploads the lastest build to a testserver"
echo " * queue | queue the lastest build to Alttiude"
echo " * setup | Add an alias to .bashrc to allow full functionality of this script. Run as:"
echo " | . ./plugin setup"
;;
esac
+1
View File
@@ -9,6 +9,7 @@ dependencyResolutionManagement {
// mavenLocal()
mavenCentral()
maven("https://repo.destro.xyz/snapshots") // Altitude - Galaxy
maven("https://oss.sonatype.org/content/groups/public/") // Adventure
maven("https://oss.sonatype.org/content/repositories/snapshots/") // Minimessage
maven("https://nexus.velocitypowered.com/repository/") // Velocity
maven("https://nexus.velocitypowered.com/repository/maven-public/") // Velocity
+7 -9
View File
@@ -5,30 +5,28 @@ plugins {
dependencies {
implementation(project(":api")) // API
compileOnly("com.velocitypowered:velocity-api:3.0.1") // Velocity
annotationProcessor("com.velocitypowered:velocity-api:3.0.1")
compileOnly("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT")
annotationProcessor("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT")
implementation("mysql:mysql-connector-java:8.0.27") // mysql
implementation("org.spongepowered", "configurate-yaml", "4.1.2")
compileOnly("com.alttd.proxydiscordlink:ProxyDiscordLink:1.0.0-BETA-SNAPSHOT")
implementation("net.kyori", "adventure-text-minimessage", "4.10.0-20220122.015731-43") { // Minimessage
exclude("net.kyori")
exclude("net.kyori.examination")
}
compileOnly("net.kyori:adventure-text-minimessage:4.10.1")
compileOnly("com.gitlab.ruany:LiteBansAPI:0.3.5")
compileOnly("com.alttd.proxydiscordlink:ProxyDiscordLink:1.0.0-BETA-SNAPSHOT")
}
tasks {
shadowJar {
archiveFileName.set("${project.name}-${project.version}.jar")
archiveFileName.set("${rootProject.name}-${project.name}-${project.version}.jar")
// minimize()
listOf(
"net.kyori.adventure.text.minimessage",
// "net.kyori.adventure.text.minimessage",
"org.spongepowered.configurate"
).forEach { relocate(it, "${rootProject.group}.lib.${it.substringAfterLast(".")}") }
}
build {
// setBuildDir("${rootProject.buildDir}")
dependsOn(shadowJar)
}
@@ -108,6 +108,7 @@ public class VelocityChat {
}
public void loadCommands() {
new SilentJoinCommand(server);
new GlobalAdminChat(server);
new Reload(server);
new MailCommand(server);
@@ -41,6 +41,27 @@ public class MailCommand {
return 1;
});
RequiredArgumentBuilder<CommandSource, String> playerNodeSender = RequiredArgumentBuilder
.<CommandSource, String>argument("sender", StringArgumentType.string())
.suggests((context, builder) -> {
Collection<String> possibleValues = new ArrayList<>();
for (Player player : proxyServer.getAllPlayers()) {
possibleValues.add(player.getGameProfile().getName());
}
if(possibleValues.isEmpty()) return Suggestions.empty();
String remaining = builder.getRemaining().toLowerCase();
for (String str : possibleValues) {
if (str.toLowerCase().startsWith(remaining)) {
builder.suggest(str = StringArgumentType.escapeIfRequired(str));
}
}
return builder.buildFuture();
})
.executes(context -> {
sendHelpMessage(context.getSource());
return 1;
});
LiteralCommandNode<CommandSource> command = LiteralArgumentBuilder
.<CommandSource>literal("mail")
.requires(ctx -> ctx.hasPermission("command.chat.mail"))
@@ -79,8 +100,13 @@ public class MailCommand {
)
.then(playerNode
.requires(ctx -> ctx.hasPermission("command.chat.mail.list.other"))// TODO permission
.then(playerNodeSender
.executes(context -> {
VelocityChat.getPlugin().getChatHandler().readMail(context.getSource(), context.getArgument("player", String.class), context.getArgument("sender", String.class));
return 1;
}))
.executes(context -> {
VelocityChat.getPlugin().getChatHandler().readMail(context.getSource(), context.getArgument("player", String.class));
VelocityChat.getPlugin().getChatHandler().readMail(context.getSource(), context.getArgument("player", String.class), null);
return 1;
})
)
@@ -8,7 +8,7 @@ import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.command.SimpleCommand;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.Arrays;
@@ -2,11 +2,15 @@ package com.alttd.velocitychat.commands;
import com.alttd.chat.config.Config;
import com.alttd.chat.util.Utility;
import com.alttd.proxydiscordlink.DiscordLink;
import com.alttd.proxydiscordlink.lib.net.dv8tion.jda.api.EmbedBuilder;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.suggestion.Suggestions;
import com.alttd.proxydiscordlink.DiscordLink;
import com.alttd.proxydiscordlink.lib.net.dv8tion.jda.api.EmbedBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.velocitypowered.api.command.BrigadierCommand;
import com.velocitypowered.api.command.CommandMeta;
@@ -16,13 +20,16 @@ import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.ServerConnection;
import net.kyori.adventure.text.minimessage.MiniMessage;
import java.util.ArrayList;
import java.util.Collection;
import java.awt.*;
import java.util.Optional;
public class Report {
// private static final MiniMessage miniMessage = MiniMessage.get();
public Report(ProxyServer proxyServer) {
LiteralCommandNode<CommandSource> command = LiteralArgumentBuilder
.<CommandSource>literal("report")
@@ -38,6 +45,11 @@ public class Report {
if (optionalServerConnection.isEmpty()) {
return 1;
}
String report = context.getArgument("report", String.class);
if (report.split(" ").length < 3) {
player.sendMessage(Utility.parseMiniMessage(Config.REPORT_TOO_SHORT));
return 1;
}
ServerConnection serverConnection = optionalServerConnection.get();
String serverName = serverConnection.getServer().getServerInfo().getName();
@@ -46,7 +58,7 @@ public class Report {
embedBuilder.setTitle("Player Report");
embedBuilder.setColor(Color.CYAN);
embedBuilder.addField("Incident",
context.getArgument("report", String.class),
report,
false);
embedBuilder.addField("Server",
serverName.substring(0, 1).toUpperCase() + serverName.substring(1),
@@ -0,0 +1,97 @@
package com.alttd.velocitychat.commands;
import com.alttd.chat.config.Config;
import com.alttd.chat.util.Utility;
import com.alttd.velocitychat.listeners.ProxyPlayerListener;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.velocitypowered.api.command.BrigadierCommand;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;
public class SilentJoinCommand {
public SilentJoinCommand(ProxyServer proxyServer) {
RequiredArgumentBuilder<CommandSource, String> serverNode = RequiredArgumentBuilder
.<CommandSource, String>argument("server", StringArgumentType.string())
.suggests((context, builder) -> {
Collection<String> possibleValues = new ArrayList<>();
for (RegisteredServer server : proxyServer.getAllServers()) {
possibleValues.add(server.getServerInfo().getName());
}
if(possibleValues.isEmpty()) return Suggestions.empty();
String remaining = builder.getRemaining().toLowerCase();
for (String str : possibleValues) {
if (str.toLowerCase().startsWith(remaining)) {
builder.suggest(str = StringArgumentType.escapeIfRequired(str));
}
}
return builder.buildFuture();
})
.executes(context -> {
sendHelpMessage(context.getSource());
return 1;
});
LiteralCommandNode<CommandSource> command = LiteralArgumentBuilder
.<CommandSource>literal("silentjoin")
.requires(ctx -> ctx.hasPermission("command.chat.silent-join"))
.then(serverNode
.executes(context -> {
if (!(context.getSource() instanceof Player player)) {
context.getSource().sendMessage(Utility.parseMiniMessage(Config.NO_CONSOLE));
return 1;
}
if (player.getCurrentServer().isEmpty()) {
return 1;
}
String server = context.getArgument("server", String.class);
Optional<RegisteredServer> optionalServer = proxyServer.getServer(server);
if (optionalServer.isEmpty()) {
player.sendMessage(Utility.parseMiniMessage(Config.SILENT_JOIN_NO_SERVER));
return 1;
}
RegisteredServer registeredServer = optionalServer.get();
player.sendMessage(Utility.parseMiniMessage(Config.SILENT_JOIN_JOINING,
Placeholder.unparsed("server", registeredServer.getServerInfo().getName())));
ProxyPlayerListener.addSilentJoin(player.getUniqueId());
player.createConnectionRequest(registeredServer).connectWithIndication();
return 1;
})
)
.executes(context -> {
sendHelpMessage(context.getSource());
return 1;
})
.build();
BrigadierCommand brigadierCommand = new BrigadierCommand(command);
CommandMeta.Builder metaBuilder = proxyServer.getCommandManager().metaBuilder(brigadierCommand);
for (String alias : Config.SILENT_JOIN_COMMAND_ALIASES) {
metaBuilder.aliases(alias);
}
CommandMeta meta = metaBuilder.build();
proxyServer.getCommandManager().register(meta, brigadierCommand);
}
private void sendHelpMessage(CommandSource commandSource) {
commandSource.sendMessage(Utility.parseMiniMessage("<red>Use: <gold>/silentjoin <server></gold>.</red>"));
}
}
@@ -9,7 +9,7 @@ import com.alttd.chat.util.Utility;
import com.alttd.velocitychat.commands.SubCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.List;
@@ -38,7 +38,7 @@ public class Create implements SubCommand {
}
if (PartyManager.getParty(args[1]) != null) {
source.sendMessage(Utility.parseMiniMessage(Config.PARTY_EXISTS,
Placeholder.miniMessage("party", args[1])
Placeholder.parsed("party", args[1])
));
return;
}
@@ -47,8 +47,8 @@ public class Create implements SubCommand {
party.addUser(ChatUserManager.getChatUser(player.getUniqueId()), player.getUsername());
PartyManager.addParty(party);
source.sendMessage(Utility.parseMiniMessage(Config.CREATED_PARTY,
Placeholder.miniMessage("party_name", party.getPartyName()),
Placeholder.miniMessage("party_password", party.getPartyPassword())));
Placeholder.unparsed("party_name", party.getPartyName()),
Placeholder.unparsed("party_password", party.getPartyPassword())));
}
@Override
@@ -8,7 +8,7 @@ import com.alttd.velocitychat.VelocityChat;
import com.alttd.velocitychat.commands.SubCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.List;
@@ -39,7 +39,7 @@ public class Disband implements SubCommand {
return;
}
if (args.length == 1) {
source.sendMessage(Utility.parseMiniMessage(Config.DISBAND_PARTY_CONFIRM, Placeholder.miniMessage("party", party.getPartyName())));
source.sendMessage(Utility.parseMiniMessage(Config.DISBAND_PARTY_CONFIRM, Placeholder.unparsed("party", party.getPartyName())));
return;
}
if (!args[1].equalsIgnoreCase("confirm") || !args[2].equals(party.getPartyName())) {
@@ -48,8 +48,8 @@ public class Disband implements SubCommand {
}
VelocityChat.getPlugin().getChatHandler().sendPartyMessage(party,
Utility.parseMiniMessage(Config.DISBANDED_PARTY,
Placeholder.miniMessage("owner", player.getUsername()),
Placeholder.miniMessage("party", party.getPartyName())
Placeholder.unparsed("owner", player.getUsername()),
Placeholder.unparsed("party", party.getPartyName())
), null);
party.delete();
}
@@ -5,16 +5,21 @@ import com.alttd.chat.managers.PartyManager;
import com.alttd.chat.objects.Party;
import com.alttd.chat.objects.PartyUser;
import com.alttd.chat.util.Utility;
import com.alttd.velocitychat.VelocityChat;
import com.alttd.velocitychat.commands.SubCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class Info implements SubCommand {
@Override
public String getName() {
return "info";
@@ -34,14 +39,19 @@ public class Info implements SubCommand {
List<Component> displayNames = new ArrayList<>();
for (PartyUser partyUser : party.getPartyUsers()) {
displayNames.add(partyUser.getDisplayName());
Optional<Player> optionalPlayer = VelocityChat.getPlugin().getProxy().getPlayer(partyUser.getUuid());
if (optionalPlayer.isPresent() && optionalPlayer.get().isActive())
displayNames.add(Config.ONLINE_PREFIX.append(partyUser.getDisplayName()));
else
displayNames.add(Config.OFFLINE_PREFIX.append(partyUser.getDisplayName()));
}
PartyUser owner = party.getPartyUser(party.getOwnerUuid());
source.sendMessage(Utility.parseMiniMessage(Config.PARTY_INFO,
Placeholder.miniMessage("party", party.getPartyName()),
Placeholder.miniMessage("password", party.getPartyPassword()),
Placeholder.component("owner", party.getPartyUser(party.getOwnerUuid()).getDisplayName()),
Placeholder.component("members", Component.join(Component.text(", "), displayNames))
Placeholder.unparsed("party", party.getPartyName()),
Placeholder.unparsed("password", party.getPartyPassword()),
Placeholder.component("owner", owner == null ? MiniMessage.miniMessage().deserialize("Unknown Owner") : owner.getDisplayName()),
Placeholder.component("members", Component.join(JoinConfiguration.separator(Component.text(", ")), displayNames))
));
}
@@ -8,7 +8,7 @@ import com.alttd.velocitychat.VelocityChat;
import com.alttd.velocitychat.commands.SubCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.List;
@@ -50,17 +50,22 @@ public class Invite implements SubCommand {
if (!target.isActive()) {
source.sendMessage(Utility.parseMiniMessage(Config.NOT_ONLINE,
Placeholder.miniMessage("player", target.getUsername())
Placeholder.unparsed("player", target.getUsername())
));
return;
}
target.sendMessage(Utility.parseMiniMessage(Config.JOIN_PARTY_CLICK_MESSAGE,
Placeholder.miniMessage("party", party.getPartyName()),
Placeholder.miniMessage("party_password", party.getPartyPassword())
Placeholder.unparsed("party", party.getPartyName()),
Placeholder.unparsed("party_password", party.getPartyPassword())
));
source.sendMessage(Utility.parseMiniMessage(Config.SENT_PARTY_INV,
Placeholder.miniMessage("player", target.getUsername())
Placeholder.unparsed("player", target.getUsername()),
Placeholder.unparsed("party", party.getPartyName()),
Placeholder.unparsed("party_password", party.getPartyPassword())
));
source.sendMessage(Utility.parseMiniMessage(Config.SENT_PARTY_INV,
Placeholder.unparsed("player", target.getUsername())
));
}
@@ -10,8 +10,7 @@ import com.alttd.velocitychat.VelocityChat;
import com.alttd.velocitychat.commands.SubCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.minimessage.Template;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.List;
@@ -46,16 +45,17 @@ public class Join implements SubCommand {
// party.addUser(ChatUserManager.getChatUser(player.getUniqueId())); //Removed until we can get nicknames to translate to colors correctly
ChatUser chatUser = ChatUserManager.getChatUser(player.getUniqueId());
if (chatUser.getPartyId() == party.getPartyId()) {
source.sendMessage(Utility.parseMiniMessage(Config.ALREADY_IN_THIS_PARTY, Placeholder.miniMessage("party", party.getPartyName())));
source.sendMessage(Utility.parseMiniMessage(Config.ALREADY_IN_THIS_PARTY, Placeholder.parsed("party", party.getPartyName())));
return;
}
party.addUser(chatUser, player.getUsername());
source.sendMessage(Utility.parseMiniMessage(Config.JOINED_PARTY, Placeholder.miniMessage("party_name", party.getPartyName())));
source.sendMessage(Utility.parseMiniMessage(Config.JOINED_PARTY, Placeholder.parsed("party_name", party.getPartyName())));
VelocityChat.getPlugin().getChatHandler().sendPartyMessage(party,
Utility.parseMiniMessage(Config.PLAYER_JOINED_PARTY,
Placeholder.component("player_name", chatUser.getDisplayName()),
Placeholder.miniMessage("party_name", party.getPartyName())
Placeholder.parsed("party_name", party.getPartyName())
), null);
}
@@ -9,7 +9,7 @@ import com.alttd.velocitychat.commands.SubCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ServerConnection;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.List;
@@ -45,8 +45,8 @@ public class Leave implements SubCommand {
source.sendMessage(Utility.parseMiniMessage(Config.NOTIFY_FINDING_NEW_OWNER));
VelocityChat.getPlugin().getChatHandler().sendPartyMessage(party,
Utility.parseMiniMessage(Config.OWNER_LEFT_PARTY,
Placeholder.miniMessage("old_owner", player.getUsername()),
Placeholder.miniMessage("new_owner", party.getPartyUser(uuid).getPlayerName())
Placeholder.unparsed("old_owner", player.getUsername()),
Placeholder.unparsed("new_owner", party.getPartyUser(uuid).getPlayerName())
), null);
} else {
party.delete();
@@ -55,7 +55,7 @@ public class Leave implements SubCommand {
source.sendMessage(Utility.parseMiniMessage(Config.LEFT_PARTY));
VelocityChat.getPlugin().getChatHandler().sendPartyMessage(party,
Utility.parseMiniMessage(Config.PLAYER_LEFT_PARTY,
Placeholder.miniMessage("player_name", player.getUsername())
Placeholder.unparsed("player_name", player.getUsername())
), null);
}
}
@@ -9,7 +9,7 @@ import com.alttd.velocitychat.VelocityChat;
import com.alttd.velocitychat.commands.SubCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.List;
@@ -45,7 +45,7 @@ public class Name implements SubCommand {
}
if (PartyManager.getParty(args[1]) != null) {
source.sendMessage(Utility.parseMiniMessage(Config.PARTY_EXISTS,
Placeholder.miniMessage("party", args[1])
Placeholder.unparsed("party", args[1])
));
return;
}
@@ -54,8 +54,8 @@ public class Name implements SubCommand {
party.setPartyName(args[1]);
VelocityChat.getPlugin().getChatHandler().sendPartyMessage(party, Utility.parseMiniMessage(Config.RENAMED_PARTY,
Placeholder.component("owner", ChatUserManager.getChatUser(player.getUniqueId()).getDisplayName()),
Placeholder.miniMessage("old_name", oldName),
Placeholder.miniMessage("new_name", args[1])
Placeholder.unparsed("old_name", oldName),
Placeholder.unparsed("new_name", args[1])
), null);
}
@@ -9,7 +9,7 @@ import com.alttd.velocitychat.VelocityChat;
import com.alttd.velocitychat.commands.SubCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.List;
@@ -44,15 +44,15 @@ public class Owner implements SubCommand {
PartyUser partyUser = party.getPartyUser(args[1]);
if (partyUser == null) {
source.sendMessage(Utility.parseMiniMessage(Config.NOT_A_PARTY_MEMBER,
Placeholder.miniMessage("player", args[1])
Placeholder.unparsed("player", args[1])
));
return;
}
party.setNewOwner(partyUser.getUuid());
VelocityChat.getPlugin().getChatHandler().sendPartyMessage(party,
Utility.parseMiniMessage(Config.NEW_PARTY_OWNER,
Placeholder.miniMessage("old_owner", player.getUsername()),
Placeholder.miniMessage("new_owner", partyUser.getPlayerName())
Placeholder.unparsed("old_owner", player.getUsername()),
Placeholder.unparsed("new_owner", partyUser.getPlayerName())
), null);
}
@@ -10,7 +10,7 @@ import com.alttd.velocitychat.VelocityChat;
import com.alttd.velocitychat.commands.SubCommand;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.List;
@@ -50,7 +50,7 @@ public class Remove implements SubCommand {
partyUser = party.getPartyUser(args[1]);
if (partyUser == null) {
source.sendMessage(Utility.parseMiniMessage(Config.NOT_A_PARTY_MEMBER,
Placeholder.miniMessage("player", args[1])
Placeholder.unparsed("player", args[1])
));
return;
}
@@ -59,26 +59,27 @@ public class Remove implements SubCommand {
partyUser = party.getPartyUser(onlinePlayer.getUniqueId());
if (partyUser == null) {
source.sendMessage(Utility.parseMiniMessage(Config.NOT_A_PARTY_MEMBER,
Placeholder.miniMessage("player", onlinePlayer.getUsername())
Placeholder.unparsed("player", onlinePlayer.getUsername())
));
return;
}
}
party.removeUser(ChatUserManager.getChatUser(partyUser.getUuid()));
if (partyUser.getUuid().equals(party.getOwnerUuid())) {
source.sendMessage(Utility.parseMiniMessage(Config.CANT_REMOVE_PARTY_OWNER));
return;
}
party.removeUser(ChatUserManager.getChatUser(partyUser.getUuid()));
if (onlinePlayer != null && onlinePlayer.isActive()) {
onlinePlayer.sendMessage(Utility.parseMiniMessage(Config.REMOVED_FROM_PARTY,
Placeholder.miniMessage("party", party.getPartyName())
Placeholder.unparsed("party", party.getPartyName())
));
}
source.sendMessage(Utility.parseMiniMessage(Config.REMOVED_USER_FROM_PARTY,
Placeholder.miniMessage("player", onlinePlayer == null ? partyUser.getPlayerName() : onlinePlayer.getUsername())
Placeholder.unparsed("player", onlinePlayer == null ? partyUser.getPlayerName() : onlinePlayer.getUsername())
));
}
@@ -5,10 +5,7 @@ import com.alttd.chat.database.Queries;
import com.alttd.chat.managers.ChatUserManager;
import com.alttd.chat.managers.PartyManager;
import com.alttd.chat.managers.RegexManager;
import com.alttd.chat.objects.ChatUser;
import com.alttd.chat.objects.Mail;
import com.alttd.chat.objects.ModifiableString;
import com.alttd.chat.objects.Party;
import com.alttd.chat.objects.*;
import com.alttd.chat.util.ALogger;
import com.alttd.chat.util.Utility;
import com.alttd.velocitychat.VelocityChat;
@@ -18,14 +15,16 @@ import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ServerConnection;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.placeholder.Replacement;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.jetbrains.annotations.Nullable;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class ChatHandler {
@@ -37,26 +36,25 @@ public class ChatHandler {
Player player = optionalPlayer.get();
Optional<Player> optionalPlayer2 = VelocityChat.getPlugin().getProxy().getPlayer(target);
if(optionalPlayer2.isEmpty()) {
player.sendMessage(MiniMessage.markdown().parse(Config.RECEIVER_DOES_NOT_EXIST, Placeholder.miniMessage("player", target)));
return;
}
if(optionalPlayer2.isEmpty()) return;
Player player2 = optionalPlayer2.get();
ChatUser targetUser = ChatUserManager.getChatUser(player2.getUniqueId());
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("sender", Replacement.component(senderUser.getDisplayName()));
placeholders.put("sendername", Replacement.miniMessage(player.getUsername()));
placeholders.put("receiver", Replacement.component(targetUser.getDisplayName()));
placeholders.put("receivername", Replacement.miniMessage(player2.getUsername()));
placeholders.put("message", Replacement.component(GsonComponentSerializer.gson().deserialize(message)));
placeholders.put("server", Replacement.miniMessage(player.getCurrentServer().isPresent() ? player.getCurrentServer().get().getServerInfo().getName() : "Altitude"));
TagResolver Placeholders = TagResolver.resolver(
Placeholder.component("sender", senderUser.getDisplayName()),
Placeholder.unparsed("sendername", player.getUsername()),
Placeholder.component("receiver", targetUser.getDisplayName()),
Placeholder.unparsed("receivername", player2.getUsername()),
Placeholder.component("message", GsonComponentSerializer.gson().deserialize(message)),
Placeholder.unparsed("server", player.getCurrentServer().isPresent() ? player.getCurrentServer().get().getServerInfo().getName() : "Altitude"));
ServerConnection serverConnection;
if(player.getCurrentServer().isPresent() && player2.getCurrentServer().isPresent()) {
// redirect to the sender
serverConnection = player.getCurrentServer().get();
Component component = Utility.parseMiniMessage(Config.MESSAGESENDER, placeholders);
Component component = Utility.parseMiniMessage(Config.MESSAGESENDER
.replaceAll("<sendername>", player.getUsername())
.replaceAll("<receivername>", player2.getUsername()), Placeholders);
ByteArrayDataOutput buf = ByteStreams.newDataOutput();
buf.writeUTF("privatemessageout");
buf.writeUTF(player.getUniqueId().toString());
@@ -67,7 +65,9 @@ public class ChatHandler {
//redirect to the receiver
serverConnection = player2.getCurrentServer().get();
component = Utility.parseMiniMessage(Config.MESSAGERECIEVER, placeholders);
component = Utility.parseMiniMessage(Config.MESSAGERECIEVER
.replaceAll("<sendername>", player.getUsername())
.replaceAll("<receivername>", player2.getUsername()), Placeholders);
buf = ByteStreams.newDataOutput();
buf.writeUTF("privatemessagein");
buf.writeUTF(player2.getUniqueId().toString());
@@ -80,12 +80,13 @@ public class ChatHandler {
}
public static void sendBlockedNotification(String prefix, Player player, String input, String target, ServerConnection serverConnection) {
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("prefix", Replacement.miniMessage(prefix));
placeholders.put("displayname", Replacement.miniMessage(Utility.getDisplayName(player.getUniqueId(), player.getUsername())));
placeholders.put("target", Replacement.miniMessage((target.isEmpty() ? " tried to say: " : " -> " + target + ": ")));
placeholders.put("input", Replacement.miniMessage(input));
Component blockedNotification = Utility.parseMiniMessage(Config.NOTIFICATIONFORMAT, placeholders);
TagResolver Placeholders = TagResolver.resolver(
Placeholder.unparsed("prefix", prefix),
Placeholder.parsed("displayname", Utility.getDisplayName(player.getUniqueId(), player.getUsername())),
Placeholder.unparsed("target", (target.isEmpty() ? " tried to say: " : " -> " + target + ": ")),
Placeholder.unparsed("input", input)
);
Component blockedNotification = Utility.parseMiniMessage(Config.NOTIFICATIONFORMAT, Placeholders);
serverConnection.getServer().getPlayersConnected().forEach(pl ->{
if (pl.hasPermission("chat.alert-blocked")) {
@@ -106,6 +107,8 @@ public class ChatHandler {
return party.getPartyUsers().stream().anyMatch(pu -> pu.getUuid().equals(uuid));
}).forEach(pl -> {
pl.sendMessage(message);
// TODO forward sound to backend server.
// https://canary.discord.com/channels/514920774923059209/1020498592219271189
});
}
@@ -121,42 +124,34 @@ public class ChatHandler {
}
Component senderName = user.getDisplayName();
ModifiableString modifiableString = new ModifiableString(message);
if (!RegexManager.filterText(player.getUsername(), uuid, modifiableString, "partychat")) {
sendBlockedNotification("Party Language",
player,
modifiableString.string(),
"",
serverConnection);
TagResolver Placeholders = TagResolver.resolver(
Placeholder.component("sender", senderName),
Placeholder.component("sendername", senderName),
Placeholder.unparsed("partyname", party.getPartyName()),
Placeholder.component("message", parseMessageContent(player, message)),
Placeholder.unparsed("server", serverConnection.getServer().getServerInfo().getName())
);
Component partyMessage = Utility.parseMiniMessage(Config.PARTY_FORMAT, Placeholders)
.replaceText(TextReplacementConfig.builder().once().matchLiteral("[i]").replacement(item).build());
ModifiableString modifiableString = new ModifiableString(partyMessage);
if (!RegexManager.filterText(player.getUsername(), uuid, modifiableString, "party")) {
sendBlockedNotification("Party Language", player, message, "", serverConnection);
return; // the message was blocked
}
String updatedMessage = modifiableString.string();
if(!player.hasPermission("chat.format")) {
updatedMessage = Utility.stripTokens(updatedMessage);
}
partyMessage = modifiableString.component();
if(updatedMessage.contains("[i]")) updatedMessage = updatedMessage.replace("[i]", "<[i]>");
updatedMessage = Utility.formatText(updatedMessage);
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("sender", Replacement.component(senderName));
placeholders.put("username", Replacement.miniMessage(player.getUsername()));
placeholders.put("party", Replacement.miniMessage(party.getPartyName()));
placeholders.put("message", Replacement.miniMessage(updatedMessage));
placeholders.put("server", Replacement.miniMessage(serverConnection.getServer().getServerInfo().getName()));
placeholders.put("[i]", Replacement.component(item));
Component partyMessage = Utility.parseMiniMessage(Config.PARTY_FORMAT, placeholders);
sendPartyMessage(party, partyMessage, user.getIgnoredBy());
Component spyMessage = Utility.parseMiniMessage(Config.PARTY_SPY, placeholders);
Component spyMessage = Utility.parseMiniMessage(Config.PARTY_SPY, Placeholders);
for(Player pl : serverConnection.getServer().getPlayersConnected()) {
if(pl.hasPermission(Config.SPYPERMISSION) && !party.getPartyUsersUuid().contains(pl.getUniqueId())) {
pl.sendMessage(spyMessage);
}
}
ALogger.info(PlainTextComponentSerializer.plainText().serialize(partyMessage));
}
public void globalAdminChat(String message) {
@@ -178,12 +173,12 @@ public class ChatHandler {
serverName = sender.getCurrentServer().isPresent() ? sender.getCurrentServer().get().getServerInfo().getName() : "Altitude";
}
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("message", Replacement.miniMessage(Utility.formatText(message)));
placeholders.put("sender", Replacement.component(senderName));
placeholders.put("server", Replacement.miniMessage(serverName));
TagResolver Placeholders = TagResolver.resolver(
Placeholder.component("message", parseMessageContent(commandSource, message)),
Placeholder.component("sender", senderName),
Placeholder.unparsed("server", serverName));
Component component = Utility.parseMiniMessage(Config.GACFORMAT, placeholders);
Component component = Utility.parseMiniMessage(Config.GACFORMAT, Placeholders);
VelocityChat.getPlugin().getProxy().getAllPlayers().stream().filter(target -> target.hasPermission("command.chat.globaladminchat")/*TODO permission*/).forEach(target -> {
target.sendMessage(component);
@@ -198,7 +193,6 @@ public class ChatHandler {
uuid = player.getUniqueId();
senderName = player.getUsername();
}
Optional<Player> optionalPlayer = VelocityChat.getPlugin().getProxy().getPlayer(recipient);
if (optionalPlayer.isEmpty()) {
targetUUID = ServerHandler.getPlayerUUID(recipient);
@@ -209,33 +203,37 @@ public class ChatHandler {
} else {
targetUUID = optionalPlayer.get().getUniqueId();
}
if (!commandSource.hasPermission("chat.format"))
message = Utility.stripTokens(message);
else
message = Utility.parseColors(message);
Mail mail = new Mail(targetUUID, uuid, message);
ChatUser chatUser = ChatUserManager.getChatUser(targetUUID);
chatUser.addMail(mail);
// TODO load from config
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("sender", Replacement.miniMessage(senderName));
optionalPlayer.ifPresent(player -> player.sendMessage(Utility.parseMiniMessage(Config.mailReceived, placeholders)));
commandSource.sendMessage(Utility.parseMiniMessage(Config.mailSent,
Placeholder.component("player_name", chatUser.getDisplayName()),
Placeholder.miniMessage("message", message)
));
String finalSenderName = senderName;
optionalPlayer.ifPresent(player -> player.sendMessage(Utility.parseMiniMessage("<yellow>New mail from " + finalSenderName)));
commandSource.sendMessage(Utility.parseMiniMessage("<yellow>Sent mail to " + recipient + "!"));
}
public void readMail(CommandSource commandSource, String targetPlayer) {
public void readMail(CommandSource commandSource, String targetPlayer, String senderPlayer) {
UUID uuid = ServerHandler.getPlayerUUID(targetPlayer);
if (uuid == null) {
commandSource.sendMessage(Utility.parseMiniMessage(Config.mailNoUser));
return;
}
ChatUser chatUser = ChatUserManager.getChatUser(uuid);
commandSource.sendMessage(parseMails(chatUser.getMails(), false));
if (senderPlayer == null) {
commandSource.sendMessage(parseMails(chatUser.getMails(), false));
}
UUID sender = ServerHandler.getPlayerUUID(senderPlayer);
if (sender == null) {
commandSource.sendMessage(Utility.parseMiniMessage(Config.mailNoUser));
return;
}
List<Mail> mails = chatUser.getMails().stream()
.filter(mail -> mail.getSender().equals(sender))
.toList();
commandSource.sendMessage(parseMails(mails, false));
}
public void readMail(CommandSource commandSource, boolean unread) {
@@ -252,15 +250,16 @@ public class ChatHandler {
mail.setReadTime(System.currentTimeMillis());
Queries.markMailRead(mail);
}
Date date = new Date(mail.getSendTime());
ChatUser chatUser = ChatUserManager.getChatUser(mail.getSender());
Date sentTime = new Date(mail.getSendTime());
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("staffprefix", Replacement.component(chatUser.getStaffPrefix()));
placeholders.put("sender", Replacement.component(chatUser.getDisplayName()));
placeholders.put("message", Replacement.miniMessage(mail.getMessage()));
placeholders.put("date", Replacement.miniMessage(sentTime.toString()));
placeholders.put("time_ago", Replacement.miniMessage(String.valueOf(TimeUnit.MILLISECONDS.toDays(new Date().getTime() - sentTime.getTime()))));
Component mailMessage = Utility.parseMiniMessage(Config.mailBody, placeholders);
TagResolver Placeholders = TagResolver.resolver(
Placeholder.component("staffprefix", chatUser.getStaffPrefix()),
Placeholder.component("sender", chatUser.getDisplayName()),
Placeholder.component("message", Utility.parseMiniMessage(mail.getMessage())),
Placeholder.unparsed("date", date.toString()),
Placeholder.unparsed("time_ago", getTimeAgo(Duration.between(date.toInstant(), new Date().toInstant())))
);
Component mailMessage = Utility.parseMiniMessage(Config.mailBody, Placeholders);
component = component.append(Component.newline()).append(mailMessage);
}
component = component.append(Component.newline()).append(Utility.parseMiniMessage(Config.mailFooter));
@@ -287,4 +286,37 @@ public class ChatHandler {
buf.writeUTF(uuid);
buf.writeBoolean(muted);
}
private String getTimeAgo(Duration duration) {
StringBuilder stringBuilder = new StringBuilder();
if (duration.toDays() != 0)
stringBuilder.append(duration.toDays()).append("d ");
if (duration.toHoursPart() != 0 || !stringBuilder.isEmpty())
stringBuilder.append(duration.toHoursPart()).append("h ");
stringBuilder.append(duration.toMinutesPart()).append("m ago");
return stringBuilder.toString();
}
private Component parseMessageContent(CommandSource source, String rawMessage) {
TagResolver.Builder tagResolver = TagResolver.builder();
Utility.formattingPerms.forEach((perm, pair) -> {
if (source.hasPermission(perm)) {
tagResolver.resolver(pair.getX());
}
});
MiniMessage miniMessage = MiniMessage.builder().tags(tagResolver.build()).build();
Component component = miniMessage.deserialize(rawMessage);
for(ChatFilter chatFilter : RegexManager.getEmoteFilters()) {
component = component.replaceText(
TextReplacementConfig.builder()
.times(Config.EMOTELIMIT)
.match(chatFilter.getRegex())
.replacement(chatFilter.getReplacement()).build());
}
return component;
}
}
@@ -9,7 +9,7 @@ import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import java.util.ArrayList;
import java.util.List;
@@ -34,9 +34,9 @@ public class ChatListener {
}
Component message = Utility.parseMiniMessage(Config.GACFORMAT,
Placeholder.miniMessage("sender", senderName),
Placeholder.miniMessage("message", event.getMessage()),
Placeholder.miniMessage("server", serverName)
Placeholder.parsed("sender", senderName),
Placeholder.component("message", Utility.parseMiniMessage(event.getMessage())),
Placeholder.parsed("server", serverName)
);
plugin.getProxy().getAllPlayers().stream().filter(target -> target.hasPermission("command.chat.globaladminchat")).forEach(target -> {
@@ -2,10 +2,9 @@ package com.alttd.velocitychat.listeners;
import com.alttd.chat.managers.ChatUserManager;
import com.alttd.chat.objects.ChatUser;
import com.alttd.velocitychat.VelocityChat;
import com.alttd.chat.database.Queries;
import com.alttd.chat.objects.channels.CustomChannel;
import com.alttd.chat.util.ALogger;
import com.alttd.velocitychat.VelocityChat;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
import com.velocitypowered.api.event.Subscribe;
@@ -23,7 +22,6 @@ import java.util.UUID;
public class PluginMessageListener {
//todo add an extra listener for nicknames?
private final ChannelIdentifier identifier;
public PluginMessageListener(ChannelIdentifier identifier){
@@ -45,38 +43,33 @@ public class PluginMessageListener {
String channel = in.readUTF();
VelocityChat.getPlugin().getLogger().info("server " + event.getSource());
switch (channel) {
case "globalchat":
VelocityChat.getPlugin().getServerHandler().sendGlobalChat(in.readUTF(), in.readUTF());
break;
case "globaladminchat":
VelocityChat.getPlugin().getChatHandler().globalAdminChat(in.readUTF());
break;
case "privatemessage":
VelocityChat.getPlugin().getChatHandler().privateMessage(in.readUTF(), in.readUTF(), in.readUTF());
break;
case "chatchannel": {
case "globalchat" -> VelocityChat.getPlugin().getServerHandler().sendGlobalChat(in.readUTF(), in.readUTF());
case "globaladminchat" -> VelocityChat.getPlugin().getChatHandler().globalAdminChat(in.readUTF());
case "privatemessage" ->
VelocityChat.getPlugin().getChatHandler().privateMessage(in.readUTF(), in.readUTF(), in.readUTF());
case "chatchannel" -> {
String channelName = in.readUTF();
CustomChannel chatChannel = (CustomChannel) CustomChannel.getChatChannel(channelName);
if (chatChannel == null) {
ALogger.warn("Received non existent channel" + channelName +".");
ALogger.warn("Received non existent channel" + channelName + ".");
break;
}
ProxyServer proxy = VelocityChat.getPlugin().getProxy();
chatChannel.getServers().forEach(server -> proxy.getServer(server).ifPresent(registeredServer ->
registeredServer.sendPluginMessage(VelocityChat.getPlugin().getChannelIdentifier(), event.getData())));
break;
}
case "party": {
case "party" -> {
VelocityChat.getPlugin().getChatHandler().sendPartyMessage(
UUID.fromString(in.readUTF()),
in.readUTF(),
GsonComponentSerializer.gson().deserialize(in.readUTF()),
serverConnection);
break;
}
case "NickNameAccepted": {
// nicknames WIP
case "NickNameAccepted", "NickNameSet" -> {
try {
short len = in.readShort();
byte[] msgbytes = new byte[len];
@@ -91,15 +84,22 @@ public class PluginMessageListener {
e.printStackTrace();
return;
}
ProxyServer proxy = VelocityChat.getPlugin().getProxy();
proxy.getAllServers().forEach(registeredServer ->
registeredServer.sendPluginMessage(VelocityChat.getPlugin().getChannelIdentifier(), event.getData()));
}
default:
case "NickNameRequest", "NickNameDenied" -> {
ProxyServer proxy = VelocityChat.getPlugin().getProxy();
proxy.getAllServers().forEach(registeredServer ->
registeredServer.sendPluginMessage(VelocityChat.getPlugin().getChannelIdentifier(), event.getData()));
}
default -> {
VelocityChat.getPlugin().getLogger().info("server " + event.getSource());
ProxyServer proxy = VelocityChat.getPlugin().getProxy();
for (RegisteredServer registeredServer : proxy.getAllServers()) {
registeredServer.sendPluginMessage(VelocityChat.getPlugin().getChannelIdentifier(), event.getData());
}
break;
}
}
}
@@ -18,8 +18,9 @@ import com.velocitypowered.api.event.player.ServerConnectedEvent;
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import net.kyori.adventure.text.minimessage.placeholder.Placeholder;
import net.kyori.adventure.text.minimessage.placeholder.Replacement;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import java.util.*;
@@ -55,7 +56,7 @@ public class ProxyPlayerListener {
if (unReadMail.isEmpty())
return;
player.sendMessage(Utility.parseMiniMessage(Config.mailUnread,
Placeholder.miniMessage("amount", String.valueOf(unReadMail.size()))
Placeholder.unparsed("amount", String.valueOf(unReadMail.size()))
));
}
@@ -76,32 +77,59 @@ public class ProxyPlayerListener {
//VelocityChat.getPlugin().getChatHandler().removePlayer(event.getPlayer().getUniqueId());
}
private static final HashSet<UUID> silentJoin = new HashSet<>();
public static void addSilentJoin(UUID uuid)
{
silentJoin.add(uuid);
}
// Server Join and Leave messages
@Subscribe
public void serverConnected(ServerConnectedEvent event) {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
ServerHandler serverHandler = VelocityChat.getPlugin().getServerHandler();
if (event.getPreviousServer().isPresent()) {
RegisteredServer previousServer = event.getPreviousServer().get();
Player player = event.getPlayer();
TagResolver placeholders = TagResolver.resolver(
Placeholder.parsed("player", player.getUsername()),
Placeholder.parsed("from_server", previousServer.getServerInfo().getName()),
Placeholder.parsed("to_server", event.getServer().getServerInfo().getName())
);
Map<String, Replacement<?>> placeholders = new HashMap<>();
placeholders.put("player", Replacement.miniMessage(player.getUsername()));
placeholders.put("from_server", Replacement.miniMessage(previousServer.getServerInfo().getName()));
placeholders.put("to_server", Replacement.miniMessage(event.getServer().getServerInfo().getName()));
if (silentJoin.remove(uuid)) {
Component message = Utility.parseMiniMessage(Config.SILENT_JOIN_JOINED_FROM,
placeholders);
event.getServer().getPlayersConnected().stream()
.filter(player1 -> player1.hasPermission("command.chat.silent-join-notify"))
.forEach(player1 -> player1.sendMessage(message));
return;
}
ServerWrapper wrapper = serverHandler.getWrapper(previousServer.getServerInfo().getName());
if(wrapper != null) {
wrapper.sendJoinLeaveMessage(event.getPlayer().getUniqueId(), Utility.parseMiniMessage(Config.SERVERSWTICHMESSAGETO, placeholders));
wrapper.sendJoinLeaveMessage(uuid, Utility.parseMiniMessage(Config.SERVERSWTICHMESSAGETO, placeholders));
}
wrapper = serverHandler.getWrapper(event.getServer().getServerInfo().getName());
if(wrapper != null) {
wrapper.sendJoinLeaveMessage(event.getPlayer().getUniqueId(), Utility.parseMiniMessage(Config.SERVERSWTICHMESSAGEFROM, placeholders));
wrapper.sendJoinLeaveMessage(uuid, Utility.parseMiniMessage(Config.SERVERSWTICHMESSAGEFROM, placeholders));
}
} else {
if (silentJoin.remove(uuid)) {
Component message = Utility.parseMiniMessage(Config.SILENT_JOIN_JOINED,
Placeholder.unparsed("player", player.getUsername()));
event.getServer().getPlayersConnected().stream()
.filter(player1 -> player1.hasPermission("command.chat.silent-join-notify"))
.forEach(player1 -> player1.sendMessage(message));
return;
}
ServerWrapper wrapper = serverHandler.getWrapper(event.getServer().getServerInfo().getName());
if(wrapper != null) {
wrapper.sendJoinLeaveMessage(event.getPlayer().getUniqueId(), Utility.parseMiniMessage(Config.SERVERJOINMESSAGE, Placeholder.miniMessage("player", event.getPlayer().getUsername())));
wrapper.sendJoinLeaveMessage(uuid, Utility.parseMiniMessage(Config.SERVERJOINMESSAGE, Placeholder.unparsed("player", player.getUsername())));
}
}
}
@@ -115,8 +143,8 @@ public class ProxyPlayerListener {
ServerWrapper wrapper = serverHandler.getWrapper(registeredServer.getServerInfo().getName());
if(wrapper != null) {
wrapper.sendJoinLeaveMessage(event.getPlayer().getUniqueId(), Utility.parseMiniMessage(Config.SERVERLEAVEMESSAGE,
Placeholder.miniMessage("player", event.getPlayer().getUsername()),
Placeholder.miniMessage("from_server", registeredServer.getServerInfo().getName())
Placeholder.unparsed("player", event.getPlayer().getUsername()),
Placeholder.unparsed("from_server", registeredServer.getServerInfo().getName())
));
}
}