Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Images/Examples/Message from Discord.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Images/Examples/Message from HUB.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Images/Examples/Message from SMP.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ use-permissions: false
# Example: If it is set to '$', then when a player sends $hello, it will be sent through the proxy.
proxy-message-prefix: ''

# Messages that start with this character will not be sent through the plugin.
# Set to '' to disable.
# Example: If it is set to '#', then when a player sends #hello, it will not be sent through the proxy.
proxy-message-prefix-blacklist: ''

# Whether to send if the statuses of the servers connected to the proxy when the proxy starts up.
# THIS IS FOR DISCORD MESSAGES ONLY.
use-initial-server-status: true
Expand Down Expand Up @@ -208,9 +213,15 @@ minecraft:
join:
enabled: true
message: "&e%player% &ahas joined the network. (%server%)"
recipients:
exclude-self: false
exclude-server: false # excludes every player but the sender
leave:
enabled: true
message: "&e%player% &chas left the network. (%server%)"
recipients:
exclude-self: false
exclude-server: false # excludes every player but the sender
chat:
enabled: true
message: "&8[&3%server%&8] &e%player% &9» &7%message%"
Expand Down Expand Up @@ -305,7 +316,7 @@ console:
update-message: "&7There is an update! You are on &c%old%. New version is &a%new%&7: &6%link%"

# DO NOT TOUCH THIS
file-version: 10
file-version: 11
```

---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ public ChatHandler(ISimpleProxyChat plugin, EpochHelper epochHelper) {

private Optional<String> getValidMessage(String message) {
String messagePrefix = config.get(ConfigKey.PROXY_MESSAGE_PREFIX).asString();
String messagePrefixBlacklist = config.get(ConfigKey.PROXY_MESSAGE_PREFIX_BLACKLIST).asString();

if (!messagePrefixBlacklist.isEmpty() && message.startsWith(messagePrefixBlacklist)) return Optional.empty();

if (messagePrefix.isEmpty()) return Optional.of(message);
if (!message.startsWith(messagePrefix)) return Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public enum ConfigKey {
ALIASES (ConfigFileType.CONFIG, "aliases", Map.class),
USE_PERMISSIONS (ConfigFileType.CONFIG, "use-permissions", Boolean.class),
PROXY_MESSAGE_PREFIX (ConfigFileType.CONFIG, "proxy-message-prefix", String.class),
PROXY_MESSAGE_PREFIX_BLACKLIST (ConfigFileType.CONFIG, "proxy-message-prefix-blacklist", String.class),
USE_INITIAL_SERVER_STATUS (ConfigFileType.CONFIG, "use-initial-server-status", Boolean.class),
USE_FAKE_MESSAGES (ConfigFileType.CONFIG, "use-fake-messages", Boolean.class),
TIMESTAMP_USE_API (ConfigFileType.CONFIG, "timestamp.use-api", Boolean.class),
Expand All @@ -46,8 +47,12 @@ public enum ConfigKey {

MINECRAFT_JOIN_ENABLED (ConfigFileType.MESSAGES, "minecraft.join.enabled", Boolean.class),
MINECRAFT_JOIN (ConfigFileType.MESSAGES, "minecraft.join.message", String.class),
MINECRAFT_JOIN_RECIPIENTS_EXCLUDE_SELF (ConfigFileType.MESSAGES, "minecraft.join.recipients.exclude-self", Boolean.class),
MINECRAFT_JOIN_RECIPIENTS_EXCLUDE_SERVER (ConfigFileType.MESSAGES, "minecraft.join.recipients.exclude-server", Boolean.class),
MINECRAFT_LEAVE_ENABLED (ConfigFileType.MESSAGES, "minecraft.leave.enabled", Boolean.class),
MINECRAFT_LEAVE (ConfigFileType.MESSAGES, "minecraft.leave.message", String.class),
MINECRAFT_LEAVE_RECIPIENTS_EXCLUDE_SELF (ConfigFileType.MESSAGES, "minecraft.leave.recipients.exclude-self", Boolean.class),
MINECRAFT_LEAVE_RECIPIENTS_EXCLUDE_SERVER (ConfigFileType.MESSAGES, "minecraft.leave.recipients.exclude-server", Boolean.class),
MINECRAFT_CHAT_ENABLED (ConfigFileType.MESSAGES, "minecraft.chat.enabled", Boolean.class),
MINECRAFT_CHAT_MESSAGE (ConfigFileType.MESSAGES, "minecraft.chat.message", String.class),
MINECRAFT_CHAT_VANISHED_MESSAGE (ConfigFileType.MESSAGES, "minecraft.chat.vanished", String.class),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,20 @@ void leave(ProxiedPlayer player, boolean isFake) {
plugin,
() -> {
previousServerHandler.get(player.getName()).ifPresent((serverInfo) -> {
if (isFake) chatHandler.runProxyLeaveMessage(player.getName(), player.getUniqueId(), serverInfo.getName(), this::sendToAllServersVanish);
else chatHandler.runProxyLeaveMessage(player.getName(), player.getUniqueId(), serverInfo.getName(), this::sendToAllServers);
if (isFake)
chatHandler.runProxyLeaveMessage(
player.getName(),
player.getUniqueId(),
serverInfo.getName(),
(message, permission) -> sendToAllServersLeaveFilteredVanish(message, permission, player.getUniqueId(), serverInfo.getName())
);
else
chatHandler.runProxyLeaveMessage(
player.getName(),
player.getUniqueId(),
serverInfo.getName(),
(message, permission) -> sendToAllServersLeaveFiltered(message, permission, player.getUniqueId(), serverInfo.getName())
);
});
},
50L, TimeUnit.MILLISECONDS); // 50ms is 1 tick
Expand Down Expand Up @@ -155,8 +167,20 @@ public void join(ProxiedPlayer player, @Nullable Server server, boolean isFake)

previousServerHandler.put(player.getName(), server.getInfo());

if (isFake) chatHandler.runProxyJoinMessage(player.getName(), player.getUniqueId(), server.getInfo().getName(), this::sendToAllServersVanish);
else chatHandler.runProxyJoinMessage(player.getName(), player.getUniqueId(), server.getInfo().getName(), this::sendToAllServers);
if (isFake)
chatHandler.runProxyJoinMessage(
player.getName(),
player.getUniqueId(),
server.getInfo().getName(),
(message, permission) -> sendToAllServersJoinFilteredVanish(message, permission, player.getUniqueId(), server.getInfo().getName())
);
else
chatHandler.runProxyJoinMessage(
player.getName(),
player.getUniqueId(),
server.getInfo().getName(),
(message, permission) -> sendToAllServersJoinFiltered(message, permission, player.getUniqueId(), server.getInfo().getName())
);
},
50L * 2, TimeUnit.MILLISECONDS); // 50ms is 1 tick
} catch (Exception e) {
Expand Down Expand Up @@ -237,4 +261,138 @@ private void sendToAllServersVanish(String parsedMessage, Permission permission)
.forEach((player) -> player.sendMessage(ChatMessageType.CHAT, Helper.convertToBungee(parsedMessage)));
}

private void sendToAllServersJoinFiltered(String parsedMessage, Permission permission, java.util.UUID subjectUUID, String subjectServerName) {
boolean excludeSelf = plugin.getConfig().get(ConfigKey.MINECRAFT_JOIN_RECIPIENTS_EXCLUDE_SELF).asBoolean();
boolean excludeServer = plugin.getConfig().get(ConfigKey.MINECRAFT_JOIN_RECIPIENTS_EXCLUDE_SERVER).asBoolean();

plugin.getProxy().getPlayers().stream()
.filter((player) -> {
if (plugin.getConfig().get(ConfigKey.USE_PERMISSIONS).asBoolean())
return player.hasPermission(permission.getPermissionNode());
return true;
})
.filter((player) -> {
if (player.getServer() == null || player.getServer().getInfo() == null) return false;
return !Helper.serverHasChatLocked(plugin, player.getServer().getInfo().getName());
})
.filter((player) -> !playerIsInDisabledServer(player, plugin))
.filter((player) -> !excludeSelf || !player.getUniqueId().equals(subjectUUID))
// Ensure the subject is not included in the stream when excluding the server to avoid duplicates
.filter((player) -> !(excludeServer && player.getUniqueId().equals(subjectUUID)))
.filter((player) -> !excludeServer || (player.getServer() == null || player.getServer().getInfo() == null) || !player.getServer().getInfo().getName().equalsIgnoreCase(subjectServerName))
.forEach((player) -> player.sendMessage(ChatMessageType.CHAT, Helper.convertToBungee(parsedMessage)));

// If excluding the server but not the subject, explicitly send to the subject to keep behavior consistent
if (excludeServer && !excludeSelf) {
ProxiedPlayer subject = plugin.getProxy().getPlayer(subjectUUID);
if (subject != null) {
if (plugin.getConfig().get(ConfigKey.USE_PERMISSIONS).asBoolean()
&& !subject.hasPermission(permission.getPermissionNode())) return;
if (subject.getServer() == null || subject.getServer().getInfo() == null) return;
if (Helper.serverHasChatLocked(plugin, subject.getServer().getInfo().getName())) return;
if (playerIsInDisabledServer(subject, plugin)) return;
subject.sendMessage(ChatMessageType.CHAT, Helper.convertToBungee(parsedMessage));
}
}
}

private void sendToAllServersLeaveFiltered(String parsedMessage, Permission permission, java.util.UUID subjectUUID, String subjectServerName) {
boolean excludeSelf = plugin.getConfig().get(ConfigKey.MINECRAFT_LEAVE_RECIPIENTS_EXCLUDE_SELF).asBoolean();
boolean excludeServer = plugin.getConfig().get(ConfigKey.MINECRAFT_LEAVE_RECIPIENTS_EXCLUDE_SERVER).asBoolean();

plugin.getProxy().getPlayers().stream()
.filter((player) -> {
if (plugin.getConfig().get(ConfigKey.USE_PERMISSIONS).asBoolean())
return player.hasPermission(permission.getPermissionNode());
return true;
})
.filter((player) -> {
if (player.getServer() == null || player.getServer().getInfo() == null) return false;
return !Helper.serverHasChatLocked(plugin, player.getServer().getInfo().getName());
})
.filter((player) -> !playerIsInDisabledServer(player, plugin))
.filter((player) -> !excludeSelf || !player.getUniqueId().equals(subjectUUID))
// Ensure the subject is not included in the stream when excluding the server to avoid duplicates
.filter((player) -> !(excludeServer && player.getUniqueId().equals(subjectUUID)))
.filter((player) -> !excludeServer || (player.getServer() == null || player.getServer().getInfo() == null) || !player.getServer().getInfo().getName().equalsIgnoreCase(subjectServerName))
.forEach((player) -> player.sendMessage(ChatMessageType.CHAT, Helper.convertToBungee(parsedMessage)));

// If excluding the server but not the subject, explicitly send to the subject to keep behavior consistent
if (excludeServer && !excludeSelf) {
ProxiedPlayer subject = plugin.getProxy().getPlayer(subjectUUID);
if (subject != null) {
if (plugin.getConfig().get(ConfigKey.USE_PERMISSIONS).asBoolean()
&& !subject.hasPermission(permission.getPermissionNode())) return;
if (subject.getServer() == null || subject.getServer().getInfo() == null) return;
if (Helper.serverHasChatLocked(plugin, subject.getServer().getInfo().getName())) return;
if (playerIsInDisabledServer(subject, plugin)) return;
subject.sendMessage(ChatMessageType.CHAT, Helper.convertToBungee(parsedMessage));
}
}
}

private void sendToAllServersJoinFilteredVanish(String parsedMessage, Permission permission, java.util.UUID subjectUUID, String subjectServerName) {
boolean excludeSelf = plugin.getConfig().get(ConfigKey.MINECRAFT_JOIN_RECIPIENTS_EXCLUDE_SELF).asBoolean();
boolean excludeServer = plugin.getConfig().get(ConfigKey.MINECRAFT_JOIN_RECIPIENTS_EXCLUDE_SERVER).asBoolean();

plugin.getProxy().getPlayers().stream()
.filter((player) -> {
if (plugin.getConfig().get(ConfigKey.USE_PERMISSIONS).asBoolean())
return player.hasPermission(permission.getPermissionNode());
return true;
})
.filter((player) -> {
if (plugin.getConfig().get(ConfigKey.USE_PERMISSIONS).asBoolean())
return player.hasPermission(Permission.READ_FAKE_MESSAGE.getPermissionNode());
return true;
})
.filter((player) -> !excludeSelf || !player.getUniqueId().equals(subjectUUID))
// Ensure the subject is not included in the stream when excluding the server to avoid duplicates
.filter((player) -> !(excludeServer && player.getUniqueId().equals(subjectUUID)))
.filter((player) -> !excludeServer || (player.getServer() == null || player.getServer().getInfo() == null) || !player.getServer().getInfo().getName().equalsIgnoreCase(subjectServerName))
.forEach((player) -> player.sendMessage(ChatMessageType.CHAT, Helper.convertToBungee(parsedMessage)));

// If excluding the server but not the subject, explicitly send to the subject to keep behavior consistent
if (excludeServer && !excludeSelf) {
ProxiedPlayer subject = plugin.getProxy().getPlayer(subjectUUID);
if (subject != null) {
if (plugin.getConfig().get(ConfigKey.USE_PERMISSIONS).asBoolean()
&& !subject.hasPermission(permission.getPermissionNode())) return;
subject.sendMessage(ChatMessageType.CHAT, Helper.convertToBungee(parsedMessage));
}
}
}

private void sendToAllServersLeaveFilteredVanish(String parsedMessage, Permission permission, java.util.UUID subjectUUID, String subjectServerName) {
boolean excludeSelf = plugin.getConfig().get(ConfigKey.MINECRAFT_LEAVE_RECIPIENTS_EXCLUDE_SELF).asBoolean();
boolean excludeServer = plugin.getConfig().get(ConfigKey.MINECRAFT_LEAVE_RECIPIENTS_EXCLUDE_SERVER).asBoolean();

plugin.getProxy().getPlayers().stream()
.filter((player) -> {
if (plugin.getConfig().get(ConfigKey.USE_PERMISSIONS).asBoolean())
return player.hasPermission(permission.getPermissionNode());
return true;
})
.filter((player) -> {
if (plugin.getConfig().get(ConfigKey.USE_PERMISSIONS).asBoolean())
return player.hasPermission(Permission.READ_FAKE_MESSAGE.getPermissionNode());
return true;
})
.filter((player) -> !excludeSelf || !player.getUniqueId().equals(subjectUUID))
// Ensure the subject is not included in the stream when excluding the server to avoid duplicates
.filter((player) -> !(excludeServer && player.getUniqueId().equals(subjectUUID)))
.filter((player) -> !excludeServer || (player.getServer() == null || player.getServer().getInfo() == null) || !player.getServer().getInfo().getName().equalsIgnoreCase(subjectServerName))
.forEach((player) -> player.sendMessage(ChatMessageType.CHAT, Helper.convertToBungee(parsedMessage)));

// If excluding the server but not the subject, explicitly send to the subject to keep behavior consistent
if (excludeServer && !excludeSelf) {
ProxiedPlayer subject = plugin.getProxy().getPlayer(subjectUUID);
if (subject != null) {
if (plugin.getConfig().get(ConfigKey.USE_PERMISSIONS).asBoolean()
&& !subject.hasPermission(permission.getPermissionNode())) return;
subject.sendMessage(ChatMessageType.CHAT, Helper.convertToBungee(parsedMessage));
}
}
}

}
Loading
Loading