Compare commits
1
Commits
9143642761
..
matrix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
636ee3c57e |
@@ -40,3 +40,5 @@ target/
|
|||||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
hs_err_pid
|
hs_err_pid
|
||||||
!gradle/wrapper/gradle-wrapper.jar
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
*.bat
|
||||||
|
|||||||
@@ -3,19 +3,12 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":web-api")) // Web-API
|
|
||||||
compileOnly("org.projectlombok:lombok:1.18.46")
|
|
||||||
annotationProcessor("org.projectlombok:lombok:1.18.46")
|
|
||||||
// Cosmos
|
// Cosmos
|
||||||
compileOnly("com.alttd.cosmos:cosmos-api:1.21.8-R0.1-SNAPSHOT") {
|
compileOnly("com.alttd.cosmos:cosmos-api:1.21.10-R0.1-SNAPSHOT") {
|
||||||
isChanging = true
|
isChanging = true
|
||||||
}
|
}
|
||||||
compileOnly("org.spongepowered:configurate-yaml:4.2.0") // Configurate
|
compileOnly("org.spongepowered:configurate-yaml:4.2.0") // Configurate
|
||||||
compileOnly("net.luckperms:api:5.5") // Luckperms
|
compileOnly("net.luckperms:api:5.5") // Luckperms
|
||||||
|
|
||||||
//API validation
|
|
||||||
implementation("org.hibernate.validator:hibernate-validator:9.0.1.Final")
|
|
||||||
implementation("org.glassfish:jakarta.el:5.0.0-M1")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
|
|||||||
@@ -183,15 +183,11 @@ public final class Config {
|
|||||||
private static void settings() {
|
private static void settings() {
|
||||||
PREFIXGROUPS = getList("settings.prefix-groups",
|
PREFIXGROUPS = getList("settings.prefix-groups",
|
||||||
Lists.newArrayList("discord", "socialmedia", "eventteam", "eventleader", "youtube", "twitch",
|
Lists.newArrayList("discord", "socialmedia", "eventteam", "eventleader", "youtube", "twitch",
|
||||||
"developer"
|
"developer"));
|
||||||
)
|
|
||||||
);
|
|
||||||
CONFLICTINGPREFIXGROUPS = getList("settings.prefix-conflicts-groups",
|
CONFLICTINGPREFIXGROUPS = getList("settings.prefix-conflicts-groups",
|
||||||
Lists.newArrayList("eventteam", "eventleader")
|
Lists.newArrayList("eventteam", "eventleader"));
|
||||||
);
|
|
||||||
STAFFGROUPS = getList("settings.staff-groups",
|
STAFFGROUPS = getList("settings.staff-groups",
|
||||||
Lists.newArrayList("trainee", "moderator", "headmod", "admin", "manager", "owner")
|
Lists.newArrayList("trainee", "moderator", "headmod", "admin", "manager", "owner"));
|
||||||
);
|
|
||||||
CONSOLENAME = getString("settings.console-name", CONSOLENAME);
|
CONSOLENAME = getString("settings.console-name", CONSOLENAME);
|
||||||
CONSOLEUUID = UUID.fromString(getString("settings.console-uuid", CONSOLEUUID.toString()));
|
CONSOLEUUID = UUID.fromString(getString("settings.console-uuid", CONSOLEUUID.toString()));
|
||||||
MINIMIUMSTAFFRANK = getString("settings.minimum-staff-rank", MINIMIUMSTAFFRANK);
|
MINIMIUMSTAFFRANK = getString("settings.minimum-staff-rank", MINIMIUMSTAFFRANK);
|
||||||
@@ -417,8 +413,7 @@ public final class Config {
|
|||||||
ConfigurationNode node = getNode("chat-channels");
|
ConfigurationNode node = getNode("chat-channels");
|
||||||
if (node.empty()) {
|
if (node.empty()) {
|
||||||
getString("chat-channels.ac.format",
|
getString("chat-channels.ac.format",
|
||||||
"<white><gray><sender></gray> <hover:show_text:on <server>><yellow>to <channel></yellow></hover><gray>: <message>"
|
"<white><gray><sender></gray> <hover:show_text:on <server>><yellow>to <channel></yellow></hover><gray>: <message>");
|
||||||
);
|
|
||||||
getList("chat-channels.ac.servers", List.of("lobby"));
|
getList("chat-channels.ac.servers", List.of("lobby"));
|
||||||
getBoolean("chat-channels.ac.proxy", false);
|
getBoolean("chat-channels.ac.proxy", false);
|
||||||
node = getNode("chat-channels");
|
node = getNode("chat-channels");
|
||||||
@@ -622,15 +617,11 @@ public final class Config {
|
|||||||
NICK_WAIT_TIME = getLong("nicknames.wait-time", NICK_WAIT_TIME);
|
NICK_WAIT_TIME = getLong("nicknames.wait-time", NICK_WAIT_TIME);
|
||||||
NICK_ITEM_LORE = getList("nicknames.item-lore",
|
NICK_ITEM_LORE = getList("nicknames.item-lore",
|
||||||
List.of("<aqua>New nick: <newnick>", "<aqua>Old nick: <oldnick>", "<aqua>Last changed: <lastchanged>",
|
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"
|
"<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_BLOCKED_COLOR_CODESLIST = getList("nicknames.blocked-color-codes", List.of("&k", "&l", "&n", "&m", "&o"));
|
||||||
NICK_ALLOWED_COLOR_CODESLIST = getList("nicknames.allowed-color-codes",
|
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",
|
List.of("&0", "&1", "&2", "&3", "&4", "&5", "&6", "&7", "&8", "&9", "&a", "&b", "&c", "&d", "&e", "&f",
|
||||||
"&r"
|
"&r"));
|
||||||
)
|
|
||||||
);
|
|
||||||
NICK_CURRENT = getString("nicknames.messages.nick-current", NICK_CURRENT);
|
NICK_CURRENT = getString("nicknames.messages.nick-current", NICK_CURRENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -651,9 +642,13 @@ public final class Config {
|
|||||||
CHAT_LOG_SAVE_DELAY_MINUTES = getLong("chat-log.save-delay-minutes", CHAT_LOG_SAVE_DELAY_MINUTES);
|
CHAT_LOG_SAVE_DELAY_MINUTES = getLong("chat-log.save-delay-minutes", CHAT_LOG_SAVE_DELAY_MINUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String CHAT_WEB_SERVER_BASE_URL = "http://10.0.0.121:8080";
|
public static String MATRIX_SERVER = "http://127.0.0.1:8008";
|
||||||
|
public static String MATRIX_AS_TOKEN = "<token>";
|
||||||
|
public static String MATRIX_HS_TOKEN = "<token>";
|
||||||
|
|
||||||
private static void webServerSettings() {
|
private static void matrixSettings() {
|
||||||
CHAT_WEB_SERVER_BASE_URL = getString("web-server.base-url", CHAT_WEB_SERVER_BASE_URL);
|
MATRIX_SERVER = getString("matrix.server", MATRIX_SERVER);
|
||||||
|
MATRIX_AS_TOKEN = getString("matrix.as_token", MATRIX_AS_TOKEN);
|
||||||
|
MATRIX_HS_TOKEN = getString("matrix.hs_token", MATRIX_HS_TOKEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,25 +15,15 @@ import java.util.concurrent.CompletionException;
|
|||||||
public class ChatLogQueries {
|
public class ChatLogQueries {
|
||||||
|
|
||||||
protected static void createChatLogTable() {
|
protected static void createChatLogTable() {
|
||||||
String nicknamesTableQuery = """
|
String nicknamesTableQuery = "CREATE TABLE IF NOT EXISTS chat_log("
|
||||||
CREATE TABLE IF NOT EXISTS chat_log (
|
+ "uuid CHAR(48) NOT NULL,"
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
+ "time_stamp TIMESTAMP(6) NOT NULL, "
|
||||||
uuid CHAR(36) NOT NULL,
|
+ "server VARCHAR(50) NOT NULL, "
|
||||||
time_stamp TIMESTAMP(6) NOT NULL,
|
+ "chat_message VARCHAR(300) NOT NULL, "
|
||||||
server VARCHAR(50) NOT NULL,
|
+ "blocked BIT(1) NOT NULL DEFAULT 0"
|
||||||
type VARCHAR(16) NOT NULL DEFAULT 'public',
|
+ ")";
|
||||||
channel VARCHAR(36) DEFAULT NULL,
|
|
||||||
receiver CHAR(36) DEFAULT NULL,
|
|
||||||
chat_message VARCHAR(300) NOT NULL,
|
|
||||||
mini_message JSON,
|
|
||||||
blocked BOOLEAN NOT NULL DEFAULT FALSE,
|
|
||||||
|
|
||||||
INDEX idx_time_stamp (time_stamp)
|
try (PreparedStatement preparedStatement = DatabaseConnection.getConnection().prepareStatement(nicknamesTableQuery)) {
|
||||||
)
|
|
||||||
""";
|
|
||||||
|
|
||||||
try (PreparedStatement preparedStatement = DatabaseConnection.getConnection().prepareStatement(
|
|
||||||
nicknamesTableQuery)) {
|
|
||||||
preparedStatement.executeUpdate();
|
preparedStatement.executeUpdate();
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
ALogger.error("Failed to create chat log table", throwable);
|
ALogger.error("Failed to create chat log table", throwable);
|
||||||
@@ -41,7 +31,7 @@ public class ChatLogQueries {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull CompletableFuture<Boolean> storeMessages(HashMap<UUID, List<ChatLog>> chatMessages) {
|
public static @NotNull CompletableFuture<Boolean> storeMessages(HashMap<UUID, List<ChatLog>> chatMessages) {
|
||||||
String insertQuery = "INSERT INTO chat_log (uuid, time_stamp, server, type, channel, receiver, chat_message, mini_message, blocked) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
String insertQuery = "INSERT INTO chat_log (uuid, time_stamp, server, chat_message, blocked) VALUES (?, ?, ?, ?, ?)";
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
try (Connection connection = DatabaseConnection.createTransactionConnection()) {
|
try (Connection connection = DatabaseConnection.createTransactionConnection()) {
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement(insertQuery);
|
PreparedStatement preparedStatement = connection.prepareStatement(insertQuery);
|
||||||
@@ -70,7 +60,7 @@ public class ChatLogQueries {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull CompletableFuture<List<ChatLog>> retrieveMessages(ChatLogHandler chatLogHandler, UUID uuid, Duration duration, String server) {
|
public static @NotNull CompletableFuture<List<ChatLog>> retrieveMessages(ChatLogHandler chatLogHandler, UUID uuid, Duration duration, String server) {
|
||||||
String query = "SELECT * FROM chat_log WHERE uuid = ? AND time_stamp > ? AND server = ? AND type = 'public'";
|
String query = "SELECT * FROM chat_log WHERE uuid = ? AND time_stamp > ? AND server = ?";
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
try (Connection connection = DatabaseConnection.getConnection()) {
|
try (Connection connection = DatabaseConnection.getConnection()) {
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
||||||
@@ -80,14 +70,13 @@ public class ChatLogQueries {
|
|||||||
ResultSet resultSet = preparedStatement.executeQuery();
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
List<ChatLog> chatLogs = new ArrayList<>();
|
List<ChatLog> chatLogs = new ArrayList<>();
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
chatLogHandler.loadFromResultSet(resultSet).ifPresent(chatLogs::add);
|
ChatLog chatLog = chatLogHandler.loadFromResultSet(resultSet);
|
||||||
|
chatLogs.add(chatLog);
|
||||||
}
|
}
|
||||||
return chatLogs;
|
return chatLogs;
|
||||||
} catch (SQLException sqlException) {
|
} catch (SQLException sqlException) {
|
||||||
ALogger.error(String.format("Failed to retrieve messages for user %s", uuid), sqlException);
|
ALogger.error(String.format("Failed to retrieve messages for user %s", uuid), sqlException);
|
||||||
throw new CompletionException(String.format("Failed to retrieve messages for user %s", uuid),
|
throw new CompletionException(String.format("Failed to retrieve messages for user %s", uuid), sqlException);
|
||||||
sqlException
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -101,13 +90,8 @@ public class ChatLogQueries {
|
|||||||
preparedStatement.setTimestamp(1, Timestamp.from(Instant.now().minus(duration)));
|
preparedStatement.setTimestamp(1, Timestamp.from(Instant.now().minus(duration)));
|
||||||
return preparedStatement.execute();
|
return preparedStatement.execute();
|
||||||
} catch (SQLException sqlException) {
|
} catch (SQLException sqlException) {
|
||||||
ALogger.error(String.format("Failed to delete messages older than %s days", duration.toDays()),
|
ALogger.error(String.format("Failed to delete messages older than %s days", duration.toDays()), sqlException);
|
||||||
sqlException
|
throw new CompletionException(String.format("Failed to delete messages older than %s days", duration.toDays()), sqlException);
|
||||||
);
|
|
||||||
throw new CompletionException(String.format("Failed to delete messages older than %s days",
|
|
||||||
duration.toDays()
|
|
||||||
), sqlException
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.alttd.chat.database;
|
package com.alttd.chat.database;
|
||||||
|
|
||||||
|
|
||||||
import com.alttd.chat.config.Config;
|
import com.alttd.chat.config.Config;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
@@ -26,7 +27,6 @@ public class DatabaseConnection {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the connection if it's not already open.
|
* Opens the connection if it's not already open.
|
||||||
*
|
|
||||||
* @throws SQLException If it can't create the connection.
|
* @throws SQLException If it can't create the connection.
|
||||||
*/
|
*/
|
||||||
public void openConnection() throws SQLException {
|
public void openConnection() throws SQLException {
|
||||||
@@ -46,15 +46,13 @@ public class DatabaseConnection {
|
|||||||
|
|
||||||
connection = DriverManager.getConnection(
|
connection = DriverManager.getConnection(
|
||||||
"jdbc:mysql://" + Config.IP + ":" + Config.PORT + "/" + Config.DATABASE + "?autoReconnect=true"+
|
"jdbc:mysql://" + Config.IP + ":" + Config.PORT + "/" + Config.DATABASE + "?autoReconnect=true"+
|
||||||
"&useSSL=false&preserveInstants=true",
|
"&useSSL=false",
|
||||||
Config.USERNAME, Config.PASSWORD
|
Config.USERNAME, Config.PASSWORD);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the connection for the database
|
* Returns the connection for the database
|
||||||
*
|
|
||||||
* @return Returns the connection.
|
* @return Returns the connection.
|
||||||
*/
|
*/
|
||||||
public static Connection getConnection() {
|
public static Connection getConnection() {
|
||||||
@@ -71,15 +69,13 @@ public class DatabaseConnection {
|
|||||||
* Creates a transactional database connection.
|
* Creates a transactional database connection.
|
||||||
*
|
*
|
||||||
* @return A {@code Connection} object representing the transactional database connection.
|
* @return A {@code Connection} object representing the transactional database connection.
|
||||||
*
|
|
||||||
* @throws SQLException If there is an error creating the database connection.
|
* @throws SQLException If there is an error creating the database connection.
|
||||||
*/
|
*/
|
||||||
public static Connection createTransactionConnection() throws SQLException {
|
public static Connection createTransactionConnection() throws SQLException {
|
||||||
connection = DriverManager.getConnection(
|
connection = DriverManager.getConnection(
|
||||||
"jdbc:mysql://" + Config.IP + ":" + Config.PORT + "/" + Config.DATABASE + "?autoReconnect=true"+
|
"jdbc:mysql://" + Config.IP + ":" + Config.PORT + "/" + Config.DATABASE + "?autoReconnect=true"+
|
||||||
"&useSSL=false&preserveInstants=true",
|
"&useSSL=false",
|
||||||
Config.USERNAME, Config.PASSWORD
|
Config.USERNAME, Config.PASSWORD);
|
||||||
);
|
|
||||||
connection.setAutoCommit(false);
|
connection.setAutoCommit(false);
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,9 @@ public abstract class Toggleable {
|
|||||||
|
|
||||||
public static Toggleable getToggleable(UUID uuid) {
|
public static Toggleable getToggleable(UUID uuid) {
|
||||||
for (Toggleable toggleableClass : togglableClasses) {
|
for (Toggleable toggleableClass : togglableClasses) {
|
||||||
if (toggleableClass.isToggled(uuid)) {
|
if (toggleableClass.isToggled(uuid))
|
||||||
return toggleableClass;
|
return toggleableClass;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
package com.alttd.chat.objects.chat_log;
|
package com.alttd.chat.objects.chat_log;
|
||||||
|
|
||||||
import com.alttd.chat.objects.BatchInsertable;
|
import com.alttd.chat.objects.BatchInsertable;
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
@@ -13,32 +9,44 @@ import java.sql.Timestamp;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Getter
|
|
||||||
public class ChatLog implements BatchInsertable {
|
public class ChatLog implements BatchInsertable {
|
||||||
|
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
private final Instant timestamp;
|
private final Instant timestamp;
|
||||||
private final String server;
|
private final String server;
|
||||||
private final ChatLogType type;
|
|
||||||
private final String channel;
|
|
||||||
private final String receiver;
|
|
||||||
private final String message;
|
private final String message;
|
||||||
private final Component miniMessage;
|
|
||||||
private final boolean blocked;
|
private final boolean blocked;
|
||||||
|
|
||||||
|
protected ChatLog(UUID uuid, Instant timestamp, String server, String message, boolean blocked) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.server = server;
|
||||||
|
this.message = message;
|
||||||
|
this.blocked = blocked;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void prepareStatement(@NotNull PreparedStatement preparedStatement) throws SQLException {
|
public void prepareStatement(@NotNull PreparedStatement preparedStatement) throws SQLException {
|
||||||
preparedStatement.setString(1, uuid.toString());
|
preparedStatement.setString(1, uuid.toString());
|
||||||
preparedStatement.setTimestamp(2, Timestamp.from(timestamp));
|
preparedStatement.setTimestamp(2, Timestamp.from(timestamp));
|
||||||
preparedStatement.setString(3, server);
|
preparedStatement.setString(3, server);
|
||||||
preparedStatement.setString(4, ChatLogTypeMapper.toDb(type));
|
preparedStatement.setString(4, message);
|
||||||
preparedStatement.setString(5, channel);
|
preparedStatement.setInt(5, blocked ? 1 : 0);
|
||||||
preparedStatement.setString(6, receiver);
|
}
|
||||||
preparedStatement.setString(7, message);
|
|
||||||
preparedStatement.setString(8,
|
public UUID getUuid() {
|
||||||
miniMessage == null ? null : GsonComponentSerializer.gson().serialize(miniMessage)
|
return uuid;
|
||||||
);
|
}
|
||||||
preparedStatement.setInt(9, blocked ? 1 : 0);
|
|
||||||
|
public Instant getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBlocked() {
|
||||||
|
return blocked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ package com.alttd.chat.objects.chat_log;
|
|||||||
import com.alttd.chat.config.Config;
|
import com.alttd.chat.config.Config;
|
||||||
import com.alttd.chat.database.ChatLogQueries;
|
import com.alttd.chat.database.ChatLogQueries;
|
||||||
import com.alttd.chat.util.ALogger;
|
import com.alttd.chat.util.ALogger;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@@ -15,17 +12,14 @@ import java.time.Instant;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class ChatLogHandler {
|
public class ChatLogHandler {
|
||||||
|
|
||||||
private final ChatLogWebHandler chatLogWebHandler = new ChatLogWebHandler();
|
|
||||||
private static ChatLogHandler instance = null;
|
private static ChatLogHandler instance = null;
|
||||||
private ScheduledExecutorService executorService = null;
|
private ScheduledExecutorService executorService = null;
|
||||||
|
|
||||||
public static ChatLogHandler getInstance(boolean enableLogging) {
|
public static ChatLogHandler getInstance(boolean enableLogging) {
|
||||||
if (instance == null) {
|
if (instance == null)
|
||||||
instance = new ChatLogHandler(enableLogging);
|
instance = new ChatLogHandler(enableLogging);
|
||||||
}
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,30 +35,23 @@ public class ChatLogHandler {
|
|||||||
Duration deleteThreshold = Duration.ofDays(Config.CHAT_LOG_DELETE_OLDER_THAN_DAYS);
|
Duration deleteThreshold = Duration.ofDays(Config.CHAT_LOG_DELETE_OLDER_THAN_DAYS);
|
||||||
ChatLogQueries.deleteOldMessages(deleteThreshold).thenAccept(success -> {
|
ChatLogQueries.deleteOldMessages(deleteThreshold).thenAccept(success -> {
|
||||||
if (success) {
|
if (success) {
|
||||||
ALogger.info(String.format("Deleted all messages older than %s days from chat log database.",
|
ALogger.info(String.format("Deleted all messages older than %s days from chat log database.", deleteThreshold.toDays()));
|
||||||
deleteThreshold.toDays()
|
|
||||||
));
|
|
||||||
} else {
|
} else {
|
||||||
ALogger.warn(String.format("Failed to delete all messages older than %s days from chat log database.",
|
ALogger.warn(String.format("Failed to delete all messages older than %s days from chat log database.", deleteThreshold.toDays()));
|
||||||
deleteThreshold.toDays()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
executorService = Executors.newSingleThreadScheduledExecutor();
|
executorService = Executors.newSingleThreadScheduledExecutor();
|
||||||
executorService.scheduleAtFixedRate(() -> {
|
executorService.scheduleAtFixedRate(() -> {
|
||||||
saveToDatabase(false);
|
saveToDatabase(false);
|
||||||
ALogger.info(String.format("Running scheduler to save messages with a %d delay",
|
ALogger.info(String.format("Running scheduler to save messages with a %d delay", Config.CHAT_LOG_SAVE_DELAY_MINUTES));
|
||||||
Config.CHAT_LOG_SAVE_DELAY_MINUTES
|
|
||||||
));
|
|
||||||
},
|
},
|
||||||
Config.CHAT_LOG_SAVE_DELAY_MINUTES, Config.CHAT_LOG_SAVE_DELAY_MINUTES, TimeUnit.MINUTES
|
Config.CHAT_LOG_SAVE_DELAY_MINUTES, Config.CHAT_LOG_SAVE_DELAY_MINUTES, TimeUnit.MINUTES);
|
||||||
);
|
|
||||||
ALogger.info("Logging has started!");
|
ALogger.info("Logging has started!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shuts down the executor service and saves the chat logs to the database. Will throw an error if called on a
|
* Shuts down the executor service and saves the chat logs to the database.
|
||||||
* ChatLogHandler that was started without logging
|
* Will throw an error if called on a ChatLogHandler that was started without logging
|
||||||
*/
|
*/
|
||||||
public void shutDown() {
|
public void shutDown() {
|
||||||
executorService.shutdown();
|
executorService.shutdown();
|
||||||
@@ -79,7 +66,7 @@ public class ChatLogHandler {
|
|||||||
return isSaving;
|
return isSaving;
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void addLog(ChatLog chatLog) {
|
public synchronized void addLog(ChatLog chatLog) {
|
||||||
if (isBlocked()) {
|
if (isBlocked()) {
|
||||||
chatLogQueue.add(chatLog);
|
chatLogQueue.add(chatLog);
|
||||||
} else {
|
} else {
|
||||||
@@ -113,50 +100,17 @@ public class ChatLogHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<ChatLog> loadFromResultSet(@NotNull ResultSet resultSet) throws SQLException {
|
public ChatLog loadFromResultSet(@NotNull ResultSet resultSet) throws SQLException {
|
||||||
UUID chatLogUUID = UUID.fromString(resultSet.getString("uuid"));
|
UUID chatLogUUID = UUID.fromString(resultSet.getString("uuid"));
|
||||||
Instant chatTimestamp = resultSet.getTimestamp("time_stamp").toInstant();
|
Instant chatTimestamp = resultSet.getTimestamp("time_stamp").toInstant();
|
||||||
String server = resultSet.getString("server");
|
String server = resultSet.getString("server");
|
||||||
String stringType = resultSet.getString("type");
|
|
||||||
ChatLogType type;
|
|
||||||
try {
|
|
||||||
type = ChatLogTypeMapper.fromDb(stringType);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Failed to load chat log from result set: {}", e.getMessage());
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
String channel = resultSet.getString("channel");
|
|
||||||
String receiver = resultSet.getString("receiver");
|
|
||||||
String chatMessage = resultSet.getString("chat_message");
|
String chatMessage = resultSet.getString("chat_message");
|
||||||
String stringMiniMessage = resultSet.getString("mini_message");
|
|
||||||
Component miniMessage = stringMiniMessage == null ? null : GsonComponentSerializer.gson().deserialize(
|
|
||||||
stringMiniMessage);
|
|
||||||
boolean chatMessageBlocked = resultSet.getInt("blocked") == 1;
|
boolean chatMessageBlocked = resultSet.getInt("blocked") == 1;
|
||||||
return Optional.of(new ChatLog(chatLogUUID,
|
return new ChatLog(chatLogUUID, chatTimestamp, server, chatMessage, chatMessageBlocked);
|
||||||
chatTimestamp,
|
|
||||||
server,
|
|
||||||
type,
|
|
||||||
channel,
|
|
||||||
receiver,
|
|
||||||
chatMessage,
|
|
||||||
miniMessage,
|
|
||||||
chatMessageBlocked
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addChatLog(UUID uuid, String server, String message, ChatLogType chatLogType, String channel, String receiver, Component miniMessage, boolean blocked) {
|
public void addChatLog(UUID uuid, String server, String message, boolean blocked) {
|
||||||
ChatLog chatLog = new ChatLog(uuid,
|
addLog(new ChatLog(uuid, Instant.now(), server, message, blocked));
|
||||||
Instant.now(),
|
|
||||||
server,
|
|
||||||
chatLogType,
|
|
||||||
channel,
|
|
||||||
receiver,
|
|
||||||
message,
|
|
||||||
miniMessage,
|
|
||||||
blocked
|
|
||||||
);
|
|
||||||
addLog(chatLog);
|
|
||||||
chatLogWebHandler.forwardChatLogToWeb(chatLog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<List<ChatLog>> retrieveChatLogs(UUID uuid, Duration duration, String server) {
|
public CompletableFuture<List<ChatLog>> retrieveChatLogs(UUID uuid, Duration duration, String server) {
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
package com.alttd.chat.objects.chat_log;
|
|
||||||
|
|
||||||
import com.alttd.altitudeweb.model.ChatMessageDto;
|
|
||||||
import jakarta.validation.ConstraintViolation;
|
|
||||||
import jakarta.validation.Validation;
|
|
||||||
import jakarta.validation.Validator;
|
|
||||||
import jakarta.validation.ValidatorFactory;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
|
||||||
|
|
||||||
import java.time.ZoneOffset;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@UtilityClass
|
|
||||||
public class ChatLogMapper {
|
|
||||||
|
|
||||||
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
|
||||||
Validator validator = factory.getValidator();
|
|
||||||
|
|
||||||
public Optional<ChatMessageDto> toDto(ChatLog chatLog) {
|
|
||||||
ChatMessageDto chatMessageDto = new ChatMessageDto();
|
|
||||||
if (chatLog.getMiniMessage() == null) {
|
|
||||||
throw new IllegalArgumentException("MiniMessage cannot be null");
|
|
||||||
}
|
|
||||||
chatMessageDto.setUuid(chatLog.getUuid());
|
|
||||||
chatMessageDto.setTimestamp(chatLog.getTimestamp().atOffset(ZoneOffset.UTC));
|
|
||||||
chatMessageDto.setServer(chatLog.getServer());
|
|
||||||
chatMessageDto.setType(ChatLogTypeMapper.toDto(chatLog.getType()));
|
|
||||||
chatMessageDto.setChannel(chatLog.getChannel());
|
|
||||||
chatMessageDto.setReceiver(chatLog.getReceiver());
|
|
||||||
chatMessageDto.setMessage(GsonComponentSerializer.gson().serialize(chatLog.getMiniMessage()));
|
|
||||||
chatMessageDto.setBlocked(chatLog.isBlocked());
|
|
||||||
if (checkIsInvalid(chatMessageDto)) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
return Optional.of(chatMessageDto);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkIsInvalid(ChatMessageDto chatMessageDto) {
|
|
||||||
Set<ConstraintViolation<ChatMessageDto>> violations = validator.validate(chatMessageDto);
|
|
||||||
if (violations.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
log.error("Validation failed for chat message: {}, {}", chatMessageDto, violations);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.alttd.chat.objects.chat_log;
|
|
||||||
|
|
||||||
public enum ChatLogType {
|
|
||||||
PUBLIC,
|
|
||||||
GLOBAL,
|
|
||||||
PARTY,
|
|
||||||
GAC,
|
|
||||||
MSG,
|
|
||||||
CUSTOM;
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package com.alttd.chat.objects.chat_log;
|
|
||||||
|
|
||||||
import com.alttd.altitudeweb.model.ChatMessageDto;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class ChatLogTypeMapper {
|
|
||||||
|
|
||||||
public static String toDb(ChatLogType chatLogType) {
|
|
||||||
return switch (chatLogType) {
|
|
||||||
case PUBLIC -> "public";
|
|
||||||
case GLOBAL -> "global";
|
|
||||||
case PARTY -> "party";
|
|
||||||
case GAC -> "gac";
|
|
||||||
case MSG -> "msg";
|
|
||||||
case CUSTOM -> "custom";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChatMessageDto.TypeEnum toDto(ChatLogType chatLogType) {
|
|
||||||
return switch (chatLogType) {
|
|
||||||
case PUBLIC -> ChatMessageDto.TypeEnum.PUBLIC;
|
|
||||||
case GLOBAL -> ChatMessageDto.TypeEnum.GLOBAL;
|
|
||||||
case PARTY -> ChatMessageDto.TypeEnum.PARTY;
|
|
||||||
case GAC -> ChatMessageDto.TypeEnum.GAC;
|
|
||||||
case MSG -> ChatMessageDto.TypeEnum.MSG;
|
|
||||||
case CUSTOM -> ChatMessageDto.TypeEnum.CUSTOM;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChatLogType fromDb(String dbType) {
|
|
||||||
return switch (dbType) {
|
|
||||||
case "public" -> ChatLogType.PUBLIC;
|
|
||||||
case "global" -> ChatLogType.GLOBAL;
|
|
||||||
case "party" -> ChatLogType.PARTY;
|
|
||||||
case "gac" -> ChatLogType.GAC;
|
|
||||||
case "msg" -> ChatLogType.MSG;
|
|
||||||
case "custom" -> ChatLogType.CUSTOM;
|
|
||||||
default -> throw new IllegalArgumentException("Invalid chat log type: " + dbType);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
package com.alttd.chat.objects.chat_log;
|
|
||||||
|
|
||||||
import com.alttd.altitudeweb.api.ChatApi;
|
|
||||||
import com.alttd.altitudeweb.invoker.ApiClient;
|
|
||||||
import com.alttd.altitudeweb.invoker.ApiException;
|
|
||||||
import com.alttd.altitudeweb.model.ChatMessageDto;
|
|
||||||
import com.alttd.chat.config.Config;
|
|
||||||
import com.alttd.chat.util.ALogger;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
public class ChatLogWebHandler {
|
|
||||||
|
|
||||||
private static final int MAX_QUEUE_SIZE = 100;
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ChatLogWebHandler.class);
|
|
||||||
|
|
||||||
private final Queue<ChatLog> queue = new ConcurrentLinkedQueue<>();
|
|
||||||
private final ExecutorService executor = Executors.newSingleThreadExecutor();
|
|
||||||
|
|
||||||
private final ChatApi chatApi;
|
|
||||||
|
|
||||||
public ChatLogWebHandler() {
|
|
||||||
ApiClient apiClient = new ApiClient();
|
|
||||||
apiClient.setBasePath(Config.CHAT_WEB_SERVER_BASE_URL);
|
|
||||||
|
|
||||||
chatApi = new ChatApi(apiClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
private volatile boolean sending;
|
|
||||||
|
|
||||||
public void forwardChatLogToWeb(ChatLog chatLog) {
|
|
||||||
if (queue.size() >= MAX_QUEUE_SIZE) {
|
|
||||||
queue.clear();
|
|
||||||
log.error("Chat log queue overflow, is the web backend still running?");
|
|
||||||
}
|
|
||||||
|
|
||||||
queue.add(chatLog);
|
|
||||||
triggerSend();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void triggerSend() {
|
|
||||||
if (sending) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (this) {
|
|
||||||
if (sending || queue.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sending = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
executor.execute(this::sendBatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendBatch() {
|
|
||||||
try {
|
|
||||||
ArrayList<ChatLog> chatLogList = new ArrayList<>();
|
|
||||||
|
|
||||||
ChatLog log;
|
|
||||||
while ((log = queue.poll()) != null) {
|
|
||||||
if (log.getMiniMessage() == null) {
|
|
||||||
ALogger.warn("No mini message for message, skipping");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
chatLogList.add(log);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ChatMessageDto> batch = chatLogList.stream()
|
|
||||||
.map(ChatLogMapper::toDto)
|
|
||||||
.filter(Optional::isPresent)
|
|
||||||
.map(Optional::get)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
if (!chatLogList.isEmpty()) {
|
|
||||||
try {
|
|
||||||
chatApi.sendChatMessages(batch);
|
|
||||||
} catch (ApiException e) {
|
|
||||||
ALogger.error("Failed to send chat messages to web backend, " +
|
|
||||||
"adding messages back to queue for another try", e
|
|
||||||
);
|
|
||||||
queue.addAll(chatLogList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
synchronized (this) {
|
|
||||||
sending = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerSend();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
`java-library`
|
`java-library`
|
||||||
id("com.gradleup.shadow") version "9.6.1"
|
id("io.github.goooler.shadow") version "8.1.8"
|
||||||
id("com.github.ben-manes.versions") version "0.52.0"
|
id("com.github.ben-manes.versions") version "0.52.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ subprojects {
|
|||||||
|
|
||||||
java {
|
java {
|
||||||
toolchain {
|
toolchain {
|
||||||
languageVersion.set(JavaLanguageVersion.of(25))
|
languageVersion.set(JavaLanguageVersion.of(21))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
plugins {
|
plugins {
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
id("com.gradleup.shadow")
|
id("io.github.goooler.shadow")
|
||||||
}
|
}
|
||||||
|
|
||||||
val nexusUser = providers.gradleProperty("alttdSnapshotUsername").orNull ?: System.getenv("NEXUS_USERNAME")
|
|
||||||
val nexusPass = providers.gradleProperty("alttdSnapshotPassword").orNull ?: System.getenv("NEXUS_PASSWORD")
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":api")) // API
|
implementation(project(":api")) // API
|
||||||
compileOnly("com.alttd.cosmos:cosmos-api:26.2.build.17-stable")
|
compileOnly("com.alttd.cosmos:cosmos-api:1.21.10-R0.1-SNAPSHOT") {
|
||||||
compileOnly("org.projectlombok:lombok:1.18.46")
|
isChanging = true
|
||||||
annotationProcessor("org.projectlombok:lombok:1.18.46")
|
}
|
||||||
compileOnly("com.gitlab.ruany:LiteBansAPI:0.6.1") // move to proxy
|
compileOnly("com.gitlab.ruany:LiteBansAPI:0.6.1") // move to proxy
|
||||||
compileOnly("org.apache.commons:commons-lang3:3.17.0") // needs an alternative, already removed from upstream api and will be removed in server
|
compileOnly("org.apache.commons:commons-lang3:3.17.0") // needs an alternative, already removed from upstream api and will be removed in server
|
||||||
compileOnly("net.luckperms:api:5.5") // Luckperms
|
compileOnly("net.luckperms:api:5.5") // Luckperms
|
||||||
implementation("com.alttd.inventory_gui:InventoryGUI:1.1.5-SNAPSHOT")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
|||||||
@@ -35,15 +35,11 @@ public class ChatPlugin extends JavaPlugin {
|
|||||||
instance = this;
|
instance = this;
|
||||||
ALogger.init(getSLF4JLogger());
|
ALogger.init(getSLF4JLogger());
|
||||||
chatAPI = new ChatImplementation();
|
chatAPI = new ChatImplementation();
|
||||||
ChatLogHandler chatLogHandler = ChatLogHandler.getInstance(true);
|
chatHandler = new ChatHandler();
|
||||||
chatHandler = new ChatHandler(chatLogHandler);
|
|
||||||
DatabaseConnection.initialize();
|
DatabaseConnection.initialize();
|
||||||
serverConfig = new ServerConfig(ServerName.getServerName());
|
serverConfig = new ServerConfig(ServerName.getServerName());
|
||||||
registerListener(new PlayerListener(serverConfig),
|
ChatLogHandler chatLogHandler = ChatLogHandler.getInstance(true);
|
||||||
new ChatListener(chatLogHandler),
|
registerListener(new PlayerListener(serverConfig), new ChatListener(chatLogHandler), new BookListener(), new ShutdownListener(chatLogHandler, this));
|
||||||
new BookListener(),
|
|
||||||
new ShutdownListener(chatLogHandler, this)
|
|
||||||
);
|
|
||||||
if (serverConfig.GLOBALCHAT) {
|
if (serverConfig.GLOBALCHAT) {
|
||||||
registerCommand("globalchat", new GlobalChat());
|
registerCommand("globalchat", new GlobalChat());
|
||||||
registerCommand("toggleglobalchat", new ToggleGlobalChat());
|
registerCommand("toggleglobalchat", new ToggleGlobalChat());
|
||||||
@@ -62,15 +58,12 @@ public class ChatPlugin extends JavaPlugin {
|
|||||||
if (!(channel instanceof CustomChannel customChannel)) {
|
if (!(channel instanceof CustomChannel customChannel)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
this.getServer()
|
this.getServer().getCommandMap().register(channel.getChannelName().toLowerCase(), new ChatChannel(customChannel));
|
||||||
.getCommandMap()
|
|
||||||
.register(channel.getChannelName().toLowerCase(), new ChatChannel(customChannel));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String messageChannel = Config.MESSAGECHANNEL;
|
String messageChannel = Config.MESSAGECHANNEL;
|
||||||
getServer().getMessenger().registerOutgoingPluginChannel(this, messageChannel);
|
getServer().getMessenger().registerOutgoingPluginChannel(this, messageChannel);
|
||||||
getServer().getMessenger()
|
getServer().getMessenger().registerIncomingPluginChannel(this, messageChannel, new PluginMessage());
|
||||||
.registerIncomingPluginChannel(this, messageChannel, new PluginMessage(chatLogHandler));
|
|
||||||
|
|
||||||
NicknamesEvents nicknamesEvents = new NicknamesEvents();
|
NicknamesEvents nicknamesEvents = new NicknamesEvents();
|
||||||
getServer().getMessenger().registerIncomingPluginChannel(this, messageChannel, nicknamesEvents);
|
getServer().getMessenger().registerIncomingPluginChannel(this, messageChannel, nicknamesEvents);
|
||||||
@@ -117,9 +110,7 @@ public class ChatPlugin extends JavaPlugin {
|
|||||||
chatAPI.reloadConfig();
|
chatAPI.reloadConfig();
|
||||||
chatAPI.reloadChatFilters();
|
chatAPI.reloadChatFilters();
|
||||||
serverConfig = new ServerConfig(ServerName.getServerName());
|
serverConfig = new ServerConfig(ServerName.getServerName());
|
||||||
Bukkit.broadcast(Utility.parseMiniMessage("Reloaded ChatPlugin Config.").asComponent(),
|
Bukkit.broadcast(Utility.parseMiniMessage("Reloaded ChatPlugin Config.").asComponent(), "command.chat.reloadchat");
|
||||||
"command.chat.reloadchat"
|
|
||||||
);
|
|
||||||
ALogger.info("Reloaded ChatPlugin config.");
|
ALogger.info("Reloaded ChatPlugin config.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import com.alttd.chat.objects.ChatFilter;
|
|||||||
import com.alttd.chat.objects.ChatUser;
|
import com.alttd.chat.objects.ChatUser;
|
||||||
import com.alttd.chat.objects.ModifiableString;
|
import com.alttd.chat.objects.ModifiableString;
|
||||||
import com.alttd.chat.objects.channels.CustomChannel;
|
import com.alttd.chat.objects.channels.CustomChannel;
|
||||||
import com.alttd.chat.objects.chat_log.ChatLogHandler;
|
|
||||||
import com.alttd.chat.objects.chat_log.ChatLogType;
|
|
||||||
import com.alttd.chat.util.ALogger;
|
import com.alttd.chat.util.ALogger;
|
||||||
import com.alttd.chat.util.GalaxyUtility;
|
import com.alttd.chat.util.GalaxyUtility;
|
||||||
import com.alttd.chat.util.ServerName;
|
import com.alttd.chat.util.ServerName;
|
||||||
@@ -30,7 +28,6 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jspecify.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -43,10 +40,8 @@ public class ChatHandler {
|
|||||||
private final ChatPlugin plugin;
|
private final ChatPlugin plugin;
|
||||||
|
|
||||||
private final ComponentLike GCNOTENABLED;
|
private final ComponentLike GCNOTENABLED;
|
||||||
private final ChatLogHandler chatLogHandler;
|
|
||||||
|
|
||||||
public ChatHandler(ChatLogHandler chatLogHandler) {
|
public ChatHandler() {
|
||||||
this.chatLogHandler = chatLogHandler;
|
|
||||||
plugin = ChatPlugin.getInstance();
|
plugin = ChatPlugin.getInstance();
|
||||||
GCNOTENABLED = Utility.parseMiniMessage(Config.GCNOTENABLED);
|
GCNOTENABLED = Utility.parseMiniMessage(Config.GCNOTENABLED);
|
||||||
}
|
}
|
||||||
@@ -69,8 +64,7 @@ public class ChatHandler {
|
|||||||
GalaxyUtility.sendBlockedNotification("DM Language",
|
GalaxyUtility.sendBlockedNotification("DM Language",
|
||||||
player,
|
player,
|
||||||
Utility.parseMiniMessage(Utility.parseColors(modifiableString.string())),
|
Utility.parseMiniMessage(Utility.parseColors(modifiableString.string())),
|
||||||
target
|
target);
|
||||||
);
|
|
||||||
return; // the message was blocked
|
return; // the message was blocked
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,8 +73,7 @@ public class ChatHandler {
|
|||||||
sendPrivateMessage(player, target, "privatemessage", component.asComponent());
|
sendPrivateMessage(player, target, "privatemessage", component.asComponent());
|
||||||
ComponentLike spymessage = Utility.parseMiniMessage(Config.MESSAGESPY, placeholders);
|
ComponentLike spymessage = Utility.parseMiniMessage(Config.MESSAGESPY, placeholders);
|
||||||
for (Player pl : Bukkit.getOnlinePlayers()) {
|
for (Player pl : Bukkit.getOnlinePlayers()) {
|
||||||
if (pl.hasPermission(Config.SPYPERMISSION) && ChatUserManager.getChatUser(pl.getUniqueId())
|
if (pl.hasPermission(Config.SPYPERMISSION) && ChatUserManager.getChatUser(pl.getUniqueId()).isSpy() && !pl.equals(player) && !pl.getName().equalsIgnoreCase(target)) {
|
||||||
.isSpy() && !pl.equals(player) && !pl.getName().equalsIgnoreCase(target)) {
|
|
||||||
pl.sendMessage(spymessage);
|
pl.sendMessage(spymessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,8 +96,7 @@ public class ChatHandler {
|
|||||||
GalaxyUtility.sendBlockedNotification("DM Language",
|
GalaxyUtility.sendBlockedNotification("DM Language",
|
||||||
player,
|
player,
|
||||||
Utility.parseMiniMessage(Utility.parseColors(modifiableString.string())),
|
Utility.parseMiniMessage(Utility.parseColors(modifiableString.string())),
|
||||||
target
|
target);
|
||||||
);
|
|
||||||
return; // the message was blocked
|
return; // the message was blocked
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,8 +108,7 @@ public class ChatHandler {
|
|||||||
sendPrivateMessage(player, target, "privatemessage", messageComponent);
|
sendPrivateMessage(player, target, "privatemessage", messageComponent);
|
||||||
ComponentLike spymessage = Utility.parseMiniMessage(Config.MESSAGESPY, placeholders);
|
ComponentLike spymessage = Utility.parseMiniMessage(Config.MESSAGESPY, placeholders);
|
||||||
for (Player pl : Bukkit.getOnlinePlayers()) {
|
for (Player pl : Bukkit.getOnlinePlayers()) {
|
||||||
if (pl.hasPermission(Config.SPYPERMISSION) && ChatUserManager.getChatUser(pl.getUniqueId())
|
if (pl.hasPermission(Config.SPYPERMISSION) && ChatUserManager.getChatUser(pl.getUniqueId()).isSpy() && !pl.equals(player) && !pl.getName().equalsIgnoreCase(target)) {
|
||||||
.isSpy() && !pl.equals(player) && !pl.getName().equalsIgnoreCase(target)) {
|
|
||||||
pl.sendMessage(spymessage);
|
pl.sendMessage(spymessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,9 +127,7 @@ public class ChatHandler {
|
|||||||
|
|
||||||
long timeLeft = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - user.getGcCooldown());
|
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
|
if (timeLeft <= Config.GCCOOLDOWN && !player.hasPermission("chat.globalchat.cooldownbypass")) { // player is on cooldown and should wait x seconds
|
||||||
player.sendRichMessage(Config.GCONCOOLDOWN,
|
player.sendRichMessage(Config.GCONCOOLDOWN, Placeholder.parsed("cooldown", Config.GCCOOLDOWN - timeLeft + ""));
|
||||||
Placeholder.parsed("cooldown", Config.GCCOOLDOWN - timeLeft + "")
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,22 +148,11 @@ public class ChatHandler {
|
|||||||
GalaxyUtility.sendBlockedNotification("GC Language",
|
GalaxyUtility.sendBlockedNotification("GC Language",
|
||||||
player,
|
player,
|
||||||
Utility.parseMiniMessage(Utility.parseColors(modifiableString.string())),
|
Utility.parseMiniMessage(Utility.parseColors(modifiableString.string())),
|
||||||
""
|
"");
|
||||||
);
|
|
||||||
return; // the message was blocked
|
return; // the message was blocked
|
||||||
}
|
}
|
||||||
component = modifiableString.component();
|
component = modifiableString.component();
|
||||||
|
|
||||||
chatLogHandler.addChatLog(player.getUniqueId(),
|
|
||||||
Bukkit.getServerName(),
|
|
||||||
message,
|
|
||||||
ChatLogType.GLOBAL,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
component,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
user.setGcCooldown(System.currentTimeMillis());
|
user.setGcCooldown(System.currentTimeMillis());
|
||||||
sendPluginMessage(player, "globalchat", component);
|
sendPluginMessage(player, "globalchat", component);
|
||||||
}
|
}
|
||||||
@@ -202,16 +180,11 @@ public class ChatHandler {
|
|||||||
Component component = Utility.parseMiniMessage(channel.getFormat(), placeholders).asComponent();
|
Component component = Utility.parseMiniMessage(channel.getFormat(), placeholders).asComponent();
|
||||||
|
|
||||||
ModifiableString modifiableString = new ModifiableString(component);
|
ModifiableString modifiableString = new ModifiableString(component);
|
||||||
if (!RegexManager.filterText(player.getName(),
|
if (!RegexManager.filterText(player.getName(), player.getUniqueId(), modifiableString, channel.getChannelName())) {
|
||||||
player.getUniqueId(),
|
|
||||||
modifiableString,
|
|
||||||
channel.getChannelName()
|
|
||||||
)) {
|
|
||||||
GalaxyUtility.sendBlockedNotification(channel.getChannelName() + " Language",
|
GalaxyUtility.sendBlockedNotification(channel.getChannelName() + " Language",
|
||||||
player,
|
player,
|
||||||
Utility.parseMiniMessage(Utility.parseColors(modifiableString.string())),
|
Utility.parseMiniMessage(Utility.parseColors(modifiableString.string())),
|
||||||
""
|
"");
|
||||||
);
|
|
||||||
ALogger.info("Refusing to send blocked chat message");
|
ALogger.info("Refusing to send blocked chat message");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -282,20 +255,16 @@ public class ChatHandler {
|
|||||||
|
|
||||||
if (!chatChannel.getServers().contains(ServerName.getServerName())) {
|
if (!chatChannel.getServers().contains(ServerName.getServerName())) {
|
||||||
player.sendRichMessage("<red>Unable to send messages to <channel> in this server.</red>",
|
player.sendRichMessage("<red>Unable to send messages to <channel> in this server.</red>",
|
||||||
Placeholder.parsed("channel", chatChannel.getChannelName())
|
Placeholder.parsed("channel", chatChannel.getChannelName()));
|
||||||
);
|
|
||||||
ALogger.info(String.format("Not sending chat message due to [%s] not being in this channels config",
|
ALogger.info(String.format("Not sending chat message due to [%s] not being in this channels config",
|
||||||
ServerName.getServerName()
|
ServerName.getServerName()));
|
||||||
));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<? extends Player> stream = Bukkit.getServer().getOnlinePlayers().stream()
|
Stream<? extends Player> stream = Bukkit.getServer().getOnlinePlayers().stream()
|
||||||
.filter(p -> p.hasPermission(chatChannel.getPermission()));
|
.filter(p -> p.hasPermission(chatChannel.getPermission()));
|
||||||
if (!player.hasPermission("chat.ignorebypass")) {
|
if (!player.hasPermission("chat.ignorebypass")) {
|
||||||
stream = stream.filter(receiver -> !ChatUserManager.getChatUser(receiver.getUniqueId())
|
stream = stream.filter(receiver -> !ChatUserManager.getChatUser(receiver.getUniqueId()).getIgnoredPlayers().contains(uuid)
|
||||||
.getIgnoredPlayers()
|
|
||||||
.contains(uuid)
|
|
||||||
|| receiver.hasPermission("chat.ignorebypass"));
|
|| receiver.hasPermission("chat.ignorebypass"));
|
||||||
}
|
}
|
||||||
if (chatChannel.isLocal()) {
|
if (chatChannel.isLocal()) {
|
||||||
@@ -314,16 +283,6 @@ public class ChatHandler {
|
|||||||
List<? extends Player> recipientPlayers = stream.toList();
|
List<? extends Player> recipientPlayers = stream.toList();
|
||||||
recipientPlayers.forEach(p -> p.sendMessage(component));
|
recipientPlayers.forEach(p -> p.sendMessage(component));
|
||||||
|
|
||||||
chatLogHandler.addChatLog(player.getUniqueId(),
|
|
||||||
Bukkit.getServerName(),
|
|
||||||
message,
|
|
||||||
ChatLogType.CUSTOM,
|
|
||||||
chatChannel.getChannelName(),
|
|
||||||
getLocationIfLocal(chatChannel, player),
|
|
||||||
component.asComponent(),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
List<UUID> recipientUUIDs = recipientPlayers.stream().map(Entity::getUniqueId).toList();
|
List<UUID> recipientUUIDs = recipientPlayers.stream().map(Entity::getUniqueId).toList();
|
||||||
Bukkit.getServer().getOnlinePlayers().stream()
|
Bukkit.getServer().getOnlinePlayers().stream()
|
||||||
.filter(onlinePlayer -> onlinePlayer.hasPermission(Config.SPYPERMISSION))
|
.filter(onlinePlayer -> onlinePlayer.hasPermission(Config.SPYPERMISSION))
|
||||||
@@ -331,22 +290,7 @@ public class ChatHandler {
|
|||||||
.forEach(onlinePlayer -> onlinePlayer.sendRichMessage(Config.CHANNEL_SPY,
|
.forEach(onlinePlayer -> onlinePlayer.sendRichMessage(Config.CHANNEL_SPY,
|
||||||
Placeholder.component("sender", player.name()),
|
Placeholder.component("sender", player.name()),
|
||||||
Placeholder.parsed("channel", chatChannel.getChannelName()),
|
Placeholder.parsed("channel", chatChannel.getChannelName()),
|
||||||
Placeholder.parsed("message", message)
|
Placeholder.parsed("message", message)));
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @Nullable String getLocationIfLocal(CustomChannel chatChannel, Player player) {
|
|
||||||
if (!chatChannel.isLocal()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String format = String.format("%s;%s",
|
|
||||||
player.getLocation().getBlockX(),
|
|
||||||
player.getLocation().getBlockZ()
|
|
||||||
);
|
|
||||||
if (format.length() > 36) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return format;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendPluginMessage(Player player, String channel, Component component) {
|
private void sendPluginMessage(Player player, String channel, Component component) {
|
||||||
@@ -382,14 +326,9 @@ public class ChatHandler {
|
|||||||
if (user == null) {
|
if (user == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (user.isMuted() || (ChatPlugin.getInstance().serverMuted() && !player.hasPermission(
|
if (user.isMuted() || (ChatPlugin.getInstance().serverMuted() && !player.hasPermission("chat.bypass-server-muted"))) {
|
||||||
"chat.bypass-server-muted"))) {
|
|
||||||
// if (Database.get().isPlayerMuted(player.getUniqueId(), null) || (ChatPlugin.getInstance().serverMuted() && !player.hasPermission("chat.bypass-server-muted"))) {
|
// if (Database.get().isPlayerMuted(player.getUniqueId(), null) || (ChatPlugin.getInstance().serverMuted() && !player.hasPermission("chat.bypass-server-muted"))) {
|
||||||
GalaxyUtility.sendBlockedNotification(prefix,
|
GalaxyUtility.sendBlockedNotification(prefix, player, Utility.parseMiniMessage(Utility.stripTokens(message)), "");
|
||||||
player,
|
|
||||||
Utility.parseMiniMessage(Utility.stripTokens(message)),
|
|
||||||
""
|
|
||||||
);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import com.alttd.chat.managers.ChatUserManager;
|
|||||||
import com.alttd.chat.managers.RegexManager;
|
import com.alttd.chat.managers.RegexManager;
|
||||||
import com.alttd.chat.objects.*;
|
import com.alttd.chat.objects.*;
|
||||||
import com.alttd.chat.objects.chat_log.ChatLogHandler;
|
import com.alttd.chat.objects.chat_log.ChatLogHandler;
|
||||||
import com.alttd.chat.objects.chat_log.ChatLogType;
|
|
||||||
import com.alttd.chat.util.ALogger;
|
import com.alttd.chat.util.ALogger;
|
||||||
import com.alttd.chat.util.GalaxyUtility;
|
import com.alttd.chat.util.GalaxyUtility;
|
||||||
import com.alttd.chat.util.ServerName;
|
import com.alttd.chat.util.ServerName;
|
||||||
@@ -56,14 +55,9 @@ public class ChatListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Component formatComponent = Component.text("%message%");
|
Component formatComponent = Component.text("%message%");
|
||||||
ComponentLike message = parseMessageContent(event.player(),
|
ComponentLike message = parseMessageContent(event.player(), plainTextComponentSerializer.serialize(event.originalMessage()));
|
||||||
plainTextComponentSerializer.serialize(event.originalMessage())
|
|
||||||
);
|
|
||||||
|
|
||||||
event.result(formatComponent.replaceText(TextReplacementConfig.builder()
|
event.result(formatComponent.replaceText(TextReplacementConfig.builder().match("%message%").replacement(message).build()));
|
||||||
.match("%message%")
|
|
||||||
.replacement(message)
|
|
||||||
.build()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
@@ -73,14 +67,9 @@ public class ChatListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Component formatComponent = Component.text("%message%");
|
Component formatComponent = Component.text("%message%");
|
||||||
ComponentLike message = parseMessageContent(event.player(),
|
ComponentLike message = parseMessageContent(event.player(), plainTextComponentSerializer.serialize(event.originalMessage()));
|
||||||
plainTextComponentSerializer.serialize(event.originalMessage())
|
|
||||||
);
|
|
||||||
|
|
||||||
event.result(formatComponent.replaceText(TextReplacementConfig.builder()
|
event.result(formatComponent.replaceText(TextReplacementConfig.builder().match("%message%").replacement(message).build()));
|
||||||
.match("%message%")
|
|
||||||
.replacement(message)
|
|
||||||
.build()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Component mention = MiniMessage.miniMessage().deserialize(Config.MENTIONPLAYERTAG);
|
private final Component mention = MiniMessage.miniMessage().deserialize(Config.MENTIONPLAYERTAG);
|
||||||
@@ -103,9 +92,8 @@ public class ChatListener implements Listener {
|
|||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
|
|
||||||
ComponentLike input = event.message().colorIfAbsent(NamedTextColor.WHITE);
|
ComponentLike input = event.message().colorIfAbsent(NamedTextColor.WHITE);
|
||||||
Component inputComponent = input.asComponent();
|
|
||||||
|
|
||||||
ModifiableString modifiableString = new ModifiableString(inputComponent);
|
ModifiableString modifiableString = new ModifiableString(input.asComponent());
|
||||||
|
|
||||||
// todo a better way for this
|
// todo a better way for this
|
||||||
if (!RegexManager.filterText(player.getName(), uuid, modifiableString, true, "chat", filterType -> {
|
if (!RegexManager.filterText(player.getName(), uuid, modifiableString, true, "chat", filterType -> {
|
||||||
@@ -119,23 +107,12 @@ public class ChatListener implements Listener {
|
|||||||
out.writeUTF(uuid.toString());
|
out.writeUTF(uuid.toString());
|
||||||
out.writeUTF(modifiableString.string());
|
out.writeUTF(modifiableString.string());
|
||||||
player.sendPluginMessage(ChatPlugin.getInstance(), Config.MESSAGECHANNEL, out.toByteArray());
|
player.sendPluginMessage(ChatPlugin.getInstance(), Config.MESSAGECHANNEL, out.toByteArray());
|
||||||
}
|
})) {
|
||||||
)) {
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
GalaxyUtility.sendBlockedNotification("Language", player,
|
GalaxyUtility.sendBlockedNotification("Language", player,
|
||||||
modifiableString.component(),
|
modifiableString.component(),
|
||||||
""
|
"");
|
||||||
);
|
chatLogHandler.addChatLog(uuid, ServerName.getServerName(), PlainTextComponentSerializer.plainText().serialize(input.asComponent()), true);
|
||||||
String originalMessage = PlainTextComponentSerializer.plainText().serialize(inputComponent);
|
|
||||||
chatLogHandler.addChatLog(uuid,
|
|
||||||
ServerName.getServerName(),
|
|
||||||
originalMessage,
|
|
||||||
ChatLogType.PUBLIC,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
render(player, inputComponent).asComponent(),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
return; // the message was blocked
|
return; // the message was blocked
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,13 +120,8 @@ public class ChatListener implements Listener {
|
|||||||
.map(audience -> (Player) audience);
|
.map(audience -> (Player) audience);
|
||||||
|
|
||||||
if (!player.hasPermission("chat.ignorebypass")) {
|
if (!player.hasPermission("chat.ignorebypass")) {
|
||||||
stream = stream.filter(receiver -> {
|
stream = stream.filter(receiver -> !ChatUserManager.getChatUser(receiver.getUniqueId()).getIgnoredPlayers().contains(uuid)
|
||||||
boolean isPlayerIgnored = ChatUserManager
|
|| receiver.hasPermission("chat.ignorebypass"));
|
||||||
.getChatUser(receiver.getUniqueId())
|
|
||||||
.getIgnoredPlayers()
|
|
||||||
.contains(uuid);
|
|
||||||
return !isPlayerIgnored || receiver.hasPermission("chat.ignorebypass");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
Set<Player> receivers = stream.collect(Collectors.toSet());
|
Set<Player> receivers = stream.collect(Collectors.toSet());
|
||||||
|
|
||||||
@@ -163,16 +135,8 @@ public class ChatListener implements Listener {
|
|||||||
for (Player pingPlayer : playersToPing) {
|
for (Player pingPlayer : playersToPing) {
|
||||||
pingPlayer.playSound(pingPlayer.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1, 1);
|
pingPlayer.playSound(pingPlayer.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1, 1);
|
||||||
}
|
}
|
||||||
chatLogHandler.addChatLog(uuid,
|
chatLogHandler.addChatLog(uuid, ServerName.getServerName(), modifiableString.string(), false);
|
||||||
ServerName.getServerName(),
|
ALogger.info(PlainTextComponentSerializer.plainText().serialize(input.asComponent()));
|
||||||
modifiableString.string(),
|
|
||||||
ChatLogType.PUBLIC,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
input.asComponent(),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
ALogger.info(PlainTextComponentSerializer.plainText().serialize(inputComponent));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pingPlayers(Set<Player> playersToPing, ModifiableString modifiableString, Player player) {
|
private void pingPlayers(Set<Player> playersToPing, ModifiableString modifiableString, Player player) {
|
||||||
@@ -201,9 +165,7 @@ public class ChatListener implements Listener {
|
|||||||
// return ;
|
// return ;
|
||||||
// });
|
// });
|
||||||
|
|
||||||
if (!ChatUserManager.getChatUser(onlinePlayer.getUniqueId())
|
if (!ChatUserManager.getChatUser(onlinePlayer.getUniqueId()).getIgnoredPlayers().contains(player.getUniqueId())
|
||||||
.getIgnoredPlayers()
|
|
||||||
.contains(player.getUniqueId())
|
|
||||||
|| player.hasPermission("chat.ignorebypass")) {
|
|| player.hasPermission("chat.ignorebypass")) {
|
||||||
playersToPing.add(onlinePlayer);
|
playersToPing.add(onlinePlayer);
|
||||||
}
|
}
|
||||||
@@ -213,9 +175,7 @@ public class ChatListener implements Listener {
|
|||||||
.match(nickPattern)
|
.match(nickPattern)
|
||||||
.replacement(mention.append(onlinePlayerUser.getDisplayName()))
|
.replacement(mention.append(onlinePlayerUser.getDisplayName()))
|
||||||
.build());
|
.build());
|
||||||
if (!ChatUserManager.getChatUser(onlinePlayer.getUniqueId())
|
if (!ChatUserManager.getChatUser(onlinePlayer.getUniqueId()).getIgnoredPlayers().contains(player.getUniqueId())
|
||||||
.getIgnoredPlayers()
|
|
||||||
.contains(player.getUniqueId())
|
|
||||||
|| player.hasPermission("chat.ignorebypass")) {
|
|| player.hasPermission("chat.ignorebypass")) {
|
||||||
playersToPing.add(onlinePlayer);
|
playersToPing.add(onlinePlayer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import com.alttd.chat.objects.Party;
|
|||||||
import com.alttd.chat.objects.PartyUser;
|
import com.alttd.chat.objects.PartyUser;
|
||||||
import com.alttd.chat.objects.channels.Channel;
|
import com.alttd.chat.objects.channels.Channel;
|
||||||
import com.alttd.chat.objects.channels.CustomChannel;
|
import com.alttd.chat.objects.channels.CustomChannel;
|
||||||
import com.alttd.chat.objects.chat_log.ChatLogHandler;
|
|
||||||
import com.alttd.chat.objects.chat_log.ChatLogType;
|
|
||||||
import com.alttd.chat.util.ALogger;
|
import com.alttd.chat.util.ALogger;
|
||||||
import com.alttd.chat.util.ServerName;
|
import com.alttd.chat.util.ServerName;
|
||||||
import com.alttd.chat.util.Utility;
|
import com.alttd.chat.util.Utility;
|
||||||
@@ -20,7 +18,6 @@ import com.google.common.io.ByteStreams;
|
|||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.ComponentLike;
|
import net.kyori.adventure.text.ComponentLike;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -32,12 +29,6 @@ import java.util.UUID;
|
|||||||
|
|
||||||
public class PluginMessage implements PluginMessageListener {
|
public class PluginMessage implements PluginMessageListener {
|
||||||
|
|
||||||
private final ChatLogHandler chatLogHandler;
|
|
||||||
|
|
||||||
public PluginMessage(ChatLogHandler chatLogHandler) {
|
|
||||||
this.chatLogHandler = chatLogHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginMessageReceived(String channel, @NotNull Player ignored, byte[] bytes) {
|
public void onPluginMessageReceived(String channel, @NotNull Player ignored, byte[] bytes) {
|
||||||
if (!channel.equals(Config.MESSAGECHANNEL)) {
|
if (!channel.equals(Config.MESSAGECHANNEL)) {
|
||||||
@@ -57,25 +48,13 @@ public class PluginMessage implements PluginMessageListener {
|
|||||||
}
|
}
|
||||||
ChatUser chatUser = ChatUserManager.getChatUser(uuid);
|
ChatUser chatUser = ChatUserManager.getChatUser(uuid);
|
||||||
if (isTargetNotIgnored(chatUser, targetuuid)) {
|
if (isTargetNotIgnored(chatUser, targetuuid)) {
|
||||||
Component component = GsonComponentSerializer.gson().deserialize(message);
|
player.sendMessage(GsonComponentSerializer.gson().deserialize(message));
|
||||||
player.sendMessage(component);
|
|
||||||
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1,
|
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1,
|
||||||
1
|
1); // todo load this from config
|
||||||
); // todo load this from config
|
|
||||||
ChatUser user = ChatUserManager.getChatUser(uuid);
|
ChatUser user = ChatUserManager.getChatUser(uuid);
|
||||||
if (!user.getReplyContinueTarget().equalsIgnoreCase(target)) {
|
if (!user.getReplyContinueTarget().equalsIgnoreCase(target)) {
|
||||||
user.setReplyTarget(target);
|
user.setReplyTarget(target);
|
||||||
}
|
}
|
||||||
// Handled here since this is after the ignore check and is only send once
|
|
||||||
chatLogHandler.addChatLog(uuid,
|
|
||||||
ServerName.getServerName(),
|
|
||||||
PlainTextComponentSerializer.plainText().serialize(component),
|
|
||||||
ChatLogType.MSG,
|
|
||||||
null,
|
|
||||||
player.getUniqueId().toString(),
|
|
||||||
component,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "privatemessageout" -> {
|
case "privatemessageout" -> {
|
||||||
@@ -90,18 +69,9 @@ public class PluginMessage implements PluginMessageListener {
|
|||||||
ChatUser chatUser = ChatUserManager.getChatUser(uuid);
|
ChatUser chatUser = ChatUserManager.getChatUser(uuid);
|
||||||
if (isTargetNotIgnored(chatUser, targetuuid)) {
|
if (isTargetNotIgnored(chatUser, targetuuid)) {
|
||||||
chatUser.setReplyTarget(target);
|
chatUser.setReplyTarget(target);
|
||||||
Component component = GsonComponentSerializer.gson().deserialize(message);
|
player.sendMessage(GsonComponentSerializer.gson().deserialize(message));
|
||||||
player.sendMessage(component);
|
// ChatUser user = ChatUserManager.getChatUser(uuid);
|
||||||
// Handled here since this is after the ignore check and is only send once
|
// user.setReplyTarget(target);
|
||||||
chatLogHandler.addChatLog(uuid,
|
|
||||||
ServerName.getServerName(),
|
|
||||||
PlainTextComponentSerializer.plainText().serialize(component),
|
|
||||||
ChatLogType.MSG,
|
|
||||||
null,
|
|
||||||
player.getUniqueId().toString(),
|
|
||||||
component,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "globalchat" -> {
|
case "globalchat" -> {
|
||||||
@@ -112,11 +82,10 @@ public class PluginMessage implements PluginMessageListener {
|
|||||||
UUID uuid = UUID.fromString(in.readUTF());
|
UUID uuid = UUID.fromString(in.readUTF());
|
||||||
String message = in.readUTF();
|
String message = in.readUTF();
|
||||||
|
|
||||||
Component component = GsonComponentSerializer.gson().deserialize(message);
|
|
||||||
Bukkit.getOnlinePlayers().stream().filter(p -> p.hasPermission(Config.GCPERMISSION)).forEach(p -> {
|
Bukkit.getOnlinePlayers().stream().filter(p -> p.hasPermission(Config.GCPERMISSION)).forEach(p -> {
|
||||||
ChatUser chatUser = ChatUserManager.getChatUser(p.getUniqueId());
|
ChatUser chatUser = ChatUserManager.getChatUser(p.getUniqueId());
|
||||||
if (isTargetNotIgnored(chatUser, uuid)) {
|
if (isTargetNotIgnored(chatUser, uuid)) {
|
||||||
p.sendMessage(component);
|
p.sendMessage(GsonComponentSerializer.gson().deserialize(message));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -138,7 +107,6 @@ public class PluginMessage implements PluginMessageListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chatChannel(in);
|
chatChannel(in);
|
||||||
//TODO [Stijn] [2026-07-19]: handle custom channels
|
|
||||||
}
|
}
|
||||||
case "tmppartyupdate" -> {
|
case "tmppartyupdate" -> {
|
||||||
int id = Integer.parseInt(in.readUTF());
|
int id = Integer.parseInt(in.readUTF());
|
||||||
|
|||||||
@@ -45,83 +45,13 @@ public class Nicknames implements CommandExecutor, TabCompleter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
|
||||||
if (!(sender instanceof Player player)) {
|
if (sender instanceof Player player) {
|
||||||
sender.sendMessage("Console commands are disabled.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
sender.sendRichMessage(helpMessage(sender, HelpType.ALL));
|
sender.sendRichMessage(helpMessage(sender, HelpType.ALL));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
switch (args[0].toLowerCase()) {
|
switch (args[0].toLowerCase()) {
|
||||||
case "set" -> setNickname(sender, args, player);
|
case "set":
|
||||||
case "review" -> reviewNickname(sender, args, player);
|
|
||||||
case "request" -> requestNickname(sender, args, player);
|
|
||||||
case "try" -> tryNickname(sender, args, player);
|
|
||||||
case "current" -> showCurrentNickname(sender, player);
|
|
||||||
case "help" ->
|
|
||||||
sender.sendRichMessage(helpMessage(sender, HelpType.ALL) + "For more info on nicknames and how to use rgb colors go to: <aqua>https://alttd.com/nicknames<white>");
|
|
||||||
default -> sender.sendRichMessage(helpMessage(sender, HelpType.ALL));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showCurrentNickname(@NotNull CommandSender sender, Player player) {
|
|
||||||
if (!hasPermission(sender, "chat.command.nick.current")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ChatUser chatUser = ChatUserManager.getChatUser(player.getUniqueId());
|
|
||||||
TagResolver placeholders = TagResolver.resolver(
|
|
||||||
Placeholder.component("nickname", chatUser.getDisplayName()),
|
|
||||||
Placeholder.parsed("currentnickname", chatUser.getNickNameString())
|
|
||||||
);
|
|
||||||
player.sendRichMessage(Config.NICK_CURRENT, placeholders);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryNickname(@NotNull CommandSender sender, String[] args, Player player) {
|
|
||||||
if (args.length != 2 || !hasPermission(sender, "chat.command.nick.try")) {
|
|
||||||
sender.sendRichMessage(helpMessage(sender, HelpType.TRY));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LuckPerms api = ChatAPI.get().getLuckPerms();
|
|
||||||
if (api == null) {
|
|
||||||
sender.sendRichMessage(Config.NICK_NO_LUCKPERMS);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!NickUtilities.validNick(player, player, args[1])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sender.sendRichMessage(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])),
|
|
||||||
Placeholder.unparsed("nickrequest", args[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void requestNickname(@NotNull CommandSender sender, String[] args, Player player) {
|
|
||||||
if (args.length != 2 || !hasPermission(sender, "chat.command.nick.request")) {
|
|
||||||
sender.sendRichMessage(helpMessage(sender, HelpType.REQUEST));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
new BukkitRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
handleNickRequest(player, args[1]);
|
|
||||||
}
|
|
||||||
}.runTaskAsynchronously(ChatPlugin.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reviewNickname(@NotNull CommandSender sender, String[] args, Player player) {
|
|
||||||
if (args.length != 1 || !hasPermission(sender, "chat.command.nick.review")) {
|
|
||||||
sender.sendRichMessage(helpMessage(sender, HelpType.REVIEW));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NicknamesGui nicknamesGui = new NicknamesGui(player);
|
|
||||||
ChatPlugin.getInstance().getServer().getPluginManager().registerEvents(nicknamesGui, ChatPlugin.getInstance());
|
|
||||||
nicknamesGui.openInventory(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setNickname(@NotNull CommandSender sender, String[] args, Player player) {
|
|
||||||
if (args.length == 2 && hasPermission(sender, "chat.command.nick.set")) {
|
if (args.length == 2 && hasPermission(sender, "chat.command.nick.set")) {
|
||||||
handleNick(player, player, args[1]);
|
handleNick(player, player, args[1]);
|
||||||
} else if (args.length == 3 && hasPermission(sender, "chat.command.nick.set.others")) {
|
} else if (args.length == 3 && hasPermission(sender, "chat.command.nick.set.others")) {
|
||||||
@@ -135,6 +65,67 @@ public class Nicknames implements CommandExecutor, TabCompleter {
|
|||||||
} else if (args.length > 3) {
|
} else if (args.length > 3) {
|
||||||
sender.sendRichMessage(helpMessage(sender, HelpType.SET_SELF, HelpType.SET_OTHERS));
|
sender.sendRichMessage(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.sendRichMessage(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.sendRichMessage(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.sendRichMessage(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])),
|
||||||
|
Placeholder.unparsed("nickrequest", args[1]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sender.sendRichMessage(Config.NICK_NO_LUCKPERMS);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sender.sendRichMessage(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.sendRichMessage(Config.NICK_CURRENT, placeholders);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "help":
|
||||||
|
sender.sendRichMessage(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.sendRichMessage(helpMessage(sender, HelpType.ALL));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sender.sendMessage("Console commands are disabled.");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -145,33 +136,6 @@ public class Nicknames implements CommandExecutor, TabCompleter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
tabCompleteArgLengthOne(sender, args, completions);
|
|
||||||
} else if (args.length == 2) {
|
|
||||||
tabCompleteArgLengthTwo(sender, args, completions);
|
|
||||||
}
|
|
||||||
return completions;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void tabCompleteArgLengthTwo(CommandSender sender, String[] args, List<String> completions) {
|
|
||||||
if (!args[0].equalsIgnoreCase("set")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void tabCompleteArgLengthOne(CommandSender sender, String[] args, List<String> completions) {
|
|
||||||
List<String> choices = new ArrayList<>();
|
List<String> choices = new ArrayList<>();
|
||||||
if (sender.hasPermission("chat.command.nick.set")) {
|
if (sender.hasPermission("chat.command.nick.set")) {
|
||||||
choices.add("set");
|
choices.add("set");
|
||||||
@@ -195,6 +159,24 @@ public class Nicknames implements CommandExecutor, TabCompleter {
|
|||||||
completions.add(s);
|
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) {
|
private void handleNickRequest(Player player, String nickName) {
|
||||||
@@ -279,13 +261,31 @@ public class Nicknames implements CommandExecutor, TabCompleter {
|
|||||||
|
|
||||||
private void handleNick(Player sender, OfflinePlayer target, final String nickName) {
|
private void handleNick(Player sender, OfflinePlayer target, final String nickName) {
|
||||||
if (nickName.equalsIgnoreCase("off")) {
|
if (nickName.equalsIgnoreCase("off")) {
|
||||||
handleNickOff(sender, target);
|
|
||||||
} else if (NickUtilities.validNick(sender, target, nickName)) {
|
try {
|
||||||
setValidNick(sender, target, nickName);
|
if (target.isOnline()) {
|
||||||
|
resetNick(Objects.requireNonNull(target.getPlayer()));
|
||||||
}
|
}
|
||||||
|
Queries.removePlayerFromDataBase(target.getUniqueId());
|
||||||
|
NickCache.remove(target.getUniqueId());
|
||||||
|
nickCacheUpdate.add(target.getUniqueId());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
ALogger.error("Failed to remove nickname from database", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setValidNick(Player sender, OfflinePlayer target, String nickName) {
|
if (!sender.equals(target)) {
|
||||||
|
sender.sendRichMessage(Config.NICK_RESET_OTHERS,
|
||||||
|
Placeholder.unparsed("player", Objects.requireNonNull(target.getName())));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.isOnline() && target.getPlayer() != null) {
|
||||||
|
target.getPlayer().sendRichMessage(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()) {
|
if (target.isOnline()) {
|
||||||
setNick(target.getPlayer(), nickName);
|
setNick(target.getPlayer(), nickName);
|
||||||
} else {
|
} else {
|
||||||
@@ -322,30 +322,6 @@ public class Nicknames implements CommandExecutor, TabCompleter {
|
|||||||
Placeholder.unparsed("nickname", getNick(target.getPlayer())));
|
Placeholder.unparsed("nickname", getNick(target.getPlayer())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleNickOff(Player sender, OfflinePlayer target) {
|
|
||||||
try {
|
|
||||||
if (target.isOnline()) {
|
|
||||||
resetNick(Objects.requireNonNull(target.getPlayer()));
|
|
||||||
}
|
|
||||||
Queries.removePlayerFromDataBase(target.getUniqueId());
|
|
||||||
NickCache.remove(target.getUniqueId());
|
|
||||||
nickCacheUpdate.add(target.getUniqueId());
|
|
||||||
} catch (SQLException e) {
|
|
||||||
ALogger.error("Failed to remove nickname from database", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sender.equals(target)) {
|
|
||||||
sender.sendRichMessage(Config.NICK_RESET_OTHERS,
|
|
||||||
Placeholder.unparsed("player", Objects.requireNonNull(target.getName())));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.isOnline() && target.getPlayer() != null) {
|
|
||||||
target.getPlayer().sendRichMessage(Config.NICK_RESET);
|
|
||||||
}
|
|
||||||
|
|
||||||
NickEvent nickEvent = new NickEvent(sender.getName(), target.getName(), null, NickEvent.NickEventType.RESET);
|
|
||||||
nickEvent.callEvent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String helpMessage(final CommandSender sender, final HelpType... helpTypes) {
|
private String helpMessage(final CommandSender sender, final HelpType... helpTypes) {
|
||||||
|
|||||||
@@ -119,7 +119,8 @@ public class NicknamesEvents implements Listener, PluginMessageListener {
|
|||||||
switch (subChannel) {
|
switch (subChannel) {
|
||||||
case "NickNameRequest":
|
case "NickNameRequest":
|
||||||
ComponentLike component = miniMessage.deserialize(Config.NICK_REQUEST_NEW, Placeholder.parsed("player", name))
|
ComponentLike component = miniMessage.deserialize(Config.NICK_REQUEST_NEW, Placeholder.parsed("player", name))
|
||||||
.clickEvent(ClickEvent.runCommand("/nick review"))
|
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND,
|
||||||
|
"/nick review"))
|
||||||
.hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT,
|
.hoverEvent(HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT,
|
||||||
miniMessage.deserialize("<gold>Click this text to review the request!")));
|
miniMessage.deserialize("<gold>Click this text to review the request!")));
|
||||||
|
|
||||||
|
|||||||
@@ -5,22 +5,24 @@ import com.alttd.chat.config.Config;
|
|||||||
import com.alttd.chat.database.Queries;
|
import com.alttd.chat.database.Queries;
|
||||||
import com.alttd.chat.events.NickEvent;
|
import com.alttd.chat.events.NickEvent;
|
||||||
import com.alttd.chat.objects.Nick;
|
import com.alttd.chat.objects.Nick;
|
||||||
import com.alttd.chat.util.ALogger;
|
|
||||||
import com.alttd.chat.util.Utility;
|
import com.alttd.chat.util.Utility;
|
||||||
import com.alttd.inventory_gui.click.GuiItem;
|
|
||||||
import com.alttd.inventory_gui.gui.InventoryGui;
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.ComponentLike;
|
import net.kyori.adventure.text.ComponentLike;
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
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.resolver.TagResolver;
|
||||||
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
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.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.bukkit.inventory.meta.SkullMeta;
|
import org.bukkit.inventory.meta.SkullMeta;
|
||||||
@@ -29,45 +31,39 @@ import org.bukkit.scheduler.BukkitRunnable;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NicknamesGui implements Listener {
|
public class NicknamesGui implements Listener {
|
||||||
|
|
||||||
public static final String UNKNOWN_PLAYER_NAME = "UNKNOWN PLAYER NAME";
|
private final Inventory inv;
|
||||||
private final int currentPage;
|
private final int currentPage;
|
||||||
private final ChatPlugin plugin = ChatPlugin.getInstance();
|
|
||||||
private final InventoryGui nicknamesGui;
|
|
||||||
|
|
||||||
public NicknamesGui(Player player) {
|
public NicknamesGui() {
|
||||||
nicknamesGui = InventoryGui.builder()
|
// Create a new inventory, with no owner (as this isn't a real inventory)
|
||||||
.plugin(plugin)
|
inv = Bukkit.createInventory(null, 36, Utility.parseMiniMessage("Nicknames GUI").asComponent());
|
||||||
.title(Component.text("Nicknames GUI"))
|
|
||||||
.rows(6)
|
// Put the items into the inventory
|
||||||
.build();
|
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
setItems(currentPage, player);
|
setItems(currentPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setItems(int currentPage, Player player) {
|
public void setItems(int currentPage) {
|
||||||
new BukkitRunnable() {
|
new BukkitRunnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
inv.clear();
|
||||||
NickUtilities.updateCache();
|
NickUtilities.updateCache();
|
||||||
boolean hasNextPage = false;
|
boolean hasNextPage = false;
|
||||||
int i = (currentPage - 1) * 27; //TODO set to 1 or 2 to test
|
int i = (currentPage - 1) * 27; //TODO set to 1 or 2 to test
|
||||||
int limit = i / 27;
|
int limit = i / 27;
|
||||||
MiniMessage miniMessage = MiniMessage.miniMessage();
|
|
||||||
|
|
||||||
for (Nick nick : Nicknames.getInstance().NickCache.values()) {
|
for (Nick nick : Nicknames.getInstance().NickCache.values()) {
|
||||||
if (nick.hasRequest()) {
|
if (nick.hasRequest()) {
|
||||||
if (limit >= i / 27) {
|
if (limit >= i / 27) {
|
||||||
ItemStack playerSkull = createPlayerSkull(nick, Config.NICK_ITEM_LORE);
|
inv.setItem(i % 27, createPlayerSkull(nick, Config.NICK_ITEM_LORE));
|
||||||
nicknamesGui.getRoot().setItem(i % 27, GuiItem.clickable(playerSkull, inventoryClickEvent ->
|
|
||||||
handleInventoryClick(nick, inventoryClickEvent, miniMessage, playerSkull)));
|
|
||||||
ALogger.info("Added nick " + i + " to gui: " + nick.getUuid());
|
|
||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
ALogger.info("Reached end of nicknames gui page");
|
|
||||||
hasNextPage = true;
|
hasNextPage = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -75,137 +71,20 @@ public class NicknamesGui implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentPage != 1) {
|
if (currentPage != 1) {
|
||||||
ItemStack itemStack = createGuiItem(Material.PAPER, "§bPrevious page",
|
inv.setItem(28, createGuiItem(Material.PAPER, "§bPrevious page",
|
||||||
"§aCurrent page: %page%".replace("%page%", String.valueOf(currentPage)),
|
"§aCurrent page: %page%".replace("%page%", String.valueOf(currentPage)),
|
||||||
"§aPrevious page: %previousPage%".replace("%previousPage%", String.valueOf(currentPage - 1)));
|
"§aPrevious page: %previousPage%".replace("%previousPage%", String.valueOf(currentPage - 1))));
|
||||||
GuiItem previousPage = GuiItem.clickable(itemStack, e -> setItems(currentPage - 1, player));
|
|
||||||
nicknamesGui.getRoot().setItem(28, previousPage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasNextPage) {
|
if (hasNextPage) {
|
||||||
ItemStack itemStack = createGuiItem(Material.PAPER, "§bNext page",
|
inv.setItem(36, createGuiItem(Material.PAPER, "§bNext page",
|
||||||
"§aCurrent page: %page%".replace("%page%", String.valueOf(currentPage)),
|
"§aCurrent page: %page%".replace("%page%", String.valueOf(currentPage)),
|
||||||
"§aNext page: §b%nextPage%".replace("%nextPage%", String.valueOf(currentPage + 1)));
|
"§aNext page: §b%nextPage%".replace("%nextPage%", String.valueOf(currentPage + 1))));
|
||||||
GuiItem nextPage = GuiItem.clickable(itemStack, e -> setItems(currentPage + 1, player));
|
|
||||||
nicknamesGui.getRoot().setItem(36, nextPage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nicknamesGui.render(player);
|
|
||||||
}
|
}
|
||||||
}.runTaskAsynchronously(ChatPlugin.getInstance());
|
}.runTaskAsynchronously(ChatPlugin.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleInventoryClick(Nick nick, InventoryClickEvent inventoryClickEvent, MiniMessage miniMessage, ItemStack playerSkull) {
|
|
||||||
final Player playerWhoClicked = (Player) inventoryClickEvent.getWhoClicked();
|
|
||||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(nick.getUuid());
|
|
||||||
Component offlinePlayerName = miniMessage.deserialize(getOfflinePlayerName(offlinePlayer));
|
|
||||||
if (!nick.hasRequest()) {
|
|
||||||
playerWhoClicked.sendRichMessage(Config.NICK_ALREADY_HANDLED,
|
|
||||||
Placeholder.component("targetplayer", offlinePlayerName));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (inventoryClickEvent.isLeftClick()) {
|
|
||||||
handleLeftClickPlayerSkull(nick, inventoryClickEvent, offlinePlayer, playerWhoClicked, offlinePlayerName, playerSkull);
|
|
||||||
} else if (inventoryClickEvent.isRightClick()) {
|
|
||||||
handleRightClickPlayerSkull(nick, inventoryClickEvent, offlinePlayer, playerWhoClicked, offlinePlayerName, playerSkull);
|
|
||||||
}
|
|
||||||
//TODO what do we do no click?
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleRightClickPlayerSkull(Nick nick, InventoryClickEvent inventoryClickEvent, OfflinePlayer offlinePlayer, Player playerWhoClicked, Component offlinePlayerName, ItemStack playerSkull) {
|
|
||||||
Queries.denyNewNickname(nick.getUuid());
|
|
||||||
|
|
||||||
String newNick = nick.getNewNick();
|
|
||||||
|
|
||||||
new BukkitRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
NickEvent nickEvent = new NickEvent(inventoryClickEvent.getWhoClicked().getName(), getOfflinePlayerName(offlinePlayer), newNick, NickEvent.NickEventType.DENIED);
|
|
||||||
nickEvent.callEvent();
|
|
||||||
}
|
|
||||||
}.runTask(ChatPlugin.getInstance());
|
|
||||||
|
|
||||||
playerWhoClicked.sendRichMessage(Config.NICK_DENIED,
|
|
||||||
Placeholder.unparsed("targetplayer", getOfflinePlayerName(offlinePlayer)),
|
|
||||||
Placeholder.component("newnick", Utility.applyColor(nick.getNewNick())),
|
|
||||||
Placeholder.component("oldnick", Utility.applyColor(nick.getCurrentNick() == null ? getOfflinePlayerName(offlinePlayer) : nick.getCurrentNick())));
|
|
||||||
|
|
||||||
if (Nicknames.getInstance().NickCache.containsKey(nick.getUuid())
|
|
||||||
&& Nicknames.getInstance().NickCache.get(nick.getUuid()).getCurrentNick() != null) {
|
|
||||||
nick.setNewNick(null);
|
|
||||||
nick.setRequestedDate(0);
|
|
||||||
Nicknames.getInstance().NickCache.put(nick.getUuid(), nick);
|
|
||||||
} else {
|
|
||||||
Nicknames.getInstance().NickCache.remove(nick.getUuid());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offlinePlayer.isOnline() && offlinePlayer.getPlayer() != null) {
|
|
||||||
Nicknames.getInstance().setNick(offlinePlayer.getPlayer(), nick.getCurrentNick() == null ? getOfflinePlayerName(offlinePlayer) : nick.getCurrentNick());
|
|
||||||
offlinePlayer.getPlayer().sendRichMessage(Config.NICK_NOT_CHANGED);
|
|
||||||
}
|
|
||||||
|
|
||||||
NickUtilities.bungeeMessageHandled(nick.getUuid(), inventoryClickEvent.getWhoClicked().getServer().getPlayer(inventoryClickEvent.getWhoClicked().getName()), "Denied");
|
|
||||||
final ComponentLike messageDenied = MiniMessage.miniMessage().deserialize("<red><name>'s nickname was denied!",
|
|
||||||
Placeholder.unparsed("name", getOfflinePlayerName(offlinePlayer)));
|
|
||||||
ChatPlugin.getInstance().getServer().getOnlinePlayers().stream()
|
|
||||||
.filter(player -> player.hasPermission("chat.command.nick.review"))
|
|
||||||
.forEach(player -> player.sendMessage(messageDenied));
|
|
||||||
|
|
||||||
ItemStack completedNickRequestItem = createCompletedNickRequestItem(offlinePlayerName, playerSkull);
|
|
||||||
inventoryClickEvent.getInventory().setItem(inventoryClickEvent.getSlot(), completedNickRequestItem);
|
|
||||||
nicknamesGui.render(playerWhoClicked);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleLeftClickPlayerSkull(Nick nick, InventoryClickEvent inventoryClickEvent, OfflinePlayer offlinePlayer, Player playerWhoClicked, Component offlinePlayerName, ItemStack playerSkull) {
|
|
||||||
Queries.acceptNewNickname(nick.getUuid(), nick.getNewNick());
|
|
||||||
|
|
||||||
String newNick = nick.getNewNick();
|
|
||||||
|
|
||||||
new BukkitRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
NickEvent nickEvent = new NickEvent(inventoryClickEvent.getWhoClicked().getName(), getOfflinePlayerName(offlinePlayer), newNick, NickEvent.NickEventType.ACCEPTED);
|
|
||||||
nickEvent.callEvent();
|
|
||||||
}
|
|
||||||
}.runTask(ChatPlugin.getInstance());
|
|
||||||
|
|
||||||
playerWhoClicked.sendRichMessage(Config.NICK_ACCEPTED,
|
|
||||||
Placeholder.component("targetplayer", offlinePlayerName),
|
|
||||||
Placeholder.component("newnick", Utility.applyColor(nick.getNewNick())),
|
|
||||||
Placeholder.component("oldnick", nick.getCurrentNick() == null ? offlinePlayerName : Utility.applyColor(nick.getCurrentNick())));
|
|
||||||
|
|
||||||
Player affectedPlayer = offlinePlayer.getPlayer();
|
|
||||||
if (offlinePlayer.isOnline() && affectedPlayer != null) {
|
|
||||||
Nicknames.getInstance().setNick(affectedPlayer, nick.getNewNick());
|
|
||||||
}
|
|
||||||
|
|
||||||
NickUtilities.bungeeMessageHandled(nick.getUuid(), inventoryClickEvent.getWhoClicked().getServer().getPlayer(inventoryClickEvent.getWhoClicked().getName()), "Accepted");
|
|
||||||
|
|
||||||
nick.setCurrentNick(nick.getNewNick());
|
|
||||||
nick.setLastChangedDate(new Date().getTime());
|
|
||||||
nick.setNewNick(null);
|
|
||||||
nick.setRequestedDate(0);
|
|
||||||
|
|
||||||
Nicknames.getInstance().NickCache.put(nick.getUuid(), nick);
|
|
||||||
|
|
||||||
ItemStack completedNickRequestItem = createCompletedNickRequestItem(offlinePlayerName, playerSkull);
|
|
||||||
inventoryClickEvent.getInventory().setItem(inventoryClickEvent.getSlot(), completedNickRequestItem);
|
|
||||||
nicknamesGui.render(playerWhoClicked);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ItemStack createCompletedNickRequestItem(Component offlinePlayerName, ItemStack playerSkull) {
|
|
||||||
ItemStack itemStack = new ItemStack(Material.SKELETON_SKULL);
|
|
||||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
|
||||||
itemMeta.displayName(offlinePlayerName);
|
|
||||||
itemMeta.lore(playerSkull.lore());
|
|
||||||
itemStack.setItemMeta(itemMeta);
|
|
||||||
return itemStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getOfflinePlayerName(OfflinePlayer offlinePlayer) {
|
|
||||||
return offlinePlayer.getName() == null ? UNKNOWN_PLAYER_NAME : offlinePlayer.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemStack createPlayerSkull(Nick nick, List<String> lore) {
|
private ItemStack createPlayerSkull(Nick nick, List<String> lore) {
|
||||||
MiniMessage miniMessage = MiniMessage.miniMessage();
|
MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||||
ItemStack playerHead = new ItemStack(Material.PLAYER_HEAD);
|
ItemStack playerHead = new ItemStack(Material.PLAYER_HEAD);
|
||||||
@@ -215,9 +94,9 @@ public class NicknamesGui implements Listener {
|
|||||||
meta.setOwningPlayer(offlinePlayer);
|
meta.setOwningPlayer(offlinePlayer);
|
||||||
String name = offlinePlayer.getName();
|
String name = offlinePlayer.getName();
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
meta.displayName(miniMessage.deserialize("<red>" + getOfflinePlayerName(offlinePlayer) + "</red>"));
|
meta.displayName(miniMessage.deserialize("UNKNOWN PLAYER NAME"));
|
||||||
} else {
|
} else {
|
||||||
meta.displayName(miniMessage.deserialize(getOfflinePlayerName(offlinePlayer)));
|
meta.displayName(miniMessage.deserialize(offlinePlayer.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TagResolver resolver = TagResolver.resolver(
|
TagResolver resolver = TagResolver.resolver(
|
||||||
@@ -249,6 +128,185 @@ public class NicknamesGui implements Listener {
|
|||||||
|
|
||||||
// You can open the inventory with this
|
// 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
|
public void openInventory(final HumanEntity ent) {//Possibly with a boolean to show if it should get from cache or update cache
|
||||||
nicknamesGui.open(ent);
|
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)) {
|
||||||
|
Component component = clickedItem.getItemMeta().displayName();
|
||||||
|
if (component == null) {
|
||||||
|
throw new IllegalStateException("Nicknames GUI: Item with no display name clicked!");
|
||||||
|
}
|
||||||
|
String serialize = PlainTextComponentSerializer.plainText().serialize(component);
|
||||||
|
if (serialize.equals("Next Page")) {
|
||||||
|
setItems(currentPage + 1);
|
||||||
|
}
|
||||||
|
} else if (clickedItem.getType().equals(Material.PLAYER_HEAD)) {
|
||||||
|
ItemMeta itemMeta = clickedItem.getItemMeta();
|
||||||
|
if (itemMeta == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SkullMeta meta = (SkullMeta) itemMeta;
|
||||||
|
if (meta.hasEnchants()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OfflinePlayer owningPlayer = meta.getOwningPlayer();
|
||||||
|
|
||||||
|
if (owningPlayer == null) {
|
||||||
|
p.sendRichMessage(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);
|
||||||
|
}
|
||||||
|
Component itemDisplayName = itemMeta.displayName();
|
||||||
|
if (itemDisplayName == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nick == null || !nick.hasRequest()) {
|
||||||
|
p.sendRichMessage(Config.NICK_ALREADY_HANDLED,
|
||||||
|
Placeholder.component("targetplayer", itemDisplayName))
|
||||||
|
;
|
||||||
|
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(), itemMeta.getDisplayName(), newNick, NickEvent.NickEventType.ACCEPTED);
|
||||||
|
nickEvent.callEvent();
|
||||||
|
}
|
||||||
|
}.runTask(ChatPlugin.getInstance());
|
||||||
|
|
||||||
|
p.sendRichMessage(Config.NICK_ACCEPTED,
|
||||||
|
Placeholder.component("targetplayer", itemDisplayName),
|
||||||
|
Placeholder.component("newnick", Utility.applyColor(nick.getNewNick())),
|
||||||
|
Placeholder.component("oldnick", Utility.applyColor(nick.getCurrentNick() == null ? itemMeta.getDisplayName() : nick.getCurrentNick())));
|
||||||
|
|
||||||
|
if (owningPlayer.isOnline() && owningPlayer.getPlayer() != null) {
|
||||||
|
Nicknames.getInstance().setNick(owningPlayer.getPlayer(), 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(itemMeta.displayName());
|
||||||
|
itemMeta.lore(clickedItem.lore());
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
e.getInventory().setItem(e.getSlot(), itemStack);
|
||||||
|
p.updateInventory();
|
||||||
|
} else {
|
||||||
|
p.sendRichMessage(Config.NICK_PLAYER_NOT_ONLINE, Placeholder.component("player", itemDisplayName));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (e.isRightClick()) {
|
||||||
|
if (owningPlayer.hasPlayedBefore()) {
|
||||||
|
Queries.denyNewNickname(uniqueId);
|
||||||
|
|
||||||
|
String newNick = nick.getNewNick();
|
||||||
|
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
NickEvent nickEvent = new NickEvent(e.getWhoClicked().getName(), itemMeta.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().sendRichMessage(Config.NICK_NOT_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
NickUtilities.bungeeMessageHandled(uniqueId, e.getWhoClicked().getServer().getPlayer(e.getWhoClicked().getName()), "Denied");
|
||||||
|
final ComponentLike 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(itemDisplayName);
|
||||||
|
itemMeta.lore(clickedItem.lore());
|
||||||
|
itemStack.setItemMeta(itemMeta);
|
||||||
|
e.getInventory().setItem(e.getSlot(), itemStack);
|
||||||
|
p.updateInventory();
|
||||||
|
} else {
|
||||||
|
if (itemDisplayName == null) {
|
||||||
|
p.sendRichMessage(Config.NICK_PLAYER_NOT_ONLINE, Placeholder.parsed("player", "UNKNOWN PLAYER NAME"));
|
||||||
|
} else {
|
||||||
|
p.sendRichMessage(Config.NICK_PLAYER_NOT_ONLINE, Placeholder.component("player", itemDisplayName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright © 2015 the original authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -15,8 +15,6 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
#
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
@@ -57,7 +55,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -86,7 +84,7 @@ done
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
@@ -114,6 +112,7 @@ case "$( uname )" in #(
|
|||||||
NONSTOP* ) nonstop=true ;;
|
NONSTOP* ) nonstop=true ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
@@ -171,6 +170,7 @@ fi
|
|||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
if "$cygwin" || "$msys" ; then
|
if "$cygwin" || "$msys" ; then
|
||||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
@@ -203,14 +203,15 @@ fi
|
|||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Collect all arguments for the java command:
|
# Collect all arguments for the java command:
|
||||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
# and any embedded shellness will be escaped.
|
# 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
|
# * 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.
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
set -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
# Stop when "xargs" is not available.
|
# Stop when "xargs" is not available.
|
||||||
|
|||||||
Vendored
+12
-13
@@ -13,8 +13,6 @@
|
|||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
@rem SPDX-License-Identifier: Apache-2.0
|
|
||||||
@rem
|
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@@ -45,11 +43,11 @@ set JAVA_EXE=java.exe
|
|||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@@ -59,21 +57,22 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
@rem Execute Gradle
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
plugins {
|
||||||
|
`maven-publish`
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api(project(":api"))
|
||||||
|
compileOnly("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT")
|
||||||
|
|
||||||
|
api("com.fasterxml.jackson.core:jackson-databind:2.17.2")
|
||||||
|
api("com.fasterxml.jackson.core:jackson-core:2.17.2")
|
||||||
|
api("com.fasterxml.jackson.core:jackson-annotations:2.17.2")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<JavaCompile>().configureEach {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
options.release.set(21)
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.alttd.matrix;
|
||||||
|
|
||||||
|
public record MatrixConfig(
|
||||||
|
String homeserver, // e.g. "http://127.0.0.1:8008"
|
||||||
|
String asToken, // from as registration yaml
|
||||||
|
String hsToken, // from as registration yaml
|
||||||
|
String domain, // "matrix.alttd.com"
|
||||||
|
String userPrefix, // "mc_"
|
||||||
|
String bindHost, // "127.0.0.1"
|
||||||
|
int bindPort // 9000
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.alttd.matrix;
|
||||||
|
|
||||||
|
import com.alttd.matrix.app_service.MatrixAppServiceHttpServer;
|
||||||
|
import com.alttd.matrix.client.HttpMatrixClient;
|
||||||
|
import com.alttd.matrix.interfaces.MatrixAppServiceServer;
|
||||||
|
import com.alttd.matrix.interfaces.MatrixClient;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
public final class MatrixRuntime {
|
||||||
|
|
||||||
|
private MatrixRuntime() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MatrixAppServiceServer startAppService(MatrixConfig cfg) throws IOException {
|
||||||
|
var server = new MatrixAppServiceHttpServer(
|
||||||
|
new InetSocketAddress(cfg.bindHost(), cfg.bindPort()),
|
||||||
|
cfg.hsToken()
|
||||||
|
);
|
||||||
|
server.start();
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MatrixClient createClient(MatrixConfig cfg) {
|
||||||
|
return new HttpMatrixClient(cfg.homeserver(), cfg.asToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
package com.alttd.matrix.app_service;
|
||||||
|
|
||||||
|
import com.alttd.matrix.interfaces.MatrixAppServiceServer;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import com.sun.net.httpserver.HttpServer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public final class MatrixAppServiceHttpServer implements MatrixAppServiceServer {
|
||||||
|
|
||||||
|
private final HttpServer server;
|
||||||
|
private final String hsToken;
|
||||||
|
private final ObjectMapper om = new ObjectMapper();
|
||||||
|
|
||||||
|
private volatile Consumer<TransactionEvent> txListener;
|
||||||
|
|
||||||
|
public MatrixAppServiceHttpServer(InetSocketAddress bind, String hsToken) throws IOException {
|
||||||
|
this.server = HttpServer.create(bind, 0);
|
||||||
|
this.hsToken = hsToken;
|
||||||
|
|
||||||
|
server.createContext("/_matrix/app/v1/transactions", this::handleTransactions);
|
||||||
|
server.createContext("/_matrix/app/v1/users", this::handleUsers);
|
||||||
|
|
||||||
|
server.setExecutor(Executors.newCachedThreadPool(r -> {
|
||||||
|
Thread t = new Thread(r, "matrix-as-http");
|
||||||
|
t.setDaemon(true);
|
||||||
|
return t;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTransactionListener(Consumer<TransactionEvent> listener) {
|
||||||
|
this.txListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
server.stop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleUsers(HttpExchange ex) throws IOException {
|
||||||
|
if (!"GET".equals(ex.getRequestMethod())) {
|
||||||
|
send(ex, 405, "{}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!validHsToken(ex)) {
|
||||||
|
send(ex, 401, "{}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Synapse asks "does this user exist?" -> for AS, answer 200 so Synapse will proceed.
|
||||||
|
// You can optionally restrict to your namespace by inspecting the path.
|
||||||
|
send(ex, 200, "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleTransactions(HttpExchange ex) throws IOException {
|
||||||
|
if (!"PUT".equals(ex.getRequestMethod())) {
|
||||||
|
send(ex, 405, "{}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!validHsToken(ex)) {
|
||||||
|
send(ex, 401, "{}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode root;
|
||||||
|
try (InputStream in = ex.getRequestBody()) {
|
||||||
|
root = om.readTree(in);
|
||||||
|
} catch (Exception e) {
|
||||||
|
send(ex, 400, "{}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Consumer<TransactionEvent> listener = txListener;
|
||||||
|
if (listener != null) {
|
||||||
|
JsonNode events = root.path("events");
|
||||||
|
if (events.isArray()) {
|
||||||
|
for (Iterator<JsonNode> it = events.elements(); it.hasNext(); ) {
|
||||||
|
JsonNode ev = it.next();
|
||||||
|
|
||||||
|
// only handle m.room.message text
|
||||||
|
if (!"m.room.message".equals(ev.path("type").asText())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!"m.text".equals(ev.path("content").path("msgtype").asText())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String roomId = ev.path("room_id").asText(null);
|
||||||
|
String sender = ev.path("sender").asText(null);
|
||||||
|
String eventId = ev.path("event_id").asText(null);
|
||||||
|
String body = ev.path("content").path("body").asText(null);
|
||||||
|
|
||||||
|
if (roomId != null && body != null) {
|
||||||
|
listener.accept(new TransactionEvent(roomId, sender, body, eventId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
send(ex, 200, "{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validHsToken(HttpExchange ex) {
|
||||||
|
String q = ex.getRequestURI().getRawQuery();
|
||||||
|
if (q == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Map<String, String> params = parseQuery(q);
|
||||||
|
String token = params.get("access_token");
|
||||||
|
return token != null && token.equals(hsToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> parseQuery(String raw) {
|
||||||
|
var map = new java.util.HashMap<String, String>();
|
||||||
|
for (String part : raw.split("&")) {
|
||||||
|
int i = part.indexOf('=');
|
||||||
|
if (i <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String k = urlDecode(part.substring(0, i));
|
||||||
|
String v = urlDecode(part.substring(i + 1));
|
||||||
|
map.put(k, v);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String urlDecode(String s) {
|
||||||
|
return URLDecoder.decode(s, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void send(HttpExchange ex, int code, String body) throws IOException {
|
||||||
|
byte[] b = body.getBytes(StandardCharsets.UTF_8);
|
||||||
|
ex.getResponseHeaders().set("Content-Type", "application/json");
|
||||||
|
ex.sendResponseHeaders(code, b.length);
|
||||||
|
ex.getResponseBody().write(b);
|
||||||
|
ex.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package com.alttd.matrix.bridge;
|
||||||
|
|
||||||
|
import com.alttd.matrix.MatrixConfig;
|
||||||
|
import com.alttd.matrix.interfaces.MatrixAppServiceServer;
|
||||||
|
import com.alttd.matrix.interfaces.MatrixBridge;
|
||||||
|
import com.alttd.matrix.interfaces.MatrixClient;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
public final class DefaultMatrixBridge implements MatrixBridge {
|
||||||
|
|
||||||
|
private final MatrixClient client;
|
||||||
|
private final MatrixConfig cfg;
|
||||||
|
private final Executor io = Executors.newSingleThreadExecutor(r -> {
|
||||||
|
Thread t = new Thread(r, "matrix-io");
|
||||||
|
t.setDaemon(true);
|
||||||
|
return t;
|
||||||
|
});
|
||||||
|
|
||||||
|
private volatile InboundHandler inbound;
|
||||||
|
private volatile RoomResolver rooms;
|
||||||
|
|
||||||
|
public DefaultMatrixBridge(MatrixConfig cfg, MatrixAppServiceServer asServer, MatrixClient client) {
|
||||||
|
this.cfg = cfg;
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
asServer.setTransactionListener(evt -> {
|
||||||
|
InboundHandler h = inbound;
|
||||||
|
RoomResolver rr = rooms;
|
||||||
|
if (h == null || rr == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// drop our own puppets to prevent loops
|
||||||
|
if (evt.senderMxid() != null && evt.senderMxid().startsWith("@" + cfg.userPrefix())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
h.onMatrixChat(evt.roomId(), evt.senderMxid(), evt.body());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInboundHandler(InboundHandler handler) {
|
||||||
|
this.inbound = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRoomResolver(RoomResolver resolver) {
|
||||||
|
this.rooms = resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChat(UUID playerUuid, String mcUsername, String serverName, String message) {
|
||||||
|
RoomResolver rr = rooms;
|
||||||
|
if (rr == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String roomId = rr.roomIdForServer(serverName);
|
||||||
|
if (roomId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String mxid = "@" + cfg.userPrefix() + playerUuid + ":" + cfg.domain();
|
||||||
|
|
||||||
|
io.execute(() -> {
|
||||||
|
client.ensureUser(mxid);
|
||||||
|
client.setDisplayName(mxid, mcUsername);
|
||||||
|
client.ensureJoined(mxid, roomId);
|
||||||
|
client.sendText(mxid, roomId, message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
package com.alttd.matrix.client;
|
||||||
|
|
||||||
|
import com.alttd.matrix.interfaces.MatrixClient;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public final class HttpMatrixClient implements MatrixClient {
|
||||||
|
|
||||||
|
private final HttpClient http = HttpClient.newBuilder()
|
||||||
|
.connectTimeout(Duration.ofSeconds(5))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private final ObjectMapper om = new ObjectMapper();
|
||||||
|
|
||||||
|
private final String hs; // e.g. http://127.0.0.1:8008
|
||||||
|
private final String asToken; // AS access token
|
||||||
|
|
||||||
|
public HttpMatrixClient(String homeserver, String asToken) {
|
||||||
|
this.hs = homeserver.endsWith("/") ? homeserver.substring(0, homeserver.length() - 1) : homeserver;
|
||||||
|
this.asToken = asToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ensureUser(String mxid) {
|
||||||
|
String localpart = localpart(mxid);
|
||||||
|
|
||||||
|
String url = hs + "/_matrix/client/v3/register"
|
||||||
|
+ "?access_token=" + enc(asToken);
|
||||||
|
|
||||||
|
String body = "{\"type\":\"m.login.application_service\",\"username\":\"" + json(localpart) + "\"}";
|
||||||
|
|
||||||
|
HttpRequest req = HttpRequest.newBuilder(URI.create(url))
|
||||||
|
.timeout(Duration.ofSeconds(10))
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.POST(HttpRequest.BodyPublishers.ofString(body))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendIgnoreConflict(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDisplayName(String mxid, String displayName) {
|
||||||
|
String url = hs + "/_matrix/client/v3/profile/" + encPath(mxid) + "/displayname"
|
||||||
|
+ "?access_token=" + enc(asToken)
|
||||||
|
+ "&user_id=" + enc(mxid);
|
||||||
|
|
||||||
|
String body = "{\"displayname\":\"" + json(displayName) + "\"}";
|
||||||
|
|
||||||
|
HttpRequest req = HttpRequest.newBuilder(URI.create(url))
|
||||||
|
.timeout(Duration.ofSeconds(10))
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.PUT(HttpRequest.BodyPublishers.ofString(body))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendOkOrIgnore(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ensureJoined(String mxid, String roomId) {
|
||||||
|
String url = hs + "/_matrix/client/v3/rooms/" + encPath(roomId) + "/join"
|
||||||
|
+ "?access_token=" + enc(asToken)
|
||||||
|
+ "&user_id=" + enc(mxid);
|
||||||
|
|
||||||
|
HttpRequest req = HttpRequest.newBuilder(URI.create(url))
|
||||||
|
.timeout(Duration.ofSeconds(10))
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.POST(HttpRequest.BodyPublishers.ofString("{}"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendOkOrIgnore(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendText(String mxid, String roomId, String bodyText) {
|
||||||
|
String txnId = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
String url = hs + "/_matrix/client/v3/rooms/" + encPath(roomId) + "/send/m.room.message/" + encPath(txnId)
|
||||||
|
+ "?access_token=" + enc(asToken)
|
||||||
|
+ "&user_id=" + enc(mxid);
|
||||||
|
|
||||||
|
String body = "{\"msgtype\":\"m.text\",\"body\":\"" + json(bodyText) + "\"}";
|
||||||
|
|
||||||
|
HttpRequest req = HttpRequest.newBuilder(URI.create(url))
|
||||||
|
.timeout(Duration.ofSeconds(10))
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.PUT(HttpRequest.BodyPublishers.ofString(body))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sendOkOrIgnore(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendIgnoreConflict(HttpRequest req) {
|
||||||
|
try {
|
||||||
|
HttpResponse<String> res = http.send(req, HttpResponse.BodyHandlers.ofString());
|
||||||
|
int c = res.statusCode();
|
||||||
|
if (c == 200) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (c == 400 && res.body() != null && res.body().contains("M_USER_IN_USE")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (c == 401 || c == 403) {
|
||||||
|
throw new RuntimeException("Matrix auth failed: " + c + " " + res.body());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendOkOrIgnore(HttpRequest req) {
|
||||||
|
try {
|
||||||
|
HttpResponse<String> res = http.send(req, HttpResponse.BodyHandlers.ofString());
|
||||||
|
int c = res.statusCode();
|
||||||
|
if (c >= 200 && c < 300) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (c == 401 || c == 403) {
|
||||||
|
throw new RuntimeException("Matrix auth failed: " + c + " " + res.body());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String localpart(String mxid) {
|
||||||
|
// "@localpart:domain"
|
||||||
|
int at = mxid.indexOf('@');
|
||||||
|
int colon = mxid.indexOf(':');
|
||||||
|
if (at != 0 || colon < 0) {
|
||||||
|
throw new IllegalArgumentException("bad mxid: " + mxid);
|
||||||
|
}
|
||||||
|
return mxid.substring(1, colon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String enc(String s) {
|
||||||
|
return URLEncoder.encode(s, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String encPath(String s) {
|
||||||
|
// safe enough for matrix path segments
|
||||||
|
return URLEncoder.encode(s, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String json(String s) {
|
||||||
|
return s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.alttd.matrix.interfaces;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public interface MatrixAppServiceServer extends Closeable {
|
||||||
|
void setTransactionListener(Consumer<TransactionEvent> listener);
|
||||||
|
|
||||||
|
record TransactionEvent(String roomId, String senderMxid, String body, String eventId) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.alttd.matrix.interfaces;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface MatrixBridge {
|
||||||
|
void setInboundHandler(InboundHandler handler);
|
||||||
|
|
||||||
|
void setRoomResolver(RoomResolver resolver);
|
||||||
|
|
||||||
|
void sendChat(UUID playerUuid, String mcUsername, String serverName, String message);
|
||||||
|
|
||||||
|
interface InboundHandler {
|
||||||
|
void onMatrixChat(String roomId, String senderMxid, String body);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RoomResolver {
|
||||||
|
String roomIdForServer(String serverName);
|
||||||
|
|
||||||
|
String serverForRoomId(String roomId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.alttd.matrix.interfaces;
|
||||||
|
|
||||||
|
public interface MatrixClient {
|
||||||
|
void ensureUser(String mxid);
|
||||||
|
|
||||||
|
void setDisplayName(String mxid, String displayName);
|
||||||
|
|
||||||
|
void ensureJoined(String mxid, String roomId);
|
||||||
|
|
||||||
|
void sendText(String mxid, String roomId, String body);
|
||||||
|
}
|
||||||
+10
-17
@@ -3,35 +3,28 @@ rootProject.name = "Chat"
|
|||||||
include(":api")
|
include(":api")
|
||||||
include(":galaxy")
|
include(":galaxy")
|
||||||
include(":velocity")
|
include(":velocity")
|
||||||
|
include(":matrix")
|
||||||
|
|
||||||
val nexusUser = providers.gradleProperty("alttdSnapshotUsername").get()
|
val nexusUser = providers.gradleProperty("alttdSnapshotUsername").get()
|
||||||
val nexusPass = providers.gradleProperty("alttdSnapshotPassword").get()
|
val nexusPass = providers.gradleProperty("alttdSnapshotPassword").get()
|
||||||
|
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
|
||||||
mavenCentral()
|
|
||||||
maven("https://repo.alttd.com/snapshots") // Altitude - Galaxy
|
|
||||||
maven("https://oss.sonatype.org/content/groups/public/") // Adventure
|
|
||||||
maven("https://oss.sonatype.org/content/repositories/snapshots/") // Minimessage
|
|
||||||
maven("https://repo.papermc.io/repository/maven-public/")
|
|
||||||
maven("https://repo.spongepowered.org/maven") // Configurate
|
|
||||||
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") // Papi
|
|
||||||
maven("https://jitpack.io")
|
|
||||||
maven {
|
maven {
|
||||||
|
name = "nexus"
|
||||||
url = uri("https://repo.alttd.com/repository/alttd-snapshot/")
|
url = uri("https://repo.alttd.com/repository/alttd-snapshot/")
|
||||||
credentials {
|
credentials {
|
||||||
username = nexusUser
|
username = nexusUser
|
||||||
password = nexusPass
|
password = nexusPass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maven {
|
// mavenLocal()
|
||||||
url = uri("https://repo.alttd.com/repository/alttd/")
|
mavenCentral()
|
||||||
credentials {
|
maven("https://oss.sonatype.org/content/groups/public/") // Adventure
|
||||||
username = nexusUser
|
maven("https://oss.sonatype.org/content/repositories/snapshots/") // Minimessage
|
||||||
password = nexusPass
|
maven("https://repo.spongepowered.org/maven") // Configurate
|
||||||
}
|
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") // Papi
|
||||||
}
|
maven("https://jitpack.io")
|
||||||
}
|
}
|
||||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||||
}
|
}
|
||||||
@@ -42,4 +35,4 @@ pluginManagement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
include("web-api")
|
include("matrix")
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
plugins {
|
plugins {
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
id("com.gradleup.shadow")
|
id("io.github.goooler.shadow")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":api")) // API
|
implementation(project(":api")) // API
|
||||||
compileOnly("org.projectlombok:lombok:1.18.46")
|
compileOnly("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT")
|
||||||
annotationProcessor("org.projectlombok:lombok:1.18.46")
|
annotationProcessor("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT")
|
||||||
compileOnly("com.velocitypowered:velocity-api:3.5.0-SNAPSHOT")
|
|
||||||
annotationProcessor("com.velocitypowered:velocity-api:3.5.0-SNAPSHOT")
|
|
||||||
implementation("mysql:mysql-connector-java:8.0.33") // mysql
|
implementation("mysql:mysql-connector-java:8.0.33") // mysql
|
||||||
implementation("org.spongepowered", "configurate-yaml", "4.2.0")
|
implementation("org.spongepowered", "configurate-yaml", "4.2.0")
|
||||||
compileOnly("net.kyori:adventure-text-minimessage:4.23.0")
|
compileOnly("net.kyori:adventure-text-minimessage:4.23.0")
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ import com.alttd.chat.managers.PartyManager;
|
|||||||
import com.alttd.chat.objects.ChatUser;
|
import com.alttd.chat.objects.ChatUser;
|
||||||
import com.alttd.chat.objects.chat_log.ChatLogHandler;
|
import com.alttd.chat.objects.chat_log.ChatLogHandler;
|
||||||
import com.alttd.chat.util.ALogger;
|
import com.alttd.chat.util.ALogger;
|
||||||
|
import com.alttd.matrix.MatrixConfig;
|
||||||
|
import com.alttd.matrix.MatrixRuntime;
|
||||||
|
import com.alttd.matrix.bridge.DefaultMatrixBridge;
|
||||||
|
import com.alttd.matrix.interfaces.MatrixAppServiceServer;
|
||||||
|
import com.alttd.matrix.interfaces.MatrixBridge;
|
||||||
|
import com.alttd.matrix.interfaces.MatrixClient;
|
||||||
import com.alttd.velocitychat.commands.*;
|
import com.alttd.velocitychat.commands.*;
|
||||||
import com.alttd.velocitychat.handlers.ChatHandler;
|
import com.alttd.velocitychat.handlers.ChatHandler;
|
||||||
import com.alttd.velocitychat.handlers.ServerHandler;
|
import com.alttd.velocitychat.handlers.ServerHandler;
|
||||||
@@ -16,9 +22,13 @@ import com.alttd.velocitychat.listeners.ChatListener;
|
|||||||
import com.alttd.velocitychat.listeners.LiteBansListener;
|
import com.alttd.velocitychat.listeners.LiteBansListener;
|
||||||
import com.alttd.velocitychat.listeners.PluginMessageListener;
|
import com.alttd.velocitychat.listeners.PluginMessageListener;
|
||||||
import com.alttd.velocitychat.listeners.ProxyPlayerListener;
|
import com.alttd.velocitychat.listeners.ProxyPlayerListener;
|
||||||
|
import com.alttd.velocitychat.matrix.MatrixRoomMap;
|
||||||
|
import com.alttd.velocitychat.matrix.VelocityMatrixInbound;
|
||||||
|
import com.alttd.velocitychat.matrix.VelocityMatrixOutbound;
|
||||||
import com.google.common.io.ByteArrayDataOutput;
|
import com.google.common.io.ByteArrayDataOutput;
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
import com.velocitypowered.api.event.EventManager;
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||||
import com.velocitypowered.api.plugin.Dependency;
|
import com.velocitypowered.api.plugin.Dependency;
|
||||||
@@ -43,7 +53,9 @@ public class VelocityChat {
|
|||||||
private final ProxyServer server;
|
private final ProxyServer server;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
private final Path dataDirectory;
|
private final Path dataDirectory;
|
||||||
|
private final EventManager eventManager;
|
||||||
|
|
||||||
|
private MatrixAppServiceServer matrixAsServer;
|
||||||
private ChatAPI chatAPI;
|
private ChatAPI chatAPI;
|
||||||
private ChatHandler chatHandler;
|
private ChatHandler chatHandler;
|
||||||
private ServerHandler serverHandler;
|
private ServerHandler serverHandler;
|
||||||
@@ -51,11 +63,12 @@ public class VelocityChat {
|
|||||||
private ChannelIdentifier channelIdentifier;
|
private ChannelIdentifier channelIdentifier;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public VelocityChat(ProxyServer proxyServer, Logger proxyLogger, @DataDirectory Path proxydataDirectory) {
|
public VelocityChat(ProxyServer proxyServer, Logger proxyLogger, @DataDirectory Path proxydataDirectory, EventManager eventManager) {
|
||||||
plugin = this;
|
plugin = this;
|
||||||
server = proxyServer;
|
server = proxyServer;
|
||||||
logger = proxyLogger;
|
logger = proxyLogger;
|
||||||
dataDirectory = proxydataDirectory;
|
dataDirectory = proxydataDirectory;
|
||||||
|
this.eventManager = eventManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -67,8 +80,7 @@ public class VelocityChat {
|
|||||||
PartyManager.initialize(); // load the parties from the db and add the previously loaded users to them
|
PartyManager.initialize(); // load the parties from the db and add the previously loaded users to them
|
||||||
|
|
||||||
serverHandler = new ServerHandler();
|
serverHandler = new ServerHandler();
|
||||||
ChatLogHandler chatLogHandler = new ChatLogHandler(true);
|
chatHandler = new ChatHandler();
|
||||||
chatHandler = new ChatHandler(chatLogHandler);
|
|
||||||
server.getEventManager().register(this, new ChatListener());
|
server.getEventManager().register(this, new ChatListener());
|
||||||
server.getEventManager().register(this, new ProxyPlayerListener());
|
server.getEventManager().register(this, new ProxyPlayerListener());
|
||||||
new LiteBansListener().init(); // init the litebans api listeners
|
new LiteBansListener().init(); // init the litebans api listeners
|
||||||
@@ -81,6 +93,7 @@ public class VelocityChat {
|
|||||||
ChatUser console = new ChatUser(Config.CONSOLEUUID, -1, null);
|
ChatUser console = new ChatUser(Config.CONSOLEUUID, -1, null);
|
||||||
console.setDisplayName(Config.CONSOLENAME);
|
console.setDisplayName(Config.CONSOLENAME);
|
||||||
ChatUserManager.addUser(console);
|
ChatUserManager.addUser(console);
|
||||||
|
initMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reloadConfig() {
|
public void reloadConfig() {
|
||||||
@@ -90,11 +103,43 @@ public class VelocityChat {
|
|||||||
ByteArrayDataOutput buf = ByteStreams.newDataOutput();
|
ByteArrayDataOutput buf = ByteStreams.newDataOutput();
|
||||||
buf.writeUTF("reloadconfig");
|
buf.writeUTF("reloadconfig");
|
||||||
ALogger.info("Reloaded ChatPlugin proxy config.");
|
ALogger.info("Reloaded ChatPlugin proxy config.");
|
||||||
getProxy().getAllServers()
|
getProxy().getAllServers().stream().forEach(registeredServer -> registeredServer.sendPluginMessage(getChannelIdentifier(), buf.toByteArray()));
|
||||||
.stream()
|
}
|
||||||
.forEach(registeredServer -> registeredServer.sendPluginMessage(getChannelIdentifier(),
|
|
||||||
buf.toByteArray()
|
//TODO call initMatrix
|
||||||
));
|
private void initMatrix() {
|
||||||
|
MatrixConfig cfg = new MatrixConfig(
|
||||||
|
Config.MATRIX_SERVER,
|
||||||
|
Config.MATRIX_AS_TOKEN,
|
||||||
|
Config.MATRIX_HS_TOKEN,
|
||||||
|
"matrix.alttd.com",
|
||||||
|
"mc_",
|
||||||
|
"127.0.0.1",
|
||||||
|
9000
|
||||||
|
);
|
||||||
|
|
||||||
|
MatrixAppServiceServer asServer;
|
||||||
|
try {
|
||||||
|
asServer = MatrixRuntime.startAppService(cfg);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to start Matrix AppService server", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MatrixClient client = MatrixRuntime.createClient(cfg);
|
||||||
|
|
||||||
|
initMatrix(cfg, asServer, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initMatrix(MatrixConfig matrixConfig, MatrixAppServiceServer asServer, MatrixClient client) {
|
||||||
|
MatrixRoomMap roomMap = new MatrixRoomMap();
|
||||||
|
roomMap.put("bayou", "!bayou:matrix.alttd.com");
|
||||||
|
|
||||||
|
MatrixBridge matrix = new DefaultMatrixBridge(matrixConfig, asServer, client);
|
||||||
|
matrix.setRoomResolver(roomMap);
|
||||||
|
matrix.setInboundHandler(new VelocityMatrixInbound(server, roomMap));
|
||||||
|
|
||||||
|
eventManager.register(this, new VelocityMatrixOutbound(matrix));
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getDataDirectory() {
|
public File getDataDirectory() {
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import com.alttd.chat.managers.ChatUserManager;
|
|||||||
import com.alttd.chat.managers.PartyManager;
|
import com.alttd.chat.managers.PartyManager;
|
||||||
import com.alttd.chat.managers.RegexManager;
|
import com.alttd.chat.managers.RegexManager;
|
||||||
import com.alttd.chat.objects.*;
|
import com.alttd.chat.objects.*;
|
||||||
import com.alttd.chat.objects.chat_log.ChatLogHandler;
|
|
||||||
import com.alttd.chat.objects.chat_log.ChatLogType;
|
|
||||||
import com.alttd.chat.util.ALogger;
|
import com.alttd.chat.util.ALogger;
|
||||||
import com.alttd.chat.util.Utility;
|
import com.alttd.chat.util.Utility;
|
||||||
import com.alttd.velocitychat.VelocityChat;
|
import com.alttd.velocitychat.VelocityChat;
|
||||||
@@ -34,12 +32,6 @@ import java.util.UUID;
|
|||||||
|
|
||||||
public class ChatHandler {
|
public class ChatHandler {
|
||||||
|
|
||||||
private final ChatLogHandler chatLogHandler;
|
|
||||||
|
|
||||||
public ChatHandler(ChatLogHandler chatLogHandler) {
|
|
||||||
this.chatLogHandler = chatLogHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void privateMessage(String sender, String target, String message) {
|
public void privateMessage(String sender, String target, String message) {
|
||||||
UUID uuid = UUID.fromString(sender);
|
UUID uuid = UUID.fromString(sender);
|
||||||
ChatUser senderUser = ChatUserManager.getChatUser(uuid);
|
ChatUser senderUser = ChatUserManager.getChatUser(uuid);
|
||||||
@@ -62,23 +54,15 @@ public class ChatHandler {
|
|||||||
Placeholder.component("receiver", targetUser.getDisplayName()),
|
Placeholder.component("receiver", targetUser.getDisplayName()),
|
||||||
Placeholder.unparsed("receivername", player2.getUsername()),
|
Placeholder.unparsed("receivername", player2.getUsername()),
|
||||||
Placeholder.component("message", GsonComponentSerializer.gson().deserialize(message)),
|
Placeholder.component("message", GsonComponentSerializer.gson().deserialize(message)),
|
||||||
Placeholder.unparsed("server",
|
Placeholder.unparsed("server", player.getCurrentServer().isPresent() ? player.getCurrentServer().get().getServerInfo().getName() : "Altitude"));
|
||||||
player.getCurrentServer().isPresent() ? player.getCurrentServer()
|
|
||||||
.get()
|
|
||||||
.getServerInfo()
|
|
||||||
.getName() : "Altitude"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
ServerConnection serverConnection;
|
ServerConnection serverConnection;
|
||||||
//Log handled on receiving server since it is only received on one server and that's where the ignore check happens
|
|
||||||
if (player.getCurrentServer().isPresent() && player2.getCurrentServer().isPresent()) {
|
if (player.getCurrentServer().isPresent() && player2.getCurrentServer().isPresent()) {
|
||||||
// redirect to the sender
|
// redirect to the sender
|
||||||
serverConnection = player.getCurrentServer().get();
|
serverConnection = player.getCurrentServer().get();
|
||||||
Component component = Utility.parseMiniMessage(Config.MESSAGESENDER
|
Component component = Utility.parseMiniMessage(Config.MESSAGESENDER
|
||||||
.replaceAll("<sendername>", player.getUsername())
|
.replaceAll("<sendername>", player.getUsername())
|
||||||
.replaceAll("<receivername>", player2.getUsername()), Placeholders
|
.replaceAll("<receivername>", player2.getUsername()), Placeholders).asComponent();
|
||||||
).asComponent();
|
|
||||||
ByteArrayDataOutput buf = ByteStreams.newDataOutput();
|
ByteArrayDataOutput buf = ByteStreams.newDataOutput();
|
||||||
buf.writeUTF("privatemessageout");
|
buf.writeUTF("privatemessageout");
|
||||||
buf.writeUTF(player.getUniqueId().toString());
|
buf.writeUTF(player.getUniqueId().toString());
|
||||||
@@ -91,8 +75,7 @@ public class ChatHandler {
|
|||||||
serverConnection = player2.getCurrentServer().get();
|
serverConnection = player2.getCurrentServer().get();
|
||||||
component = Utility.parseMiniMessage(Config.MESSAGERECIEVER
|
component = Utility.parseMiniMessage(Config.MESSAGERECIEVER
|
||||||
.replaceAll("<sendername>", player.getUsername())
|
.replaceAll("<sendername>", player.getUsername())
|
||||||
.replaceAll("<receivername>", player2.getUsername()), Placeholders
|
.replaceAll("<receivername>", player2.getUsername()), Placeholders).asComponent();
|
||||||
).asComponent();
|
|
||||||
buf = ByteStreams.newDataOutput();
|
buf = ByteStreams.newDataOutput();
|
||||||
buf.writeUTF("privatemessagein");
|
buf.writeUTF("privatemessagein");
|
||||||
buf.writeUTF(player2.getUniqueId().toString());
|
buf.writeUTF(player2.getUniqueId().toString());
|
||||||
@@ -151,7 +134,7 @@ public class ChatHandler {
|
|||||||
}
|
}
|
||||||
ComponentLike senderName = user.getDisplayName();
|
ComponentLike senderName = user.getDisplayName();
|
||||||
|
|
||||||
TagResolver placeholders = TagResolver.resolver(
|
TagResolver Placeholders = TagResolver.resolver(
|
||||||
Placeholder.component("sender", senderName),
|
Placeholder.component("sender", senderName),
|
||||||
Placeholder.component("sendername", senderName),
|
Placeholder.component("sendername", senderName),
|
||||||
Placeholder.unparsed("partyname", party.getPartyName()),
|
Placeholder.unparsed("partyname", party.getPartyName()),
|
||||||
@@ -159,7 +142,7 @@ public class ChatHandler {
|
|||||||
Placeholder.unparsed("server", serverConnection.getServer().getServerInfo().getName())
|
Placeholder.unparsed("server", serverConnection.getServer().getServerInfo().getName())
|
||||||
);
|
);
|
||||||
|
|
||||||
Component partyMessage = Utility.parseMiniMessage(Config.PARTY_FORMAT, placeholders).asComponent()
|
Component partyMessage = Utility.parseMiniMessage(Config.PARTY_FORMAT, Placeholders).asComponent()
|
||||||
.replaceText(TextReplacementConfig.builder().once().matchLiteral("[i]").replacement(item).build());
|
.replaceText(TextReplacementConfig.builder().once().matchLiteral("[i]").replacement(item).build());
|
||||||
|
|
||||||
ModifiableString modifiableString = new ModifiableString(partyMessage);
|
ModifiableString modifiableString = new ModifiableString(partyMessage);
|
||||||
@@ -172,17 +155,7 @@ public class ChatHandler {
|
|||||||
|
|
||||||
sendPartyMessage(party, partyMessage, user.getIgnoredBy());
|
sendPartyMessage(party, partyMessage, user.getIgnoredBy());
|
||||||
|
|
||||||
chatLogHandler.addChatLog(uuid,
|
ComponentLike spyMessage = Utility.parseMiniMessage(Config.PARTY_SPY, Placeholders);
|
||||||
serverConnection.getServer().getServerInfo().getName(),
|
|
||||||
PlainTextComponentSerializer.plainText().serialize(partyMessage),
|
|
||||||
ChatLogType.PARTY,
|
|
||||||
String.valueOf(party.getPartyId()),
|
|
||||||
null,
|
|
||||||
partyMessage,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
ComponentLike spyMessage = Utility.parseMiniMessage(Config.PARTY_SPY, placeholders);
|
|
||||||
for (Player pl : serverConnection.getServer().getPlayersConnected()) {
|
for (Player pl : serverConnection.getServer().getPlayersConnected()) {
|
||||||
if (pl.hasPermission(Config.SPYPERMISSION) && !party.getPartyUsersUuid().contains(pl.getUniqueId())) {
|
if (pl.hasPermission(Config.SPYPERMISSION) && !party.getPartyUsersUuid().contains(pl.getUniqueId())) {
|
||||||
pl.sendMessage(spyMessage);
|
pl.sendMessage(spyMessage);
|
||||||
@@ -198,17 +171,6 @@ public class ChatHandler {
|
|||||||
.stream()
|
.stream()
|
||||||
.filter(target -> target.hasPermission("command.chat.globaladminchat"))
|
.filter(target -> target.hasPermission("command.chat.globaladminchat"))
|
||||||
.forEach(target -> target.sendMessage(component));
|
.forEach(target -> target.sendMessage(component));
|
||||||
|
|
||||||
chatLogHandler.addChatLog(
|
|
||||||
new UUID(0, 0), //No origin uuid for GAC
|
|
||||||
"GAC", //No server for GAC
|
|
||||||
PlainTextComponentSerializer.plainText().serialize(component),
|
|
||||||
ChatLogType.GAC,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
component,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void globalAdminChat(CommandSource commandSource, String message) {
|
public void globalAdminChat(CommandSource commandSource, String message) {
|
||||||
@@ -220,17 +182,13 @@ public class ChatHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
senderName = user.getDisplayName();
|
senderName = user.getDisplayName();
|
||||||
serverName = sender.getCurrentServer().isPresent() ? sender.getCurrentServer()
|
serverName = sender.getCurrentServer().isPresent() ? sender.getCurrentServer().get().getServerInfo().getName() : "Altitude";
|
||||||
.get()
|
|
||||||
.getServerInfo()
|
|
||||||
.getName() : "Altitude";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TagResolver Placeholders = TagResolver.resolver(
|
TagResolver Placeholders = TagResolver.resolver(
|
||||||
Placeholder.component("message", parseMessageContent(commandSource, message)),
|
Placeholder.component("message", parseMessageContent(commandSource, message)),
|
||||||
Placeholder.component("sender", senderName),
|
Placeholder.component("sender", senderName),
|
||||||
Placeholder.unparsed("server", serverName)
|
Placeholder.unparsed("server", serverName));
|
||||||
);
|
|
||||||
|
|
||||||
ComponentLike component = Utility.parseMiniMessage(Config.GACFORMAT, Placeholders);
|
ComponentLike component = Utility.parseMiniMessage(Config.GACFORMAT, Placeholders);
|
||||||
|
|
||||||
@@ -252,8 +210,7 @@ public class ChatHandler {
|
|||||||
if (optionalPlayer.isEmpty()) {
|
if (optionalPlayer.isEmpty()) {
|
||||||
targetUUID = ServerHandler.getPlayerUUID(recipient);
|
targetUUID = ServerHandler.getPlayerUUID(recipient);
|
||||||
if (targetUUID == null) {
|
if (targetUUID == null) {
|
||||||
commandSource.sendMessage(Utility.parseMiniMessage(
|
commandSource.sendMessage(Utility.parseMiniMessage("<red>A player with this name hasn't logged in recently.")); // TOOD load from config
|
||||||
"<red>A player with this name hasn't logged in recently.")); // TOOD load from config
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -317,9 +274,7 @@ public class ChatHandler {
|
|||||||
Placeholder.component("sender", chatUser.getDisplayName()),
|
Placeholder.component("sender", chatUser.getDisplayName()),
|
||||||
Placeholder.component("message", Utility.parseMiniMessage(mail.getMessage())),
|
Placeholder.component("message", Utility.parseMiniMessage(mail.getMessage())),
|
||||||
Placeholder.unparsed("date", date.toString()),
|
Placeholder.unparsed("date", date.toString()),
|
||||||
Placeholder.unparsed("time_ago",
|
Placeholder.unparsed("time_ago", getTimeAgo(Duration.between(date.toInstant(), new Date().toInstant())))
|
||||||
getTimeAgo(Duration.between(date.toInstant(), new Date().toInstant()))
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
ComponentLike mailMessage = Utility.parseMiniMessage(Config.mailBody, Placeholders);
|
ComponentLike mailMessage = Utility.parseMiniMessage(Config.mailBody, Placeholders);
|
||||||
component = component.append(Component.newline()).append(mailMessage);
|
component = component.append(Component.newline()).append(mailMessage);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.alttd.chat.util.Utility;
|
|||||||
import com.alttd.velocitychat.VelocityChat;
|
import com.alttd.velocitychat.VelocityChat;
|
||||||
import com.alttd.velocitychat.events.GlobalAdminChatEvent;
|
import com.alttd.velocitychat.events.GlobalAdminChatEvent;
|
||||||
import com.velocitypowered.api.command.CommandSource;
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
|
import com.velocitypowered.api.event.PostOrder;
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import net.kyori.adventure.text.ComponentLike;
|
import net.kyori.adventure.text.ComponentLike;
|
||||||
@@ -18,7 +19,7 @@ public class ChatListener {
|
|||||||
plugin = VelocityChat.getPlugin();
|
plugin = VelocityChat.getPlugin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(priority = 0)
|
@Subscribe(order = PostOrder.FIRST)
|
||||||
public void onGlobalStaffChat(GlobalAdminChatEvent event) {
|
public void onGlobalStaffChat(GlobalAdminChatEvent event) {
|
||||||
String senderName = Config.CONSOLENAME;
|
String senderName = Config.CONSOLENAME;
|
||||||
String serverName = "Altitude";
|
String serverName = "Altitude";
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import com.alttd.velocitychat.VelocityChat;
|
|||||||
import com.alttd.velocitychat.commands.vote_to_mute.ActiveVoteToMute;
|
import com.alttd.velocitychat.commands.vote_to_mute.ActiveVoteToMute;
|
||||||
import com.alttd.velocitychat.data.ServerWrapper;
|
import com.alttd.velocitychat.data.ServerWrapper;
|
||||||
import com.alttd.velocitychat.handlers.ServerHandler;
|
import com.alttd.velocitychat.handlers.ServerHandler;
|
||||||
|
import com.velocitypowered.api.event.PostOrder;
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||||
import com.velocitypowered.api.event.connection.LoginEvent;
|
import com.velocitypowered.api.event.connection.LoginEvent;
|
||||||
@@ -33,7 +34,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
public class ProxyPlayerListener {
|
public class ProxyPlayerListener {
|
||||||
|
|
||||||
@Subscribe(priority = 0)
|
@Subscribe(order = PostOrder.FIRST)
|
||||||
public void onPlayerLogin(LoginEvent event) {
|
public void onPlayerLogin(LoginEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
@@ -56,7 +57,7 @@ public class ProxyPlayerListener {
|
|||||||
ServerHandler.addPlayerUUID(player.getUsername(), uuid);
|
ServerHandler.addPlayerUUID(player.getUsername(), uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(priority = 4)
|
@Subscribe(order = PostOrder.LAST)
|
||||||
public void afterPlayerLogin(ServerPostConnectEvent event) {
|
public void afterPlayerLogin(ServerPostConnectEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
RegisteredServer previousServer = event.getPreviousServer();
|
RegisteredServer previousServer = event.getPreviousServer();
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.alttd.velocitychat.matrix;
|
||||||
|
|
||||||
|
import com.alttd.matrix.interfaces.MatrixBridge;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public final class MatrixRoomMap implements MatrixBridge.RoomResolver {
|
||||||
|
private final Map<String, String> serverToRoom = new ConcurrentHashMap<>();
|
||||||
|
private final Map<String, String> roomToServer = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public void put(String serverName, String roomId) {
|
||||||
|
serverToRoom.put(serverName, roomId);
|
||||||
|
roomToServer.put(roomId, serverName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String roomIdForServer(String serverName) {
|
||||||
|
return serverToRoom.get(serverName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String serverForRoomId(String roomId) {
|
||||||
|
return roomToServer.get(roomId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.alttd.velocitychat.matrix;
|
||||||
|
|
||||||
|
import com.alttd.matrix.interfaces.MatrixBridge;
|
||||||
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
|
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public final class VelocityMatrixInbound implements MatrixBridge.InboundHandler {
|
||||||
|
private final ProxyServer proxy;
|
||||||
|
private final MatrixRoomMap rooms;
|
||||||
|
|
||||||
|
public VelocityMatrixInbound(ProxyServer proxy, MatrixRoomMap rooms) {
|
||||||
|
this.proxy = proxy;
|
||||||
|
this.rooms = rooms;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMatrixChat(String roomId, String senderMxid, String body) {
|
||||||
|
final String serverName = rooms.serverForRoomId(roomId);
|
||||||
|
if (serverName == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// route to backend server players connected to that server
|
||||||
|
Optional<RegisteredServer> rs = proxy.getServer(serverName);
|
||||||
|
if (rs.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// minimal formatting; adjust to your chat format
|
||||||
|
String sender = senderMxid != null ? senderMxid : "matrix";
|
||||||
|
Component msg = Component.text("[M] " + sender + ": " + body);
|
||||||
|
|
||||||
|
rs.get().getPlayersConnected().forEach(p -> p.sendMessage(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.alttd.velocitychat.matrix;
|
||||||
|
|
||||||
|
import com.alttd.matrix.interfaces.MatrixBridge;
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.player.PlayerChatEvent;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
|
|
||||||
|
public final class VelocityMatrixOutbound {
|
||||||
|
private final MatrixBridge matrix;
|
||||||
|
|
||||||
|
public VelocityMatrixOutbound(MatrixBridge matrix) {
|
||||||
|
this.matrix = matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onChat(PlayerChatEvent e) {
|
||||||
|
if (!e.getResult().isAllowed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player p = e.getPlayer();
|
||||||
|
String serverName = p.getCurrentServer().map(s -> s.getServerInfo().getName()).orElse(null);
|
||||||
|
if (serverName == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String msg = PlainTextComponentSerializer.plainText().serialize(e.getMessage());
|
||||||
|
if (msg == null || msg.isBlank()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
matrix.sendChat(p.getUniqueId(), p.getUsername(), serverName, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
plugins {
|
|
||||||
java
|
|
||||||
id("org.openapi.generator") version "7.12.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
group = "com.alttd.chat"
|
|
||||||
version = "2.0.0-SNAPSHOT"
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation("io.swagger.core.v3:swagger-annotations:2.2.28")
|
|
||||||
|
|
||||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
|
||||||
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
|
|
||||||
|
|
||||||
implementation("com.google.code.gson:gson:2.12.1")
|
|
||||||
implementation("io.gsonfire:gson-fire:1.9.0")
|
|
||||||
|
|
||||||
implementation("javax.annotation:javax.annotation-api:1.3.2")
|
|
||||||
implementation("jakarta.annotation:jakarta.annotation-api:2.1.1")
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
main {
|
|
||||||
java {
|
|
||||||
srcDir("${projectDir}/build/generated-sources/client/src/main/java")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.named<org.openapitools.generator.gradle.plugin.tasks.GenerateTask>("openApiGenerate") {
|
|
||||||
generatorName.set("java")
|
|
||||||
inputSpec.set("${projectDir}/src/main/resources/chat-api.yml")
|
|
||||||
configFile.set("${projectDir}/src/main/resources/config_backend.json")
|
|
||||||
outputDir.set("${projectDir}/build/generated-sources/client")
|
|
||||||
|
|
||||||
apiPackage.set("com.alttd.altitudeweb.api")
|
|
||||||
modelPackage.set("com.alttd.altitudeweb.model")
|
|
||||||
|
|
||||||
modelNameSuffix.set("Dto")
|
|
||||||
|
|
||||||
additionalProperties.set(
|
|
||||||
mapOf(
|
|
||||||
"dateLibrary" to "java8",
|
|
||||||
"library" to "okhttp-gson"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
generateApiTests.set(false)
|
|
||||||
generateApiDocumentation.set(false)
|
|
||||||
generateModelTests.set(false)
|
|
||||||
generateModelDocumentation.set(false)
|
|
||||||
|
|
||||||
generateAliasAsModel.set(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
main {
|
|
||||||
java {
|
|
||||||
srcDir(layout.buildDirectory.dir("generated/openapi/src/main/java"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.compileJava {
|
|
||||||
dependsOn("openApiGenerate")
|
|
||||||
}
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
openapi: 3.0.3
|
|
||||||
|
|
||||||
info:
|
|
||||||
title: Minecraft Network API
|
|
||||||
version: 1.0.0
|
|
||||||
|
|
||||||
servers:
|
|
||||||
- url: http://localhost:8080/api
|
|
||||||
|
|
||||||
tags:
|
|
||||||
- name: chat
|
|
||||||
description: Data for displaying Chat messages to clients
|
|
||||||
|
|
||||||
paths:
|
|
||||||
/chat/send/chat/message:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- chat
|
|
||||||
summary: Sends one or more chat messages
|
|
||||||
operationId: sendChatMessages
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: "#/components/schemas/ChatMessage"
|
|
||||||
responses:
|
|
||||||
"202":
|
|
||||||
description: Accepted
|
|
||||||
|
|
||||||
/chat/send/servers/state:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- chat
|
|
||||||
summary: Update server states
|
|
||||||
operationId: updateServerStates
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: "#/components/schemas/ServerState"
|
|
||||||
responses:
|
|
||||||
"202":
|
|
||||||
description: Accepted
|
|
||||||
|
|
||||||
components:
|
|
||||||
schemas:
|
|
||||||
User:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- uuid
|
|
||||||
- name
|
|
||||||
- styledName
|
|
||||||
# TODO [Stijn] [2026-07-19]: Add who they ignore and who they are ignored by
|
|
||||||
|
|
||||||
properties:
|
|
||||||
uuid:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
styledName:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
ChatMessage:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- uuid
|
|
||||||
- message
|
|
||||||
- server
|
|
||||||
- type
|
|
||||||
- timestamp
|
|
||||||
- blocked
|
|
||||||
properties:
|
|
||||||
uuid:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
server:
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- PUBLIC
|
|
||||||
- GLOBAL
|
|
||||||
- PARTY
|
|
||||||
- GAC
|
|
||||||
- MSG
|
|
||||||
- CUSTOM
|
|
||||||
channel:
|
|
||||||
type: string
|
|
||||||
maxLength: 36
|
|
||||||
receiver:
|
|
||||||
type: string
|
|
||||||
maxLength: 36
|
|
||||||
timestamp:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
blocked:
|
|
||||||
type: boolean
|
|
||||||
|
|
||||||
PrivateMessage:
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- sender
|
|
||||||
- receiver
|
|
||||||
- message
|
|
||||||
- senderServer
|
|
||||||
- receiverServer
|
|
||||||
properties:
|
|
||||||
sender:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
receiver:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
senderServer:
|
|
||||||
type: string
|
|
||||||
receiverServer:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
Server:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
players:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: "#/components/schemas/User"
|
|
||||||
|
|
||||||
ServerState:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
servers:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: "#/components/schemas/Server"
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"library": "okhttp-gson",
|
|
||||||
"hideGenerationTimestamp": true,
|
|
||||||
"modelPackage": "com.alttd.altitudeweb.model",
|
|
||||||
"apiPackage": "com.alttd.altitudeweb.api",
|
|
||||||
"invokerPackage": "com.alttd.altitudeweb.invoker",
|
|
||||||
"serializableModel": true,
|
|
||||||
"openApiNullable": false,
|
|
||||||
"useTags": true,
|
|
||||||
"generateApis": true,
|
|
||||||
"generateApiTests": false,
|
|
||||||
"generateApiDocumentation": false,
|
|
||||||
"generateModels": true,
|
|
||||||
"generateModelTests": false,
|
|
||||||
"generateSupportingFiles": true,
|
|
||||||
"modelNameSuffix": "Dto",
|
|
||||||
"generateTests": false,
|
|
||||||
"dateLibrary": "java8",
|
|
||||||
"enumUnknownDefaultCase": true,
|
|
||||||
"disallowAdditionalPropertiesIfNotPresent": false,
|
|
||||||
"useJakartaEe": true
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user